Print this page
NEX-19665 Several door servers don't properly handle exiting threads
Review by: Gordon Ross <gordon.ross@nexenta.com>
Review by: Evan Layton <evan.layton@nexenta.com>
NEX-2225 Unable to join NexentaStor to 2008 AD
NEX-1638 Updated DC Locator
 Includes work by: matt.barden@nexenta.com, kevin.crowe@nexenta.com

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/idmap/idmapd/idmapd.c
          +++ new/usr/src/cmd/idmap/idmapd/idmapd.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  
  27   27  /*
  28   28   * main() of idmapd(1M)
  29   29   */
  30   30  
  31   31  #include "idmapd.h"
  32   32  #include <atomic.h>
  33   33  #include <signal.h>
↓ open down ↓ 43 lines elided ↑ open up ↑
  77   77  
  78   78  
  79   79  static uint32_t         num_threads = 0;
  80   80  static pthread_key_t    create_threads_key;
  81   81  static uint32_t         max_threads = 40;
  82   82  
  83   83  /*
  84   84   * Server door thread start routine.
  85   85   *
  86   86   * Set a TSD value to the door thread. This enables the destructor to
  87      - * be called when this thread exits.
       87 + * be called when this thread exits. Note that we need a non-NULL
       88 + * value for this or the TSD destructor is not called.
  88   89   */
  89   90  /*ARGSUSED*/
  90   91  static void *
  91   92  idmapd_door_thread_start(void *arg)
  92   93  {
  93      -        static void *value = 0;
       94 +        static void *value = "NON-NULL TSD";
  94   95  
  95   96          /*
  96   97           * Disable cancellation to avoid memory leaks from not running
  97   98           * the thread cleanup code.
  98   99           */
  99  100          (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 100  101          (void) pthread_setspecific(create_threads_key, value);
 101  102          (void) door_return(NULL, 0, NULL, 0);
 102  103  
 103  104          /* make lint happy */
↓ open down ↓ 25 lines elided ↑ open up ↑
 129  130  
 130  131  /*
 131  132   * Server door thread cleanup
 132  133   */
 133  134  /*ARGSUSED*/
 134  135  static void
 135  136  idmapd_door_thread_cleanup(void *arg)
 136  137  {
 137  138          int num;
 138  139  
      140 +        /* set TSD to NULL so we don't loop infinitely */
      141 +        (void) pthread_setspecific(create_threads_key, NULL);
 139  142          num = atomic_dec_32_nv(&num_threads);
 140  143          idmapdlog(LOG_DEBUG,
 141  144              "exiting thread ID %d - %d threads currently active",
 142  145              pthread_self(), num);
 143  146  }
 144  147  
 145  148  /*
 146  149   * This is needed for mech_krb5 -- we run as daemon, yes, but we want
 147  150   * mech_krb5 to think we're root so it can get host/nodename.fqdn
 148  151   * tickets for us so we can authenticate to AD as the machine account
↓ open down ↓ 223 lines elided ↑ open up ↑
 372  375                  idmapdlog(LOG_ERR, "unable to determine hostname, error: %d",
 373  376                      error);
 374  377                  exit(1);
 375  378          }
 376  379  
 377  380          if ((error = init_mapping_system()) < 0) {
 378  381                  idmapdlog(LOG_ERR, "unable to initialize mapping system");
 379  382                  exit(error < -2 ? SMF_EXIT_ERR_CONFIG : 1);
 380  383          }
 381  384  
      385 +        /*
      386 +         * This means max_threads can't be updated without restarting idmap.
      387 +         */
      388 +        RDLOCK_CONFIG();
      389 +        max_threads = _idmapdstate.cfg->pgcfg.max_threads;
      390 +        UNLOCK_CONFIG();
      391 +
 382  392          (void) door_server_create(idmapd_door_thread_create);
 383  393          if ((error = pthread_key_create(&create_threads_key,
 384  394              idmapd_door_thread_cleanup)) != 0) {
 385  395                  idmapdlog(LOG_ERR, "unable to create threads key (%s)",
 386  396                      strerror(error));
 387  397                  goto errout;
 388  398          }
 389  399  
 390  400          xprt = svc_door_create(idmap_prog_1, IDMAP_PROG, IDMAP_V1, connmaxrec);
 391  401          if (xprt == NULL) {
↓ open down ↓ 295 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX