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);
89 if (s
->be_constr
!= NULL
)
92 if (s
->be_version_p
!= NULL
)
93 free(s
->be_version_p
);
95 /* remove reference to the nsw state base */
96 if (s
->base
!= NULL
) {
97 _nscd_release((nscd_acc_data_t
*)s
->base
);
101 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
102 (me
, "nsw state %p freed \n", s
);
108 _nscd_free_nsw_state_base(
109 nscd_acc_data_t
*data
)
111 nscd_nsw_state_base_t
*base
= (nscd_nsw_state_base_t
*)data
;
112 nscd_nsw_state_t
*s
, *ts
;
114 char *me
= "_nscd_free_nsw_state_base";
116 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
117 (me
, "freeing db state base %p\n", base
);
122 for (i
= 0; i
< 2; i
++) {
124 s
= base
->nsw_state
.first
;
126 s
= base
->nsw_state_thr
.first
;
130 _nscd_free_nsw_state(s
);
135 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
136 (me
, "nsw state base %p freed \n", base
);
140 _nscd_free_all_nsw_state_base()
142 nscd_nsw_state_base_t
*base
;
144 char *me
= "_nscd_free_all_nsw_state_base";
146 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
147 (me
, "freeing all db state base\n");
149 (void) rw_wrlock(&nscd_nsw_state_base_lock
);
150 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
152 base
= nscd_nsw_state_base
[i
];
153 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
154 NSCD_LOG_LEVEL_DEBUG
)
155 (me
, "freeing db state base (%d) %p \n", i
, base
);
160 nscd_nsw_state_base
[i
] = (nscd_nsw_state_base_t
*)
161 _nscd_set((nscd_acc_data_t
*)base
, NULL
);
163 (void) rw_unlock(&nscd_nsw_state_base_lock
);
166 static nscd_nsw_state_t
*
167 _nscd_create_nsw_state(
168 nscd_nsw_params_t
*params
)
171 nscd_nsw_config_t
*nsw_cfg
;
172 nscd_db_t
**be_db_p
, *be_db
;
174 char *me
= "_nscd_create_nsw_state";
177 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
178 (me
, "creating nsw state...\n");
180 s
= calloc(1, sizeof (nscd_nsw_state_t
));
182 if ((*s
->nsw_cfg_p
)->nobase
!= 1)
183 _nscd_release((nscd_acc_data_t
*)params
->nswcfg
);
184 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
185 (me
, "not able to allocate a nsw state\n");
188 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
189 (me
, "nsw state %p allocated\n", s
);
191 s
->dbi
= params
->dbi
;
194 nsw_cfg
= *params
->nswcfg
;
196 s
->nsw_cfg_p
= params
->nswcfg
;
197 s
->config
= nsw_cfg
->nsw_config
;
198 s
->max_src
= nsw_cfg
->max_src
;
201 s
->be
= calloc(s
->max_src
, sizeof (nss_backend_t
**));
203 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
204 (me
, "not able to allocate s->be\n");
206 _nscd_free_nsw_state(s
);
209 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
210 (me
, "db be array %p allocated\n", s
->be
);
213 s
->be_constr
= (nss_backend_constr_t
*)calloc(s
->max_src
,
214 sizeof (nss_backend_constr_t
));
215 if (s
->be_constr
== NULL
) {
216 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
217 (me
, "not able to allocate s->be_constr\n");
219 _nscd_free_nsw_state(s
);
222 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
223 (me
, "db be constructor array %p allocated\n", s
->be_constr
);
226 s
->be_version_p
= (void **)calloc(s
->max_src
, sizeof (void *));
227 if (s
->be_version_p
== NULL
) {
228 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
229 (me
, "not able to allocate s->be_version_p\n");
231 _nscd_free_nsw_state(s
);
234 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
235 (me
, "db be version ptr array %p allocated\n", s
->be_version_p
);
238 s
->be_db_pp
= calloc(s
->max_src
, sizeof (nscd_db_t
***));
239 if (s
->be_db_pp
== NULL
) {
240 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
241 (me
, "not able to allocate s->be_db_pp\n");
242 _nscd_free_nsw_state(s
);
245 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
246 (me
, "be_db_pp array %p allocated\n", s
->be_db_pp
);
249 /* create the source:database backends */
250 for (i
= 0; i
< s
->max_src
; i
++) {
255 struct __nsw_lookup_v1
*lkp
;
256 const nscd_db_entry_t
*dbe
;
257 nscd_be_info_t
*be_info
;
260 lkp
= s
->config
->lookups
;
264 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
265 (me
, "error: lkp is NULL\n");
266 _nscd_free_nsw_state(s
);
270 srci
= nsw_cfg
->src_idx
[i
];
271 srcn
= lkp
->service_name
;
272 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
273 (me
, "source name = %s, index = %d\n", srcn
, srci
);
275 be_db_p
= (nscd_db_t
**)_nscd_get(
276 (nscd_acc_data_t
*)nscd_src_backend_db
[srci
]);
277 if (be_db_p
== NULL
) {
278 _nscd_free_nsw_state(s
);
282 s
->be_db_pp
[i
] = be_db_p
;
283 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
284 (me
, "be db ptr array %p referenced\n", be_db_p
);
288 dbn
= params
->p
.name
;
289 dbe
= _nscd_get_db_entry(be_db
, NSCD_DATA_BACKEND_INFO
,
290 (const char *)dbn
, NSCD_GET_FIRST_DB_ENTRY
, 0);
292 be_info
= (nscd_be_info_t
*)*(dbe
->data_array
);
294 if (be_info
== NULL
|| be_info
->be_constr
== NULL
) {
295 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
296 (me
, "no backend info or be_constr is NULL "
297 "for <%s : %s>\n", NSCD_NSW_SRC_NAME(srci
),
300 s
->be_constr
[i
] = be_info
->be_constr
;
301 be
= (be_info
->be_constr
)(dbn
,
302 NSCD_NSW_SRC_NAME(srci
), 0);
304 s
->recheck_be
= nscd_true
;
308 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
309 (me
, "not able to init be for <%s : %s>\n",
310 NSCD_NSW_SRC_NAME(srci
), dbn
);
312 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
313 (me
, "releasing db be ptr %p\n", be_db_p
);
315 _nscd_release((nscd_acc_data_t
*)be_db_p
);
316 s
->be_db_pp
[i
] = NULL
;
322 s
->be_version_p
[i
] = be_info
->be_version
;
323 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
324 (me
, "backend version is %p\n", be_info
->be_version
);
329 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
330 (me
, "NO backend found, returning NULL\n");
332 _nscd_free_nsw_state(s
);
340 * Try to initialize the backend instances one more time
341 * in case the dependencies the backend libraries depend
342 * on are now available
351 struct __nsw_lookup_v1
*lkp
;
353 dbn
= NSCD_NSW_DB_NAME(s
->dbi
);
355 s
->recheck_be
= nscd_false
;
356 for (i
= 0; i
< s
->max_src
; i
++) {
359 lkp
= s
->config
->lookups
;
365 srcn
= lkp
->service_name
;
368 * it is possible that 's->be[i]' could not be
369 * initialized earlier due to a dependency not
370 * yet available (e.g., nis on domain name),
371 * try to initialize one more time
373 if (s
->be
[i
] == NULL
&& s
->be_constr
[i
] != NULL
) {
374 s
->be
[i
] = (s
->be_constr
[i
])(dbn
, srcn
, 0);
375 if (s
->be
[i
] == NULL
)
376 s
->recheck_be
= nscd_true
;
383 nss_db_root_t
*rootp
,
384 nscd_nsw_params_t
*params
,
388 nscd_nsw_state_t
*ret
= NULL
;
389 nscd_nsw_config_t
**nswcfg
;
390 nscd_nsw_state_base_t
*base
;
391 nscd_state_ctrl_t
*ctrl_p
;
392 int thread_only
= 0, wait_cond
= 0;
393 char *me
= "_get_nsw_state_int";
400 * no nsw state will be reused, if asked to use
401 * default config. So create the new structures
402 * used by the switch engine and the new nsw state
404 if (params
->p
.flags
& NSS_USE_DEFAULT_CONFIG
) {
405 rc
= _nscd_create_sw_struct(dbi
, -1, (char *)params
->p
.name
,
406 (char *)params
->p
.default_config
, NULL
, params
);
407 if (rc
!= NSCD_SUCCESS
)
410 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
411 (me
, "no base nsw config created for %s (sources: %s)\n",
412 params
->p
.name
, params
->p
.default_config
);
414 ret
= _nscd_create_nsw_state(params
);
416 return (NSCD_CREATE_NSW_STATE_FAILED
);
417 rootp
->s
= (struct nss_db_state
*)ret
;
418 return (NSCD_SUCCESS
);
422 * if getting a nsw state for a request from the compat
423 * backend, create the new switch structures if this
424 * is the first time around for a passwd, shadow, group,
425 * or user_attr database
427 if (params
->compati
!= -1) {
429 nscd_nsw_config_t
**nswcfg1
, **nswcfg2
;
430 int i
= params
->compati
;
435 * retrieve the pointer space which contains a
436 * pointer pointing to the nsswitch config
437 * structure for the compat backend
439 nswcfg
= (nscd_nsw_config_t
**)_nscd_get(
440 (nscd_acc_data_t
*)nscd_nsw_config
[i
]);
443 * If nsswitch config structure not created yet,
444 * get the config string from the passwd_compat
445 * or group_compat DB and create the structure.
447 if (*nswcfg
== NULL
) {
448 /* Wait first if it's being created. */
449 nswcfg2
= (nscd_nsw_config_t
**)_nscd_mutex_lock(
450 (nscd_acc_data_t
*)nscd_nsw_config
[i
]);
452 /* still not created yet */
453 if (*nswcfg2
== NULL
) {
455 * get the nsswitch config string specified
456 * for passwd_compat or group_compat
458 nswcfg1
= (nscd_nsw_config_t
**)_nscd_get(
460 nscd_nsw_config
[params
->cfgdbi
]);
461 if (nswcfg1
== NULL
) {
462 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
463 NSCD_LOG_LEVEL_ERROR
)
464 (me
, "no nsw config for %s\n",
467 (void) _nscd_mutex_unlock(
468 (nscd_acc_data_t
*)nswcfg2
);
469 _nscd_release((nscd_acc_data_t
*)
472 return (NSCD_CREATE_NSW_STATE_FAILED
);
475 rc
= _nscd_create_sw_struct(i
, params
->cfgdbi
,
476 params
->p
.name
, (*nswcfg1
)->nsw_cfg_str
,
478 _nscd_release((nscd_acc_data_t
*)nswcfg1
);
480 if (rc
== NSCD_SUCCESS
) {
481 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
482 NSCD_LOG_LEVEL_DEBUG
)
483 (me
, "nsw config created for %s (%s)\n",
485 (*nswcfg1
)->nsw_cfg_str
);
487 (void) _nscd_mutex_unlock(
488 (nscd_acc_data_t
*)nswcfg2
);
489 _nscd_release((nscd_acc_data_t
*)
494 (void) _nscd_mutex_unlock((nscd_acc_data_t
*)nswcfg2
);
496 _nscd_release((nscd_acc_data_t
*)nswcfg
);
499 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
500 base
= nscd_nsw_state_base
[dbi
];
501 (void) rw_unlock(&nscd_nsw_state_base_lock
);
503 assert(base
!= NULL
);
506 * If list is not empty, return the first one on list.
507 * Otherwise, create and return a new db state if the
508 * limit is not reached. if reacehed, wait for the 'one
509 * is available' signal.
511 assert(base
== (nscd_nsw_state_base_t
*)_nscd_mutex_lock(
512 (nscd_acc_data_t
*)base
));
515 ctrl_p
= &base
->nsw_state
;
518 ctrl_p
= &base
->nsw_state_thr
;
520 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
521 _nscd_logit(me
, "per thread nsw state info: \n");
522 _nscd_logit(me
, "tid = %d\n", *tid
);
523 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
524 _nscd_logit(me
, "number of free nsw_state = %d\n",
526 _nscd_logit(me
, "number of nsw state allocated = %d\n",
528 _nscd_logit(me
, "first nsw state on list = %p\n",
530 _nscd_logit(me
, "number of waiter = %d\n",
536 if (ctrl_p
->first
== NULL
&& ctrl_p
->allocated
== ctrl_p
->max
)
538 else if (thread_only
&& base
->used_by_thr
&& base
->tid
!= *tid
)
547 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
548 NSCD_LOG_LEVEL_DEBUG
)
549 (me
, "waiting for nsw state signal\n");
551 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
552 NSCD_LOG_LEVEL_DEBUG
)
553 (me
, "waiting for per thread "
554 "nsw state signal\n");
557 _nscd_cond_wait((nscd_acc_data_t
*)base
,
560 if (base
->used_by_thr
== 0 &&
561 ctrl_p
->first
!= NULL
)
564 _nscd_cond_wait((nscd_acc_data_t
*)base
, NULL
);
566 if (ctrl_p
->first
!= NULL
)
571 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
572 NSCD_LOG_LEVEL_DEBUG
)
573 (me
, "woke from cond wait ...wait_cond = %d\n",
577 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
578 NSCD_LOG_LEVEL_DEBUG
)
579 (me
, "woke from cond wait (per thread) "
580 "...wait_cond = %d\n", wait_cond
);
587 if (ctrl_p
->first
== NULL
) {
591 * for lookup calls from the compat backend
592 * uses the switch policy for passwd_compat
595 if (params
->compati
!= -1)
596 geti
= params
->compati
;
600 params
->nswcfg
= (nscd_nsw_config_t
**)_nscd_get(
601 (nscd_acc_data_t
*)nscd_nsw_config
[geti
]);
602 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
603 (me
, "got a nsw config %p for index %d\n",
604 params
->nswcfg
, geti
);
606 ctrl_p
->first
= _nscd_create_nsw_state(params
);
607 if (ctrl_p
->first
!= NULL
) {
609 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
610 NSCD_LOG_LEVEL_DEBUG
)
611 (me
, "got a new nsw_state %p\n", ctrl_p
->first
);
613 _NSCD_LOG(NSCD_LOG_NSW_STATE
,
614 NSCD_LOG_LEVEL_DEBUG
)
615 (me
, "got a new per thread nsw_state %p\n",
621 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_ERROR
)
622 (me
, "error: unable to obtain a nsw state\n");
623 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
624 return (NSCD_CREATE_NSW_STATE_FAILED
);
629 if (ret
->recheck_be
== nscd_true
)
631 ctrl_p
->first
= ret
->next
;
636 base
->used_by_thr
= 1;
638 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
639 _nscd_logit(me
, "\t\t\tgot a per thread nsw "
640 "state %p: \n", ret
);
641 _nscd_logit(me
, "tid = %d\n", *tid
);
642 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
643 _nscd_logit(me
, "number of free nsw_state = %d\n",
645 _nscd_logit(me
, "number od nsw state allocated = %d\n",
647 _nscd_logit(me
, "first nsw state on list = %p\n",
649 _nscd_logit(me
, "number of waiter = %d\n",
654 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
655 (me
, "got old nsw state %p\n", ret
);
658 * reference count the nsswitch state base bfore handing out
661 ret
->base
= (nscd_nsw_state_base_t
*)
662 _nscd_get((nscd_acc_data_t
*)base
);
664 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
666 rootp
->s
= (struct nss_db_state
*)ret
;
668 return (NSCD_SUCCESS
);
673 nss_db_root_t
*rootp
,
674 nscd_nsw_params_t
*params
)
676 return (_get_nsw_state_int(rootp
, params
, NULL
));
680 _nscd_get_nsw_state_thread(
681 nss_db_root_t
*rootp
,
682 nscd_nsw_params_t
*params
)
684 thread_t tid
= thr_self();
685 return (_get_nsw_state_int(rootp
, params
, &tid
));
695 nscd_nsw_state_base_t
*base
;
696 nscd_state_ctrl_t
*ctrl_p
;
698 char *me
= "_put_nsw_state_int";
700 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
701 (me
, "put back a nsw state\n");
704 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
705 (me
, "nsw state is NULL, nothing to put back\n");
710 * no need to put back if the nsw state is not on any base
711 * but need to free the resources used
713 if ((*s
->nsw_cfg_p
)->nobase
== 1) {
714 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
715 (me
, "no base nsw state, freeing resources ...\n");
717 _nscd_free_nsw_state(s
);
726 if (_nscd_mutex_lock((nscd_acc_data_t
*)base
) == NULL
) {
727 /* base has been freed or no longer valid, free the nsw state */
728 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
729 (me
, "nsw state base gone or no longer valid, freeing %p\n", s
);
730 _nscd_free_nsw_state(s
);
735 ctrl_p
= &base
->nsw_state_thr
;
737 ctrl_p
= &base
->nsw_state
;
739 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
740 _nscd_logit(me
, "before returning the nsw state: \n");
741 _nscd_logit(me
, "tid = %d\n", (tid
== NULL
) ? -1 : *tid
);
742 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
743 _nscd_logit(me
, "number of free nsw_state = %d\n",
745 _nscd_logit(me
, "number od nsw state allocated = %d\n",
747 _nscd_logit(me
, "first nsw state on list = %p\n",
749 _nscd_logit(me
, "number of waiter = %d\n", ctrl_p
->waiter
);
752 if (ctrl_p
->first
!= NULL
) {
753 s
->next
= ctrl_p
->first
;
762 * Remove reference to the nsswitch state base.
764 _nscd_release((nscd_acc_data_t
*)base
);
767 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
768 (me
, "signaling waiter thread_only = %d..\n", thread_only
);
770 if (thread_only
&& ctrl_p
->free
== ctrl_p
->allocated
) {
771 assert(ctrl_p
->first
!= NULL
);
772 base
->used_by_thr
= 0;
773 if (ctrl_p
->waiter
> 0) {
774 (void) cond_signal(&base
->thr_cond
);
778 if (!thread_only
&& ctrl_p
->waiter
> 0) {
780 _nscd_cond_signal((nscd_acc_data_t
*)base
);
783 _NSCD_LOG_IF(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
) {
784 _nscd_logit(me
, "after the nsw state is returned: \n");
785 _nscd_logit(me
, "tid = %d\n", (tid
== NULL
) ? -1 : *tid
);
786 _nscd_logit(me
, "tid in base = %d\n", base
->tid
);
787 _nscd_logit(me
, "number of free nsw_state = %d\n",
789 _nscd_logit(me
, "number od nsw state allocated = %d\n",
791 _nscd_logit(me
, "first nsw state on list = %p\n",
793 _nscd_logit(me
, "tnumber of waiter = %d\n", ctrl_p
->waiter
);
796 _NSCD_LOG(NSCD_LOG_NSW_STATE
, NSCD_LOG_LEVEL_DEBUG
)
797 (me
, "done putting back nsw state %p, thread_only = %d\n",
800 _nscd_mutex_unlock((nscd_acc_data_t
*)base
);
808 _put_nsw_state_int(s
, NULL
);
812 _nscd_put_nsw_state_thread(
815 thread_t tid
= thr_self();
816 _put_nsw_state_int(s
, &tid
);
820 _nscd_init_nsw_state_base(
826 nscd_nsw_state_base_t
*base
= NULL
;
827 char *me
= "_nscd_init_nsw_state_base";
830 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
832 base
= (nscd_nsw_state_base_t
*)_nscd_alloc(
833 NSCD_DATA_NSW_STATE_BASE
,
834 sizeof (nscd_nsw_state_base_t
),
835 _nscd_free_nsw_state_base
,
836 NSCD_ALLOC_MUTEX
| NSCD_ALLOC_COND
);
839 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
840 NSCD_LOG_LEVEL_ERROR
)
841 (me
, "not able to allocate a nsw state base\n");
843 (void) rw_unlock(&nscd_nsw_state_base_lock
);
844 return (NSCD_NO_MEMORY
);
846 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
847 (me
, "nsw state base %p allocated\n", base
);
850 * initialize and activate the new nss_nsw_state base
853 if (compat_basei
!= -1)
854 cfgdbi
= compat_basei
;
858 base
->nsw_state
.max
= NSCD_SW_CFG(cfgdbi
).max_nsw_state_per_db
;
859 base
->nsw_state_thr
.max
= NSCD_SW_CFG(cfgdbi
).max_nsw_state_per_thread
;
861 nscd_nsw_state_base
[dbi
] = (nscd_nsw_state_base_t
*)_nscd_set(
862 (nscd_acc_data_t
*)nscd_nsw_state_base
[dbi
],
863 (nscd_acc_data_t
*)base
);
866 (void) rw_unlock(&nscd_nsw_state_base_lock
);
868 return (NSCD_SUCCESS
);
872 _nscd_init_all_nsw_state_base()
876 char *me
= "_nscd_init_all_nsw_state_base";
878 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
880 for (i
= 0; i
< NSCD_NUM_DB
; i
++) {
882 rc
= _nscd_init_nsw_state_base(i
, -1, 0);
884 if (rc
!= NSCD_SUCCESS
) {
885 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
,
886 NSCD_LOG_LEVEL_ERROR
)
887 (me
, "not able to initialize a nsw db state "
890 (void) rw_unlock(&nscd_nsw_state_base_lock
);
894 _NSCD_LOG(NSCD_LOG_NSW_STATE
| NSCD_LOG_CONFIG
, NSCD_LOG_LEVEL_DEBUG
)
895 (me
, "all nsw state base initialized\n");
897 (void) rw_unlock(&nscd_nsw_state_base_lock
);
899 return (NSCD_SUCCESS
);
903 _nscd_alloc_nsw_state_base()
906 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
908 nscd_nsw_state_base
= calloc(NSCD_NUM_DB
,
909 sizeof (nscd_nsw_state_base_t
*));
910 if (nscd_nsw_state_base
== NULL
) {
911 (void) rw_unlock(&nscd_nsw_state_base_lock
);
912 return (NSCD_NO_MEMORY
);
915 (void) rw_rdlock(&nscd_nsw_state_base_lock
);
917 return (NSCD_SUCCESS
);