Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2012 Milan Jurik. All rights reserved.

  25  */
  26 
  27 #include <stdlib.h>
  28 #include <alloca.h>
  29 #include <signal.h>
  30 #include <sys/stat.h>
  31 #include <unistd.h>
  32 #include <pthread.h>
  33 #include <time.h>
  34 #include <errno.h>
  35 #include <door.h>
  36 #include <zone.h>
  37 #include <resolv.h>
  38 #include <sys/socket.h>
  39 #include <net/route.h>
  40 #include <string.h>
  41 #include <net/if.h>
  42 #include <sys/stat.h>
  43 #include <fcntl.h>
  44 #include "nscd_common.h"


  72 extern mutex_t  activity_lock;
  73 
  74 static sema_t   common_sema;
  75 
  76 static thread_key_t     lookup_state_key;
  77 static mutex_t          create_lock = DEFAULTMUTEX;
  78 static int              num_servers = 0;
  79 static thread_key_t     server_key;
  80 
  81 /*
  82  * Bind a TSD value to a server thread. This enables the destructor to
  83  * be called if/when this thread exits.  This would be a programming
  84  * error, but better safe than sorry.
  85  */
  86 /*ARGSUSED*/
  87 static void *
  88 server_tsd_bind(void *arg)
  89 {
  90         static void *value = 0;
  91 


  92         /* disable cancellation to avoid hangs if server threads disappear */
  93         (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  94         (void) thr_setspecific(server_key, value);
  95         (void) door_return(NULL, 0, NULL, 0);
  96 
  97         /* make lint happy */
  98         return (NULL);
  99 }
 100 
 101 /*
 102  * Server threads are created here.
 103  */
 104 /*ARGSUSED*/
 105 static void
 106 server_create(door_info_t *dip)
 107 {
 108         (void) mutex_lock(&create_lock);
 109         if (++num_servers > max_servers) {
 110                 num_servers--;
 111                 (void) mutex_unlock(&create_lock);


 115         (void) thr_create(NULL, 0, server_tsd_bind, NULL,
 116             THR_BOUND|THR_DETACHED, NULL);
 117 }
 118 
 119 /*
 120  * Server thread are destroyed here
 121  */
 122 /*ARGSUSED*/
 123 static void
 124 server_destroy(void *arg)
 125 {
 126         (void) mutex_lock(&create_lock);
 127         num_servers--;
 128         (void) mutex_unlock(&create_lock);
 129 }
 130 
 131 /*
 132  * get clearance
 133  */
 134 int
 135 _nscd_get_clearance(sema_t *sema) {

 136         if (sema_trywait(&common_sema) == 0) {
 137                 (void) thr_setspecific(lookup_state_key, NULL);
 138                 return (0);
 139         }
 140 
 141         if (sema_trywait(sema) == 0) {
 142                 (void) thr_setspecific(lookup_state_key, (void*)1);
 143                 return (0);
 144         }
 145 
 146         return (1);
 147 }
 148 
 149 
 150 /*
 151  * release clearance
 152  */
 153 int
 154 _nscd_release_clearance(sema_t *sema) {

 155         int     which;
 156 
 157         (void) thr_getspecific(lookup_state_key, (void**)&which);
 158         if (which == 0) /* from common pool */ {
 159                 (void) sema_post(&common_sema);
 160                 return (0);
 161         }
 162 
 163         (void) sema_post(sema);
 164         return (1);
 165 }
 166 
 167 static void
 168 dozip(void)
 169 {
 170         /* not much here */
 171 }
 172 
 173 /*
 174  * _nscd_restart_if_cfgfile_changed()


1460  * cache are sorted based on destination address selection rules,
1461  * so when things change that could affect that sorting (interfaces
1462  * go up or down, flags change, etc.), we clear that cache so the
1463  * list will be re-ordered the next time the hostname is resolved.
1464  */
1465 static void
1466 rts_mon(void)
1467 {
1468         int     rt_sock, rdlen, idx;
1469         union {
1470                 struct {
1471                         struct rt_msghdr rtm;
1472                         struct sockaddr_storage addrs[RTA_NUMBITS];
1473                 } r;
1474                 struct if_msghdr ifm;
1475                 struct ifa_msghdr ifam;
1476         } mbuf;
1477         struct ifa_msghdr *ifam = &mbuf.ifam;
1478         char    *me = "rts_mon";
1479 


1480         rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
1481         if (rt_sock < 0) {
1482                 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
1483                 (me, "Failed to open routing socket: %s\n", strerror(errno));
1484                 thr_exit(0);
1485         }
1486 
1487         for (;;) {
1488                 rdlen = read(rt_sock, &mbuf, sizeof (mbuf));
1489                 if (rdlen <= 0) {
1490                         if (rdlen == 0 || (errno != EINTR && errno != EAGAIN)) {
1491                                 _NSCD_LOG(NSCD_LOG_FRONT_END,
1492                                     NSCD_LOG_LEVEL_ERROR)
1493                                 (me, "routing socket read: %s\n",
1494                                     strerror(errno));
1495                                 thr_exit(0);
1496                         }
1497                         continue;
1498                 }
1499                 if (ifam->ifam_version != RTM_VERSION) {




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2012 Milan Jurik. All rights reserved.
  25  * Copyright 2018 Joyent, Inc.
  26  */
  27 
  28 #include <stdlib.h>
  29 #include <alloca.h>
  30 #include <signal.h>
  31 #include <sys/stat.h>
  32 #include <unistd.h>
  33 #include <pthread.h>
  34 #include <time.h>
  35 #include <errno.h>
  36 #include <door.h>
  37 #include <zone.h>
  38 #include <resolv.h>
  39 #include <sys/socket.h>
  40 #include <net/route.h>
  41 #include <string.h>
  42 #include <net/if.h>
  43 #include <sys/stat.h>
  44 #include <fcntl.h>
  45 #include "nscd_common.h"


  73 extern mutex_t  activity_lock;
  74 
  75 static sema_t   common_sema;
  76 
  77 static thread_key_t     lookup_state_key;
  78 static mutex_t          create_lock = DEFAULTMUTEX;
  79 static int              num_servers = 0;
  80 static thread_key_t     server_key;
  81 
  82 /*
  83  * Bind a TSD value to a server thread. This enables the destructor to
  84  * be called if/when this thread exits.  This would be a programming
  85  * error, but better safe than sorry.
  86  */
  87 /*ARGSUSED*/
  88 static void *
  89 server_tsd_bind(void *arg)
  90 {
  91         static void *value = 0;
  92 
  93         (void) thr_setname(thr_self(), "server_tsd_bind");
  94 
  95         /* disable cancellation to avoid hangs if server threads disappear */
  96         (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  97         (void) thr_setspecific(server_key, value);
  98         (void) door_return(NULL, 0, NULL, 0);
  99 
 100         /* make lint happy */
 101         return (NULL);
 102 }
 103 
 104 /*
 105  * Server threads are created here.
 106  */
 107 /*ARGSUSED*/
 108 static void
 109 server_create(door_info_t *dip)
 110 {
 111         (void) mutex_lock(&create_lock);
 112         if (++num_servers > max_servers) {
 113                 num_servers--;
 114                 (void) mutex_unlock(&create_lock);


 118         (void) thr_create(NULL, 0, server_tsd_bind, NULL,
 119             THR_BOUND|THR_DETACHED, NULL);
 120 }
 121 
 122 /*
 123  * Server thread are destroyed here
 124  */
 125 /*ARGSUSED*/
 126 static void
 127 server_destroy(void *arg)
 128 {
 129         (void) mutex_lock(&create_lock);
 130         num_servers--;
 131         (void) mutex_unlock(&create_lock);
 132 }
 133 
 134 /*
 135  * get clearance
 136  */
 137 int
 138 _nscd_get_clearance(sema_t *sema)
 139 {
 140         if (sema_trywait(&common_sema) == 0) {
 141                 (void) thr_setspecific(lookup_state_key, NULL);
 142                 return (0);
 143         }
 144 
 145         if (sema_trywait(sema) == 0) {
 146                 (void) thr_setspecific(lookup_state_key, (void*)1);
 147                 return (0);
 148         }
 149 
 150         return (1);
 151 }
 152 
 153 
 154 /*
 155  * release clearance
 156  */
 157 int
 158 _nscd_release_clearance(sema_t *sema)
 159 {
 160         int     which;
 161 
 162         (void) thr_getspecific(lookup_state_key, (void**)&which);
 163         if (which == 0) /* from common pool */ {
 164                 (void) sema_post(&common_sema);
 165                 return (0);
 166         }
 167 
 168         (void) sema_post(sema);
 169         return (1);
 170 }
 171 
 172 static void
 173 dozip(void)
 174 {
 175         /* not much here */
 176 }
 177 
 178 /*
 179  * _nscd_restart_if_cfgfile_changed()


1465  * cache are sorted based on destination address selection rules,
1466  * so when things change that could affect that sorting (interfaces
1467  * go up or down, flags change, etc.), we clear that cache so the
1468  * list will be re-ordered the next time the hostname is resolved.
1469  */
1470 static void
1471 rts_mon(void)
1472 {
1473         int     rt_sock, rdlen, idx;
1474         union {
1475                 struct {
1476                         struct rt_msghdr rtm;
1477                         struct sockaddr_storage addrs[RTA_NUMBITS];
1478                 } r;
1479                 struct if_msghdr ifm;
1480                 struct ifa_msghdr ifam;
1481         } mbuf;
1482         struct ifa_msghdr *ifam = &mbuf.ifam;
1483         char    *me = "rts_mon";
1484 
1485         (void) thr_setname(thr_self(), me);
1486 
1487         rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
1488         if (rt_sock < 0) {
1489                 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
1490                 (me, "Failed to open routing socket: %s\n", strerror(errno));
1491                 thr_exit(0);
1492         }
1493 
1494         for (;;) {
1495                 rdlen = read(rt_sock, &mbuf, sizeof (mbuf));
1496                 if (rdlen <= 0) {
1497                         if (rdlen == 0 || (errno != EINTR && errno != EAGAIN)) {
1498                                 _NSCD_LOG(NSCD_LOG_FRONT_END,
1499                                     NSCD_LOG_LEVEL_ERROR)
1500                                 (me, "routing socket read: %s\n",
1501                                     strerror(errno));
1502                                 thr_exit(0);
1503                         }
1504                         continue;
1505                 }
1506                 if (ifam->ifam_version != RTM_VERSION) {