4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include "nscd_switch.h"
33 * nscd_nsw_state_t list for each nss database. Protected
34 * by the readers/writer lock nscd_nsw_state_base_lock.
36 nscd_nsw_state_base_t
**nscd_nsw_state_base
;
37 static rwlock_t nscd_nsw_state_base_lock
= DEFAULTRWLOCK
;
45 char *me
= "_nscd_free_nsw_state";
47 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
48 (me
, "freeing nsw state = %p\n", s
);
53 if (s
->nsw_cfg_p
!= NULL
)
55 * an nsw state without base does not reference
56 * count the nsw config data (ie not using a
57 * shared one), so the one created for it should
60 if ((*s
->nsw_cfg_p
)->nobase
!= 1)
61 _nscd_release((nscd_acc_data_t
*)s
->nsw_cfg_p
);
63 (void) _nscd_set((nscd_acc_data_t
*)s
->nsw_cfg_p
, NULL
);
65 if (s
->be_db_pp
!= NULL
) {
66 for (i
= 0; i
< s
->max_src
; i
++) {
67 if (s
->be_db_pp
[i
] == NULL
)
69 _nscd_release((nscd_acc_data_t
*)s
->be_db_pp
[i
]);
70 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
71 (me
, "release db be ptr %p\n", s
->be_db_pp
[i
]);
77 for (i
= 0; i
< s
->max_src
; i
++) {
81 (void) NSS_INVOKE_DBOP(s
->be
[i
],
83 (void) NSS_INVOKE_DBOP(s
->be
[i
],
84 NSS_DBOP_DESTRUCTOR
, 0);
91 free(s
->be_version_p
);
93 /* remove reference to the nsw state base */
94 if (s
->base
!= NULL
) {
95 _nscd_release((nscd_acc_data_t
*)s
->base
);
99 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
100 (me
, "nsw state %p freed \n", s
);
106 _nscd_free_nsw_state_base(
107 nscd_acc_data_t
*data
)
109 nscd_nsw_state_base_t
*base
= (nscd_nsw_state_base_t
*)data
;
110 nscd_nsw_state_t
*s
, *ts
;
112 char *me
= "_nscd_free_nsw_state_base";
114 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
115 (me
, "freeing db state base %p\n", base
);
120 for (i
= 0; i
< 2; i
++) {
122 s
= base
->nsw_state
.first
;
124 s
= base
->nsw_state_thr
.first
;
128 _nscd_free_nsw_state(s
);
133 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
134 (me
, "nsw state base %p freed \n", base
);
138 _nscd_free_all_nsw_state_base()
140 nscd_nsw_state_base_t
*base
;
142 char *me
= "_nscd_free_all_nsw_state_base";
144 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
145 (me
, "freeing all db state base\n");
147 (void) rw_wrlock(&nscd_nsw_state_base_lock
);
148 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
150 base
= nscd_nsw_state_base
[i
];
151 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
152 NSCD_LOG_LEVEL_DEBUG
)
153 (me
, "freeing db state base (%d) %p \n", i
, base
);
158 nscd_nsw_state_base
[i
] = (nscd_nsw_state_base_t
*)
159 _nscd_set((nscd_acc_data_t
*)base
, NULL
);
161 (void) rw_unlock(&nscd_nsw_state_base_lock
);
164 static nscd_nsw_state_t
*
165 _nscd_create_nsw_state(
166 nscd_nsw_params_t
*params
)
169 nscd_nsw_config_t
*nsw_cfg
;
170 nscd_db_t
**be_db_p
, *be_db
;
172 char *me
= "_nscd_create_nsw_state";
175 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
176 (me
, "creating nsw state...\n");
178 s
= calloc(1, sizeof (nscd_nsw_state_t
));
180 if ((*s
->nsw_cfg_p
)->nobase
!= 1)
181 _nscd_release((nscd_acc_data_t
*)params
->nswcfg
);
182 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
183 (me
, "not able to allocate a nsw state\n");
186 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
187 (me
, "nsw state %p allocated\n", s
);
189 s
->dbi
= params
->dbi
;
192 nsw_cfg
= *params
->nswcfg
;
194 s
->nsw_cfg_p
= params
->nswcfg
;
195 s
->config
= nsw_cfg
->nsw_config
;
196 s
->max_src
= nsw_cfg
->max_src
;
199 s
->be
= calloc(s
->max_src
, sizeof (nss_backend_t
**));
201 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
202 (me
, "not able to allocate s->be\n");
204 _nscd_free_nsw_state(s
);
207 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
208 (me
, "db be array %p allocated\n", s
->be
);
211 s
->be_constr
= (nss_backend_constr_t
*)calloc(s
->max_src
,
212 sizeof (nss_backend_constr_t
));
213 if (s
->be_constr
== NULL
) {
214 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
215 (me
, "not able to allocate s->be_constr\n");
217 _nscd_free_nsw_state(s
);
220 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
221 (me
, "db be constructor array %p allocated\n", s
->be_constr
);
224 s
->be_version_p
= (void **)calloc(s
->max_src
, sizeof (void *));
225 if (s
->be_version_p
== NULL
) {
226 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
227 (me
, "not able to allocate s->be_version_p\n");
229 _nscd_free_nsw_state(s
);
232 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
233 (me
, "db be version ptr array %p allocated\n", s
->be_version_p
);
236 s
->be_db_pp
= calloc(s
->max_src
, sizeof (nscd_db_t
***));
237 if (s
->be_db_pp
== NULL
) {
238 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
239 (me
, "not able to allocate s->be_db_pp\n");
240 _nscd_free_nsw_state(s
);
243 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
244 (me
, "be_db_pp array %p allocated\n", s
->be_db_pp
);
247 /* create the source:database backends */
248 for (i
= 0; i
< s
->max_src
; i
++) {
253 struct __nsw_lookup_v1
*lkp
;
254 const nscd_db_entry_t
*dbe
;
255 nscd_be_info_t
*be_info
;
258 lkp
= s
->config
->lookups
;
262 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
263 (me
, "error: lkp is NULL\n");
264 _nscd_free_nsw_state(s
);
268 srci
= nsw_cfg
->src_idx
[i
];
269 srcn
= lkp
->service_name
;
270 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
271 (me
, "source name = %s, index = %d\n", srcn
, srci
);
273 be_db_p
= (nscd_db_t
**)_nscd_get(
274 (nscd_acc_data_t
*)nscd_src_backend_db
[srci
]);
275 if (be_db_p
== NULL
) {
276 _nscd_free_nsw_state(s
);
280 s
->be_db_pp
[i
] = be_db_p
;
281 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
282 (me
, "be db ptr array %p referenced\n", be_db_p
);
286 dbn
= params
->p
.name
;
287 dbe
= _nscd_get_db_entry(be_db
, NSCD_DATA_BACKEND_INFO
,
288 (const char *)dbn
, NSCD_GET_FIRST_DB_ENTRY
, 0);
290 be_info
= (nscd_be_info_t
*)*(dbe
->data_array
);
292 if (be_info
== NULL
|| be_info
->be_constr
== NULL
) {
293 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
294 (me
, "no backend info or be_constr is NULL "
295 "for <%s : %s>\n", NSCD_NSW_SRC_NAME(srci
),
298 s
->be_constr
[i
] = be_info
->be_constr
;
299 be
= (be_info
->be_constr
)(dbn
,
300 NSCD_NSW_SRC_NAME(srci
), 0);
302 s
->recheck_be
= nscd_true
;
306 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
307 (me
, "not able to init be for <%s : %s>\n",
308 NSCD_NSW_SRC_NAME(srci
), dbn
);
310 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
311 (me
, "releasing db be ptr %p\n", be_db_p
);
313 _nscd_release((nscd_acc_data_t
*)be_db_p
);
314 s
->be_db_pp
[i
] = NULL
;
320 s
->be_version_p
[i
] = be_info
->be_version
;
321 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
322 (me
, "backend version is %p\n", be_info
->be_version
);
327 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
328 (me
, "NO backend found, returning NULL\n");
330 _nscd_free_nsw_state(s
);
338 * Try to initialize the backend instances one more time
339 * in case the dependencies the backend libraries depend
340 * on are now available
349 struct __nsw_lookup_v1
*lkp
;
351 dbn
= NSCD_NSW_DB_NAME(s
->dbi
);
353 s
->recheck_be
= nscd_false
;
354 for (i
= 0; i
< s
->max_src
; i
++) {
357 lkp
= s
->config
->lookups
;
363 srcn
= lkp
->service_name
;
366 * it is possible that 's->be[i]' could not be
367 * initialized earlier due to a dependency not
368 * yet available (e.g., nis on domain name),
369 * try to initialize one more time
371 if (s
->be
[i
] == NULL
&& s
->be_constr
[i
] != NULL
) {
372 s
->be
[i
] = (s
->be_constr
[i
])(dbn
, srcn
, 0);
373 if (s
->be
[i
] == NULL
)
374 s
->recheck_be
= nscd_true
;
381 nss_db_root_t
*rootp
,
382 nscd_nsw_params_t
*params
,
386 nscd_nsw_state_t
*ret
= NULL
;
387 nscd_nsw_config_t
**nswcfg
;
388 nscd_nsw_state_base_t
*base
;
389 nscd_state_ctrl_t
*ctrl_p
;
390 int thread_only
= 0, wait_cond
= 0;
391 char *me
= "_get_nsw_state_int";
398 * no nsw state will be reused, if asked to use
399 * default config. So create the new structures
400 * used by the switch engine and the new nsw state
402 if (params
->p
.flags
& NSS_USE_DEFAULT_CONFIG
) {
403 rc
= _nscd_create_sw_struct(dbi
, -1, (char *)params
->p
.name
,
404 (char *)params
->p
.default_config
, NULL
, params
);
405 if (rc
!= NSCD_SUCCESS
)
408 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
409 (me
, "no base nsw config created for %s (sources: %s)\n",
410 params
->p
.name
, params
->p
.default_config
);
412 ret
= _nscd_create_nsw_state(params
);
414 return (NSCD_CREATE_NSW_STATE_FAILED
);
415 rootp
->s
= (struct nss_db_state
*)ret
;
416 return (NSCD_SUCCESS
);
420 * if getting a nsw state for a request from the compat
421 * backend, create the new switch structures if this
422 * is the first time around for a passwd, shadow, group,
423 * or user_attr database
425 if (params
->compati
!= -1) {
427 nscd_nsw_config_t
**nswcfg1
, **nswcfg2
;
428 int i
= params
->compati
;
433 * retrieve the pointer space which contains a
434 * pointer pointing to the nsswitch config
435 * structure for the compat backend
437 nswcfg
= (nscd_nsw_config_t
**)_nscd_get(
438 (nscd_acc_data_t
*)nscd_nsw_config
[i
]);
441 * If nsswitch config structure not created yet,
442 * get the config string from the passwd_compat
443 * or group_compat DB and create the structure.
445 if (*nswcfg
== NULL
) {
446 /* Wait first if it's being created. */
447 nswcfg2
= (nscd_nsw_config_t
**)_nscd_mutex_lock(
448 (nscd_acc_data_t
*)nscd_nsw_config
[i
]);
450 /* still not created yet */
451 if (*nswcfg2
== NULL
) {
453 * get the nsswitch config string specified
454 * for passwd_compat or group_compat
456 nswcfg1
= (nscd_nsw_config_t
**)_nscd_get(
458 nscd_nsw_config
[params
->cfgdbi
]);
459 if (nswcfg1
== NULL
) {
460 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
461 NSCD_LOG_LEVEL_ERROR
)
462 (me
, "no nsw config for %s\n",
465 (void) _nscd_mutex_unlock(
466 (nscd_acc_data_t
*)nswcfg2
);
467 _nscd_release((nscd_acc_data_t
*)
470 return (NSCD_CREATE_NSW_STATE_FAILED
);
473 rc
= _nscd_create_sw_struct(i
, params
->cfgdbi
,
474 params
->p
.name
, (*nswcfg1
)->nsw_cfg_str
,
476 _nscd_release((nscd_acc_data_t
*)nswcfg1
);
478 if (rc
== NSCD_SUCCESS
) {
479 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
480 NSCD_LOG_LEVEL_DEBUG
)
481 (me
, "nsw config created for %s (%s)\n",
483 (*nswcfg1
)->nsw_cfg_str
);
485 (void) _nscd_mutex_unlock(
486 (nscd_acc_data_t
*)nswcfg2
);
487 _nscd_release((nscd_acc_data_t
*)
492 (void) _nscd_mutex_unlock((nscd_acc_data_t
*)nswcfg2
);
494 _nscd_release((nscd_acc_data_t
*)nswcfg
);
497 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
498 base
= nscd_nsw_state_base
[dbi
];
499 (void) rw_unlock(&nscd_nsw_state_base_lock
);
501 assert(base
!= NULL
);
504 * If list is not empty, return the first one on list.
505 * Otherwise, create and return a new db state if the
506 * limit is not reached. if reacehed, wait for the 'one
507 * is available' signal.
509 assert(base
== (nscd_nsw_state_base_t
*)_nscd_mutex_lock(
510 (nscd_acc_data_t
*)base
));
513 ctrl_p
= &base
->nsw_state
;
516 ctrl_p
= &base
->nsw_state_thr
;
518 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
519 _nscd_logit(me
, "per thread nsw state info: \n");
520 _nscd_logit(me
, "tid = %d\n", *tid
);
521 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
522 _nscd_logit(me
, "number of free nsw_state = %d\n",
524 _nscd_logit(me
, "number of nsw state allocated = %d\n",
526 _nscd_logit(me
, "first nsw state on list = %p\n",
528 _nscd_logit(me
, "number of waiter = %d\n",
534 if (ctrl_p
->first
== NULL
&& ctrl_p
->allocated
== ctrl_p
->max
)
536 else if (thread_only
&& base
->used_by_thr
&& base
->tid
!= *tid
)
545 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
546 NSCD_LOG_LEVEL_DEBUG
)
547 (me
, "waiting for nsw state signal\n");
549 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
550 NSCD_LOG_LEVEL_DEBUG
)
551 (me
, "waiting for per thread "
552 "nsw state signal\n");
555 _nscd_cond_wait((nscd_acc_data_t
*)base
,
558 if (base
->used_by_thr
== 0 &&
559 ctrl_p
->first
!= NULL
)
562 _nscd_cond_wait((nscd_acc_data_t
*)base
, NULL
);
564 if (ctrl_p
->first
!= NULL
)
569 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
570 NSCD_LOG_LEVEL_DEBUG
)
571 (me
, "woke from cond wait ...wait_cond = %d\n",
575 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
576 NSCD_LOG_LEVEL_DEBUG
)
577 (me
, "woke from cond wait (per thread) "
578 "...wait_cond = %d\n", wait_cond
);
585 if (ctrl_p
->first
== NULL
) {
589 * for lookup calls from the compat backend
590 * uses the switch policy for passwd_compat
593 if (params
->compati
!= -1)
594 geti
= params
->compati
;
598 params
->nswcfg
= (nscd_nsw_config_t
**)_nscd_get(
599 (nscd_acc_data_t
*)nscd_nsw_config
[geti
]);
600 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
601 (me
, "got a nsw config %p for index %d\n",
602 params
->nswcfg
, geti
);
604 ctrl_p
->first
= _nscd_create_nsw_state(params
);
605 if (ctrl_p
->first
!= NULL
) {
607 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
608 NSCD_LOG_LEVEL_DEBUG
)
609 (me
, "got a new nsw_state %p\n", ctrl_p
->first
);
611 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
612 NSCD_LOG_LEVEL_DEBUG
)
613 (me
, "got a new per thread nsw_state %p\n",
619 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
620 (me
, "error: unable to obtain a nsw state\n");
621 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
622 return (NSCD_CREATE_NSW_STATE_FAILED
);
627 if (ret
->recheck_be
== nscd_true
)
629 ctrl_p
->first
= ret
->next
;
634 base
->used_by_thr
= 1;
636 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
637 _nscd_logit(me
, "\t\t\tgot a per thread nsw "
638 "state %p: \n", ret
);
639 _nscd_logit(me
, "tid = %d\n", *tid
);
640 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
641 _nscd_logit(me
, "number of free nsw_state = %d\n",
643 _nscd_logit(me
, "number od nsw state allocated = %d\n",
645 _nscd_logit(me
, "first nsw state on list = %p\n",
647 _nscd_logit(me
, "number of waiter = %d\n",
652 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
653 (me
, "got old nsw state %p\n", ret
);
656 * reference count the nsswitch state base bfore handing out
659 ret
->base
= (nscd_nsw_state_base_t
*)
660 _nscd_get((nscd_acc_data_t
*)base
);
662 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
664 rootp
->s
= (struct nss_db_state
*)ret
;
666 return (NSCD_SUCCESS
);
671 nss_db_root_t
*rootp
,
672 nscd_nsw_params_t
*params
)
674 return (_get_nsw_state_int(rootp
, params
, NULL
));
678 _nscd_get_nsw_state_thread(
679 nss_db_root_t
*rootp
,
680 nscd_nsw_params_t
*params
)
682 thread_t tid
= thr_self();
683 return (_get_nsw_state_int(rootp
, params
, &tid
));
693 nscd_nsw_state_base_t
*base
;
694 nscd_state_ctrl_t
*ctrl_p
;
696 char *me
= "_put_nsw_state_int";
698 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
699 (me
, "put back a nsw state\n");
702 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
703 (me
, "nsw state is NULL, nothing to put back\n");
708 * no need to put back if the nsw state is not on any base
709 * but need to free the resources used
711 if ((*s
->nsw_cfg_p
)->nobase
== 1) {
712 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
713 (me
, "no base nsw state, freeing resources ...\n");
715 _nscd_free_nsw_state(s
);
724 if (_nscd_mutex_lock((nscd_acc_data_t
*)base
) == NULL
) {
725 /* base has been freed or no longer valid, free the nsw state */
726 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
727 (me
, "nsw state base gone or no longer valid, freeing %p\n", s
);
728 _nscd_free_nsw_state(s
);
733 ctrl_p
= &base
->nsw_state_thr
;
735 ctrl_p
= &base
->nsw_state
;
737 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
738 _nscd_logit(me
, "before returning the nsw state: \n");
739 _nscd_logit(me
, "tid = %d\n", (tid
== NULL
) ? -1 : *tid
);
740 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
741 _nscd_logit(me
, "number of free nsw_state = %d\n",
743 _nscd_logit(me
, "number od nsw state allocated = %d\n",
745 _nscd_logit(me
, "first nsw state on list = %p\n",
747 _nscd_logit(me
, "number of waiter = %d\n", ctrl_p
->waiter
);
750 if (ctrl_p
->first
!= NULL
) {
751 s
->next
= ctrl_p
->first
;
760 * Remove reference to the nsswitch state base.
762 _nscd_release((nscd_acc_data_t
*)base
);
765 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
766 (me
, "signaling waiter thread_only = %d..\n", thread_only
);
768 if (thread_only
&& ctrl_p
->free
== ctrl_p
->allocated
) {
769 assert(ctrl_p
->first
!= NULL
);
770 base
->used_by_thr
= 0;
771 if (ctrl_p
->waiter
> 0) {
772 (void) cond_signal(&base
->thr_cond
);
776 if (!thread_only
&& ctrl_p
->waiter
> 0) {
778 _nscd_cond_signal((nscd_acc_data_t
*)base
);
781 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
782 _nscd_logit(me
, "after the nsw state is returned: \n");
783 _nscd_logit(me
, "tid = %d\n", (tid
== NULL
) ? -1 : *tid
);
784 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
785 _nscd_logit(me
, "number of free nsw_state = %d\n",
787 _nscd_logit(me
, "number od nsw state allocated = %d\n",
789 _nscd_logit(me
, "first nsw state on list = %p\n",
791 _nscd_logit(me
, "tnumber of waiter = %d\n", ctrl_p
->waiter
);
794 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
795 (me
, "done putting back nsw state %p, thread_only = %d\n",
798 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
806 _put_nsw_state_int(s
, NULL
);
810 _nscd_put_nsw_state_thread(
813 thread_t tid
= thr_self();
814 _put_nsw_state_int(s
, &tid
);
818 _nscd_init_nsw_state_base(
824 nscd_nsw_state_base_t
*base
= NULL
;
825 char *me
= "_nscd_init_nsw_state_base";
828 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
830 base
= (nscd_nsw_state_base_t
*)_nscd_alloc(
831 NSCD_DATA_NSW_STATE_BASE
,
832 sizeof (nscd_nsw_state_base_t
),
833 _nscd_free_nsw_state_base
,
834 NSCD_ALLOC_MUTEX
| NSCD_ALLOC_COND
);
837 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
838 NSCD_LOG_LEVEL_ERROR
)
839 (me
, "not able to allocate a nsw state base\n");
841 (void) rw_unlock(&nscd_nsw_state_base_lock
);
842 return (NSCD_NO_MEMORY
);
844 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
845 (me
, "nsw state base %p allocated\n", base
);
848 * initialize and activate the new nss_nsw_state base
851 if (compat_basei
!= -1)
852 cfgdbi
= compat_basei
;
856 base
->nsw_state
.max
= NSCD_SW_CFG(cfgdbi
).max_nsw_state_per_db
;
857 base
->nsw_state_thr
.max
= NSCD_SW_CFG(cfgdbi
).max_nsw_state_per_thread
;
859 nscd_nsw_state_base
[dbi
] = (nscd_nsw_state_base_t
*)_nscd_set(
860 (nscd_acc_data_t
*)nscd_nsw_state_base
[dbi
],
861 (nscd_acc_data_t
*)base
);
864 (void) rw_unlock(&nscd_nsw_state_base_lock
);
866 return (NSCD_SUCCESS
);
870 _nscd_init_all_nsw_state_base()
874 char *me
= "_nscd_init_all_nsw_state_base";
876 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
878 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
880 rc
= _nscd_init_nsw_state_base(i
, -1, 0);
882 if (rc
!= NSCD_SUCCESS
) {
883 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
884 NSCD_LOG_LEVEL_ERROR
)
885 (me
, "not able to initialize a nsw db state "
888 (void) rw_unlock(&nscd_nsw_state_base_lock
);
892 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
893 (me
, "all nsw state base initialized\n");
895 (void) rw_unlock(&nscd_nsw_state_base_lock
);
897 return (NSCD_SUCCESS
);
901 _nscd_alloc_nsw_state_base()
904 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
906 nscd_nsw_state_base
= calloc(NSCD_NUM_DB
,
907 sizeof (nscd_nsw_state_base_t
*));
908 if (nscd_nsw_state_base
== NULL
) {
909 (void) rw_unlock(&nscd_nsw_state_base_lock
);
910 return (NSCD_NO_MEMORY
);
913 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
915 return (NSCD_SUCCESS
);