1cb5caa98Sdjl /* 2cb5caa98Sdjl * CDDL HEADER START 3cb5caa98Sdjl * 4cb5caa98Sdjl * The contents of this file are subject to the terms of the 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * You may not use this file except in compliance with the License. 7cb5caa98Sdjl * 8cb5caa98Sdjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9cb5caa98Sdjl * or http://www.opensolaris.org/os/licensing. 10cb5caa98Sdjl * See the License for the specific language governing permissions 11cb5caa98Sdjl * and limitations under the License. 12cb5caa98Sdjl * 13cb5caa98Sdjl * When distributing Covered Code, include this CDDL HEADER in each 14cb5caa98Sdjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15cb5caa98Sdjl * If applicable, add the following below this CDDL HEADER, with the 16cb5caa98Sdjl * fields enclosed by brackets "[]" replaced with your own identifying 17cb5caa98Sdjl * information: Portions Copyright [yyyy] [name of copyright owner] 18cb5caa98Sdjl * 19cb5caa98Sdjl * CDDL HEADER END 20cb5caa98Sdjl */ 21cb5caa98Sdjl /* 22*cfed26cbSMichen Chang * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23cb5caa98Sdjl * Use is subject to license terms. 24cb5caa98Sdjl */ 25cb5caa98Sdjl 26cb5caa98Sdjl #include <stdio.h> 27cb5caa98Sdjl #include <stdlib.h> 28cb5caa98Sdjl #include <assert.h> 29cb5caa98Sdjl #include <string.h> 30cb5caa98Sdjl #include "nscd_switch.h" 31cb5caa98Sdjl #include "nscd_log.h" 32cb5caa98Sdjl 33cb5caa98Sdjl /* 34cb5caa98Sdjl * nscd_nsw_state_t list for each nss database. Protected 35cb5caa98Sdjl * by the readers/writer lock nscd_nsw_state_base_lock. 36cb5caa98Sdjl */ 37cb5caa98Sdjl nscd_nsw_state_base_t **nscd_nsw_state_base; 38cb5caa98Sdjl static rwlock_t nscd_nsw_state_base_lock = DEFAULTRWLOCK; 39cb5caa98Sdjl 40cb5caa98Sdjl static void 41cb5caa98Sdjl _nscd_free_nsw_state( 42cb5caa98Sdjl nscd_nsw_state_t *s) 43cb5caa98Sdjl { 44cb5caa98Sdjl 45cb5caa98Sdjl int i; 46cb5caa98Sdjl char *me = "_nscd_free_nsw_state"; 47cb5caa98Sdjl 48cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 49cb5caa98Sdjl (me, "freeing nsw state = %p\n", s); 50cb5caa98Sdjl 51cb5caa98Sdjl if (s == NULL) 52cb5caa98Sdjl return; 53cb5caa98Sdjl 54cb5caa98Sdjl if (s->nsw_cfg_p != NULL) 55cb5caa98Sdjl /* 56cb5caa98Sdjl * an nsw state without base does not reference 57cb5caa98Sdjl * count the nsw config data (ie not using a 58cb5caa98Sdjl * shared one), so the one created for it should 59cb5caa98Sdjl * be freed 60cb5caa98Sdjl */ 61cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase != 1) 62cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)s->nsw_cfg_p); 63cb5caa98Sdjl else 643d047983Smichen (void) _nscd_set((nscd_acc_data_t *)s->nsw_cfg_p, NULL); 65cb5caa98Sdjl 66cb5caa98Sdjl if (s->be_db_pp != NULL) { 67cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 68cb5caa98Sdjl if (s->be_db_pp[i] == NULL) 69cb5caa98Sdjl continue; 70cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)s->be_db_pp[i]); 71cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 72cb5caa98Sdjl (me, "release db be ptr %p\n", s->be_db_pp[i]); 73cb5caa98Sdjl } 74cb5caa98Sdjl free(s->be_db_pp); 75cb5caa98Sdjl } 76cb5caa98Sdjl 77cb5caa98Sdjl if (s->be != NULL) { 78cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 79cb5caa98Sdjl if (s->be[i] == NULL) 80cb5caa98Sdjl continue; 81cb5caa98Sdjl if (s->getent == 1) 82cb5caa98Sdjl (void) NSS_INVOKE_DBOP(s->be[i], 83cb5caa98Sdjl NSS_DBOP_ENDENT, 0); 84cb5caa98Sdjl (void) NSS_INVOKE_DBOP(s->be[i], 85cb5caa98Sdjl NSS_DBOP_DESTRUCTOR, 0); 86cb5caa98Sdjl } 87cb5caa98Sdjl free(s->be); 88cb5caa98Sdjl } 89cb5caa98Sdjl 90bf1e3beeSmichen if (s->be_constr != NULL) 91bf1e3beeSmichen free(s->be_constr); 92bf1e3beeSmichen 93d2ba247cSmichen if (s->be_version_p != NULL) 94d2ba247cSmichen free(s->be_version_p); 95d2ba247cSmichen 96*cfed26cbSMichen Chang /* remove reference to the nsw state base */ 97*cfed26cbSMichen Chang if (s->base != NULL) { 98*cfed26cbSMichen Chang _nscd_release((nscd_acc_data_t *)s->base); 99cb5caa98Sdjl s->base = NULL; 100*cfed26cbSMichen Chang } 101cb5caa98Sdjl 102cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 103cb5caa98Sdjl (me, "nsw state %p freed \n", s); 104cb5caa98Sdjl 105cb5caa98Sdjl free(s); 106cb5caa98Sdjl } 107cb5caa98Sdjl 108cb5caa98Sdjl static void 109cb5caa98Sdjl _nscd_free_nsw_state_base( 110cb5caa98Sdjl nscd_acc_data_t *data) 111cb5caa98Sdjl { 112cb5caa98Sdjl nscd_nsw_state_base_t *base = (nscd_nsw_state_base_t *)data; 113cb5caa98Sdjl nscd_nsw_state_t *s, *ts; 114cb5caa98Sdjl int i; 115cb5caa98Sdjl char *me = "_nscd_free_nsw_state_base"; 116cb5caa98Sdjl 117cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 118cb5caa98Sdjl (me, "freeing db state base %p\n", base); 119cb5caa98Sdjl 120cb5caa98Sdjl if (base == NULL) 121cb5caa98Sdjl return; 122cb5caa98Sdjl 123cb5caa98Sdjl for (i = 0; i < 2; i++) { 124cb5caa98Sdjl if (i == 1) 125cb5caa98Sdjl s = base->nsw_state.first; 126cb5caa98Sdjl else 127cb5caa98Sdjl s = base->nsw_state_thr.first; 128cb5caa98Sdjl 129cb5caa98Sdjl while (s != NULL) { 130cb5caa98Sdjl ts = s->next; 131cb5caa98Sdjl _nscd_free_nsw_state(s); 132cb5caa98Sdjl s = ts; 133cb5caa98Sdjl } 134cb5caa98Sdjl } 135cb5caa98Sdjl 136cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 137cb5caa98Sdjl (me, "nsw state base %p freed \n", base); 138cb5caa98Sdjl } 139cb5caa98Sdjl 140cb5caa98Sdjl void 141cb5caa98Sdjl _nscd_free_all_nsw_state_base() 142cb5caa98Sdjl { 143cb5caa98Sdjl nscd_nsw_state_base_t *base; 144cb5caa98Sdjl int i; 145cb5caa98Sdjl char *me = "_nscd_free_all_nsw_state_base"; 146cb5caa98Sdjl 147cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 148cb5caa98Sdjl (me, "freeing all db state base\n"); 149cb5caa98Sdjl 150cb5caa98Sdjl (void) rw_wrlock(&nscd_nsw_state_base_lock); 151cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 152cb5caa98Sdjl 153cb5caa98Sdjl base = nscd_nsw_state_base[i]; 154cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 155cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 156cb5caa98Sdjl (me, "freeing db state base (%d) %p \n", i, base); 157cb5caa98Sdjl 158cb5caa98Sdjl if (base == NULL) 159cb5caa98Sdjl continue; 160cb5caa98Sdjl 161cb5caa98Sdjl nscd_nsw_state_base[i] = (nscd_nsw_state_base_t *) 162cb5caa98Sdjl _nscd_set((nscd_acc_data_t *)base, NULL); 163cb5caa98Sdjl } 164cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 165cb5caa98Sdjl } 166cb5caa98Sdjl 167cb5caa98Sdjl static nscd_nsw_state_t * 168cb5caa98Sdjl _nscd_create_nsw_state( 169cb5caa98Sdjl nscd_nsw_params_t *params) 170cb5caa98Sdjl { 171cb5caa98Sdjl nscd_nsw_state_t *s; 172cb5caa98Sdjl nscd_nsw_config_t *nsw_cfg; 173cb5caa98Sdjl nscd_db_t **be_db_p, *be_db; 174cb5caa98Sdjl int i, nobe = 1; 175cb5caa98Sdjl char *me = "_nscd_create_nsw_state"; 176cb5caa98Sdjl 177cb5caa98Sdjl 178cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 179cb5caa98Sdjl (me, "creating nsw state...\n"); 180cb5caa98Sdjl 181cb5caa98Sdjl s = calloc(1, sizeof (nscd_nsw_state_t)); 182cb5caa98Sdjl if (s == NULL) { 183cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase != 1) 184cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)params->nswcfg); 185cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 186cb5caa98Sdjl (me, "not able to allocate a nsw state\n"); 187cb5caa98Sdjl return (NULL); 188cb5caa98Sdjl } else 189cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 190cb5caa98Sdjl (me, "nsw state %p allocated\n", s); 191cb5caa98Sdjl 192cb5caa98Sdjl s->dbi = params->dbi; 193cb5caa98Sdjl s->next = NULL; 194cb5caa98Sdjl 195cb5caa98Sdjl nsw_cfg = *params->nswcfg; 196cb5caa98Sdjl 197cb5caa98Sdjl s->nsw_cfg_p = params->nswcfg; 198cb5caa98Sdjl s->config = nsw_cfg->nsw_config; 199cb5caa98Sdjl s->max_src = nsw_cfg->max_src; 200cb5caa98Sdjl s->p = params->p; 201cb5caa98Sdjl 202cb5caa98Sdjl s->be = calloc(s->max_src, sizeof (nss_backend_t **)); 203cb5caa98Sdjl if (s->be == NULL) { 204cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 205cb5caa98Sdjl (me, "not able to allocate s->be\n"); 206cb5caa98Sdjl 207cb5caa98Sdjl _nscd_free_nsw_state(s); 208cb5caa98Sdjl return (NULL); 209cb5caa98Sdjl } else { 210cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 211cb5caa98Sdjl (me, "db be array %p allocated\n", s->be); 212cb5caa98Sdjl } 213cb5caa98Sdjl 214bf1e3beeSmichen s->be_constr = (nss_backend_constr_t *)calloc(s->max_src, 215bf1e3beeSmichen sizeof (nss_backend_constr_t)); 216bf1e3beeSmichen if (s->be_constr == NULL) { 217bf1e3beeSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 218bf1e3beeSmichen (me, "not able to allocate s->be_constr\n"); 219bf1e3beeSmichen 220bf1e3beeSmichen _nscd_free_nsw_state(s); 221bf1e3beeSmichen return (NULL); 222bf1e3beeSmichen } else { 223bf1e3beeSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 224bf1e3beeSmichen (me, "db be constructor array %p allocated\n", s->be_constr); 225bf1e3beeSmichen } 226bf1e3beeSmichen 227d2ba247cSmichen s->be_version_p = (void **)calloc(s->max_src, sizeof (void *)); 228d2ba247cSmichen if (s->be_version_p == NULL) { 229d2ba247cSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 230d2ba247cSmichen (me, "not able to allocate s->be_version_p\n"); 231d2ba247cSmichen 232d2ba247cSmichen _nscd_free_nsw_state(s); 233d2ba247cSmichen return (NULL); 234d2ba247cSmichen } else { 235d2ba247cSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 236d2ba247cSmichen (me, "db be version ptr array %p allocated\n", s->be_version_p); 237d2ba247cSmichen } 238d2ba247cSmichen 239cb5caa98Sdjl s->be_db_pp = calloc(s->max_src, sizeof (nscd_db_t ***)); 240cb5caa98Sdjl if (s->be_db_pp == NULL) { 241cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 242cb5caa98Sdjl (me, "not able to allocate s->be_db_pp\n"); 243cb5caa98Sdjl _nscd_free_nsw_state(s); 244cb5caa98Sdjl return (NULL); 245cb5caa98Sdjl } else { 246cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 247cb5caa98Sdjl (me, "be_db_pp array %p allocated\n", s->be_db_pp); 248cb5caa98Sdjl } 249cb5caa98Sdjl 250cb5caa98Sdjl /* create the source:database backends */ 251cb5caa98Sdjl for (i = 0; i < s->max_src; i++) { 252cb5caa98Sdjl nss_backend_t *be; 253cb5caa98Sdjl int srci; 254cb5caa98Sdjl char *srcn; 255cb5caa98Sdjl const char *dbn; 256cb5caa98Sdjl struct __nsw_lookup_v1 *lkp; 257cb5caa98Sdjl const nscd_db_entry_t *dbe; 258cb5caa98Sdjl nscd_be_info_t *be_info; 259cb5caa98Sdjl 260cb5caa98Sdjl if (i == 0) 261cb5caa98Sdjl lkp = s->config->lookups; 262cb5caa98Sdjl else 263cb5caa98Sdjl lkp = lkp->next; 264cb5caa98Sdjl if (lkp == NULL) { 265cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 266cb5caa98Sdjl (me, "error: lkp is NULL\n"); 267cb5caa98Sdjl _nscd_free_nsw_state(s); 268cb5caa98Sdjl return (NULL); 269cb5caa98Sdjl } 270cb5caa98Sdjl 271cb5caa98Sdjl srci = nsw_cfg->src_idx[i]; 272cb5caa98Sdjl srcn = lkp->service_name; 273cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 274cb5caa98Sdjl (me, "source name = %s, index = %d\n", srcn, srci); 275cb5caa98Sdjl 276cb5caa98Sdjl be_db_p = (nscd_db_t **)_nscd_get( 277cb5caa98Sdjl (nscd_acc_data_t *)nscd_src_backend_db[srci]); 278cb5caa98Sdjl if (be_db_p == NULL) { 279cb5caa98Sdjl _nscd_free_nsw_state(s); 280cb5caa98Sdjl return (NULL); 281cb5caa98Sdjl } 282cb5caa98Sdjl be_db = *be_db_p; 283cb5caa98Sdjl s->be_db_pp[i] = be_db_p; 284cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 285cb5caa98Sdjl (me, "be db ptr array %p referenced\n", be_db_p); 286cb5caa98Sdjl 287cb5caa98Sdjl be_info = NULL; 288cb5caa98Sdjl be = NULL; 289cb5caa98Sdjl dbn = params->p.name; 290cb5caa98Sdjl dbe = _nscd_get_db_entry(be_db, NSCD_DATA_BACKEND_INFO, 291cb5caa98Sdjl (const char *)dbn, NSCD_GET_FIRST_DB_ENTRY, 0); 292cb5caa98Sdjl if (dbe != NULL) 293cb5caa98Sdjl be_info = (nscd_be_info_t *)*(dbe->data_array); 294cb5caa98Sdjl 295cb5caa98Sdjl if (be_info == NULL || be_info->be_constr == NULL) { 296cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 297cb5caa98Sdjl (me, "no backend info or be_constr is NULL " 298cb5caa98Sdjl "for <%s : %s>\n", NSCD_NSW_SRC_NAME(srci), 299cb5caa98Sdjl dbn); 300bf1e3beeSmichen } else { 301bf1e3beeSmichen s->be_constr[i] = be_info->be_constr; 302cb5caa98Sdjl be = (be_info->be_constr)(dbn, 303cb5caa98Sdjl NSCD_NSW_SRC_NAME(srci), 0); 304bf1e3beeSmichen if (be == NULL) 305bf1e3beeSmichen s->recheck_be = nscd_true; 306bf1e3beeSmichen } 307cb5caa98Sdjl 308cb5caa98Sdjl if (be == NULL) { 309cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 310cb5caa98Sdjl (me, "not able to init be for <%s : %s>\n", 311cb5caa98Sdjl NSCD_NSW_SRC_NAME(srci), dbn); 312cb5caa98Sdjl 313cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 314cb5caa98Sdjl (me, "releasing db be ptr %p\n", be_db_p); 315cb5caa98Sdjl 316cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)be_db_p); 317cb5caa98Sdjl s->be_db_pp[i] = NULL; 318cb5caa98Sdjl 319cb5caa98Sdjl continue; 320cb5caa98Sdjl } 321cb5caa98Sdjl 322cb5caa98Sdjl s->be[i] = be; 323d2ba247cSmichen s->be_version_p[i] = be_info->be_version; 324d2ba247cSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 325d2ba247cSmichen (me, "backend version is %p\n", be_info->be_version); 326cb5caa98Sdjl nobe = 0; 327cb5caa98Sdjl } 328cb5caa98Sdjl 329cb5caa98Sdjl if (nobe == 1) { 330cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 331cb5caa98Sdjl (me, "NO backend found, returning NULL\n"); 332cb5caa98Sdjl 333cb5caa98Sdjl _nscd_free_nsw_state(s); 334cb5caa98Sdjl return (NULL); 335cb5caa98Sdjl } 336cb5caa98Sdjl 337cb5caa98Sdjl return (s); 338cb5caa98Sdjl } 339cb5caa98Sdjl 340bf1e3beeSmichen /* 341bf1e3beeSmichen * Try to initialize the backend instances one more time 342bf1e3beeSmichen * in case the dependencies the backend libraries depend 343bf1e3beeSmichen * on are now available 344bf1e3beeSmichen */ 345bf1e3beeSmichen static void 346bf1e3beeSmichen check_be_array( 347bf1e3beeSmichen nscd_nsw_state_t *s) 348bf1e3beeSmichen { 349bf1e3beeSmichen int i; 350bf1e3beeSmichen char *dbn; 351bf1e3beeSmichen char *srcn; 352bf1e3beeSmichen struct __nsw_lookup_v1 *lkp; 353bf1e3beeSmichen 354bf1e3beeSmichen dbn = NSCD_NSW_DB_NAME(s->dbi); 355bf1e3beeSmichen 356bf1e3beeSmichen s->recheck_be = nscd_false; 357bf1e3beeSmichen for (i = 0; i < s->max_src; i++) { 358bf1e3beeSmichen 359bf1e3beeSmichen if (i == 0) 360bf1e3beeSmichen lkp = s->config->lookups; 361bf1e3beeSmichen else 362bf1e3beeSmichen lkp = lkp->next; 363bf1e3beeSmichen if (lkp == NULL) 364bf1e3beeSmichen return; 365bf1e3beeSmichen 366bf1e3beeSmichen srcn = lkp->service_name; 367bf1e3beeSmichen 368bf1e3beeSmichen /* 369bf1e3beeSmichen * it is possible that 's->be[i]' could not be 370bf1e3beeSmichen * initialized earlier due to a dependency not 371bf1e3beeSmichen * yet available (e.g., nis on domain name), 372bf1e3beeSmichen * try to initialize one more time 373bf1e3beeSmichen */ 374bf1e3beeSmichen if (s->be[i] == NULL && s->be_constr[i] != NULL) { 375bf1e3beeSmichen s->be[i] = (s->be_constr[i])(dbn, srcn, 0); 376bf1e3beeSmichen if (s->be[i] == NULL) 377bf1e3beeSmichen s->recheck_be = nscd_true; 378bf1e3beeSmichen } 379bf1e3beeSmichen } 380bf1e3beeSmichen } 381bf1e3beeSmichen 382cb5caa98Sdjl static nscd_rc_t 383cb5caa98Sdjl _get_nsw_state_int( 384cb5caa98Sdjl nss_db_root_t *rootp, 385cb5caa98Sdjl nscd_nsw_params_t *params, 386cb5caa98Sdjl thread_t *tid) 387cb5caa98Sdjl { 388cb5caa98Sdjl 389cb5caa98Sdjl nscd_nsw_state_t *ret = NULL; 390cb5caa98Sdjl nscd_nsw_config_t **nswcfg; 391cb5caa98Sdjl nscd_nsw_state_base_t *base; 392cb5caa98Sdjl nscd_state_ctrl_t *ctrl_p; 393cb5caa98Sdjl int thread_only = 0, wait_cond = 0; 394cb5caa98Sdjl char *me = "_get_nsw_state_int"; 395cb5caa98Sdjl int dbi; 396cb5caa98Sdjl nscd_rc_t rc; 397cb5caa98Sdjl 398cb5caa98Sdjl dbi = params->dbi; 399cb5caa98Sdjl 400cb5caa98Sdjl /* 401cb5caa98Sdjl * no nsw state will be reused, if asked to use 402cb5caa98Sdjl * default config. So create the new structures 403cb5caa98Sdjl * used by the switch engine and the new nsw state 404cb5caa98Sdjl */ 405cb5caa98Sdjl if (params->p.flags & NSS_USE_DEFAULT_CONFIG) { 406ad0e80f7Smichen rc = _nscd_create_sw_struct(dbi, -1, (char *)params->p.name, 407cb5caa98Sdjl (char *)params->p.default_config, NULL, params); 408cb5caa98Sdjl if (rc != NSCD_SUCCESS) 409cb5caa98Sdjl return (rc); 410cb5caa98Sdjl 411cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 412cb5caa98Sdjl (me, "no base nsw config created for %s (sources: %s)\n", 413cb5caa98Sdjl params->p.name, params->p.default_config); 414cb5caa98Sdjl 415cb5caa98Sdjl ret = _nscd_create_nsw_state(params); 416cb5caa98Sdjl if (ret == NULL) 417cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 418cb5caa98Sdjl rootp->s = (struct nss_db_state *)ret; 419cb5caa98Sdjl return (NSCD_SUCCESS); 420cb5caa98Sdjl } 421cb5caa98Sdjl 422cb5caa98Sdjl /* 423cb5caa98Sdjl * if getting a nsw state for a request from the compat 424cb5caa98Sdjl * backend, create the new switch structures if this 425cb5caa98Sdjl * is the first time around for a passwd, shadow, group, 426cb5caa98Sdjl * audit_user, or user_attr database 427cb5caa98Sdjl */ 428cb5caa98Sdjl if (params->compati != -1) { 429cb5caa98Sdjl 430*cfed26cbSMichen Chang nscd_nsw_config_t **nswcfg1, **nswcfg2; 431cb5caa98Sdjl int i = params->compati; 432cb5caa98Sdjl 433ad0e80f7Smichen dbi = i; 434ad0e80f7Smichen 435*cfed26cbSMichen Chang /* 436*cfed26cbSMichen Chang * retrieve the pointer space which contains a 437*cfed26cbSMichen Chang * pointer pointing to the nsswitch config 438*cfed26cbSMichen Chang * structure for the compat backend 439*cfed26cbSMichen Chang */ 440cb5caa98Sdjl nswcfg = (nscd_nsw_config_t **)_nscd_get( 441cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[i]); 442cb5caa98Sdjl 443cb5caa98Sdjl /* 444*cfed26cbSMichen Chang * If nsswitch config structure not created yet, 445*cfed26cbSMichen Chang * get the config string from the passwd_compat 446*cfed26cbSMichen Chang * or group_compat DB and create the structure. 447cb5caa98Sdjl */ 448*cfed26cbSMichen Chang if (*nswcfg == NULL) { 449*cfed26cbSMichen Chang /* Wait first if it's being created. */ 450*cfed26cbSMichen Chang nswcfg2 = (nscd_nsw_config_t **)_nscd_mutex_lock( 451*cfed26cbSMichen Chang (nscd_acc_data_t *)nscd_nsw_config[i]); 452*cfed26cbSMichen Chang 453*cfed26cbSMichen Chang /* still not created yet */ 454*cfed26cbSMichen Chang if (*nswcfg2 == NULL) { 455*cfed26cbSMichen Chang /* 456*cfed26cbSMichen Chang * get the nsswitch config string specified 457*cfed26cbSMichen Chang * for passwd_compat or group_compat 458*cfed26cbSMichen Chang */ 459cb5caa98Sdjl nswcfg1 = (nscd_nsw_config_t **)_nscd_get( 460*cfed26cbSMichen Chang (nscd_acc_data_t *) 461*cfed26cbSMichen Chang nscd_nsw_config[params->cfgdbi]); 462cb5caa98Sdjl if (nswcfg1 == NULL) { 463cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 464cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 465cb5caa98Sdjl (me, "no nsw config for %s\n", 466cb5caa98Sdjl params->p.name); 467*cfed26cbSMichen Chang 468*cfed26cbSMichen Chang (void) _nscd_mutex_unlock( 469*cfed26cbSMichen Chang (nscd_acc_data_t *)nswcfg2); 470*cfed26cbSMichen Chang _nscd_release((nscd_acc_data_t *) 471*cfed26cbSMichen Chang nswcfg); 472*cfed26cbSMichen Chang 473cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 474cb5caa98Sdjl } 475cb5caa98Sdjl 476ad0e80f7Smichen rc = _nscd_create_sw_struct(i, params->cfgdbi, 477ad0e80f7Smichen params->p.name, (*nswcfg1)->nsw_cfg_str, 478ad0e80f7Smichen NULL, params); 479cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)nswcfg1); 480cb5caa98Sdjl 481*cfed26cbSMichen Chang if (rc == NSCD_SUCCESS) { 482cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 483cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 484cb5caa98Sdjl (me, "nsw config created for %s (%s)\n", 485*cfed26cbSMichen Chang params->p.name, 486*cfed26cbSMichen Chang (*nswcfg1)->nsw_cfg_str); 487*cfed26cbSMichen Chang } else { 488*cfed26cbSMichen Chang (void) _nscd_mutex_unlock( 489*cfed26cbSMichen Chang (nscd_acc_data_t *)nswcfg2); 490*cfed26cbSMichen Chang _nscd_release((nscd_acc_data_t *) 491*cfed26cbSMichen Chang nswcfg); 492*cfed26cbSMichen Chang return (rc); 493*cfed26cbSMichen Chang } 494*cfed26cbSMichen Chang } 495*cfed26cbSMichen Chang (void) _nscd_mutex_unlock((nscd_acc_data_t *)nswcfg2); 496*cfed26cbSMichen Chang } 497cb5caa98Sdjl _nscd_release((nscd_acc_data_t *)nswcfg); 498cb5caa98Sdjl } 499cb5caa98Sdjl 500cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 501cb5caa98Sdjl base = nscd_nsw_state_base[dbi]; 502cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 503cb5caa98Sdjl if (base == NULL) 504cb5caa98Sdjl assert(base != NULL); 505cb5caa98Sdjl 506cb5caa98Sdjl /* 507cb5caa98Sdjl * If list is not empty, return the first one on list. 508cb5caa98Sdjl * Otherwise, create and return a new db state if the 509cb5caa98Sdjl * limit is not reached. if reacehed, wait for the 'one 510cb5caa98Sdjl * is available' signal. 511cb5caa98Sdjl */ 512cb5caa98Sdjl assert(base == (nscd_nsw_state_base_t *)_nscd_mutex_lock( 513cb5caa98Sdjl (nscd_acc_data_t *)base)); 514cb5caa98Sdjl 515cb5caa98Sdjl if (tid == NULL) { 516cb5caa98Sdjl ctrl_p = &base->nsw_state; 517cb5caa98Sdjl } else { 518cb5caa98Sdjl thread_only = 1; 519cb5caa98Sdjl ctrl_p = &base->nsw_state_thr; 520cb5caa98Sdjl 521cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 522cb5caa98Sdjl _nscd_logit(me, "per thread nsw state info: \n"); 523cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", *tid); 524cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 525cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 526cb5caa98Sdjl ctrl_p->free); 527cb5caa98Sdjl _nscd_logit(me, "number of nsw state allocated = %d\n", 528cb5caa98Sdjl ctrl_p->allocated); 529cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 530cb5caa98Sdjl ctrl_p->first); 531cb5caa98Sdjl _nscd_logit(me, "number of waiter = %d\n", 532cb5caa98Sdjl ctrl_p->waiter); 533bf1e3beeSmichen 534cb5caa98Sdjl } 535cb5caa98Sdjl } 536cb5caa98Sdjl 537cb5caa98Sdjl if (ctrl_p->first == NULL && ctrl_p->allocated == ctrl_p->max) 538cb5caa98Sdjl wait_cond = 1; 539cb5caa98Sdjl else if (thread_only && base->used_by_thr && base->tid != *tid) 540cb5caa98Sdjl wait_cond = 1; 541cb5caa98Sdjl 542cb5caa98Sdjl if (wait_cond) { 543cb5caa98Sdjl 544cb5caa98Sdjl ctrl_p->waiter++; 545cb5caa98Sdjl 546cb5caa98Sdjl while (wait_cond) { 547cb5caa98Sdjl if (!thread_only) 548cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 549cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 550cb5caa98Sdjl (me, "waiting for nsw state signal\n"); 551cb5caa98Sdjl else 552cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 553cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 554cb5caa98Sdjl (me, "waiting for per thread " 555cb5caa98Sdjl "nsw state signal\n"); 556cb5caa98Sdjl 557cb5caa98Sdjl if (thread_only) { 558cb5caa98Sdjl _nscd_cond_wait((nscd_acc_data_t *)base, 559cb5caa98Sdjl &base->thr_cond); 560cb5caa98Sdjl 561cb5caa98Sdjl if (base->used_by_thr == 0 && 562cb5caa98Sdjl ctrl_p->first != NULL) 563cb5caa98Sdjl wait_cond = 0; 564cb5caa98Sdjl } else { 565cb5caa98Sdjl _nscd_cond_wait((nscd_acc_data_t *)base, NULL); 566cb5caa98Sdjl 567cb5caa98Sdjl if (ctrl_p->first != NULL) 568cb5caa98Sdjl wait_cond = 0; 569cb5caa98Sdjl } 570cb5caa98Sdjl 571cb5caa98Sdjl if (!thread_only) 572cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 573cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 574cb5caa98Sdjl (me, "woke from cond wait ...wait_cond = %d\n", 575cb5caa98Sdjl wait_cond); 576cb5caa98Sdjl else 577cb5caa98Sdjl 578cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 579cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 580cb5caa98Sdjl (me, "woke from cond wait (per thread) " 581cb5caa98Sdjl "...wait_cond = %d\n", wait_cond); 582cb5caa98Sdjl 583cb5caa98Sdjl } 584cb5caa98Sdjl 585cb5caa98Sdjl ctrl_p->waiter--; 586cb5caa98Sdjl } 587cb5caa98Sdjl 588cb5caa98Sdjl if (ctrl_p->first == NULL) { 589cb5caa98Sdjl int geti; 590cb5caa98Sdjl 591cb5caa98Sdjl /* 592cb5caa98Sdjl * for lookup calls from the compat backend 593cb5caa98Sdjl * uses the switch policy for passwd_compat 594cb5caa98Sdjl * or group_compat 595cb5caa98Sdjl */ 596cb5caa98Sdjl if (params->compati != -1) 597cb5caa98Sdjl geti = params->compati; 598cb5caa98Sdjl else 599cb5caa98Sdjl geti = params->dbi; 600cb5caa98Sdjl 601cb5caa98Sdjl params->nswcfg = (nscd_nsw_config_t **)_nscd_get( 602cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_config[geti]); 603cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 604cb5caa98Sdjl (me, "got a nsw config %p for index %d\n", 605cb5caa98Sdjl params->nswcfg, geti); 606cb5caa98Sdjl 607cb5caa98Sdjl ctrl_p->first = _nscd_create_nsw_state(params); 608cb5caa98Sdjl if (ctrl_p->first != NULL) { 609cb5caa98Sdjl if (tid == NULL) { 610cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 611cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 612cb5caa98Sdjl (me, "got a new nsw_state %p\n", ctrl_p->first); 613cb5caa98Sdjl } else { 614cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, 615cb5caa98Sdjl NSCD_LOG_LEVEL_DEBUG) 616cb5caa98Sdjl (me, "got a new per thread nsw_state %p\n", 617cb5caa98Sdjl ctrl_p->first); 618cb5caa98Sdjl } 619cb5caa98Sdjl ctrl_p->allocated++; 620cb5caa98Sdjl ctrl_p->free++; 621cb5caa98Sdjl } else { 622cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_ERROR) 623cb5caa98Sdjl (me, "error: unable to obtain a nsw state\n"); 624cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 625cb5caa98Sdjl return (NSCD_CREATE_NSW_STATE_FAILED); 626cb5caa98Sdjl } 627cb5caa98Sdjl } 628cb5caa98Sdjl 629cb5caa98Sdjl ret = ctrl_p->first; 630bf1e3beeSmichen if (ret->recheck_be == nscd_true) 631bf1e3beeSmichen check_be_array(ret); 632cb5caa98Sdjl ctrl_p->first = ret->next; 633cb5caa98Sdjl ret->next = NULL; 634cb5caa98Sdjl ctrl_p->free--; 635cb5caa98Sdjl if (thread_only) { 636cb5caa98Sdjl base->tid = *tid; 637cb5caa98Sdjl base->used_by_thr = 1; 638cb5caa98Sdjl 639cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 640cb5caa98Sdjl _nscd_logit(me, "\t\t\tgot a per thread nsw " 641cb5caa98Sdjl "state %p: \n", ret); 642cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", *tid); 643cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 644cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 645cb5caa98Sdjl ctrl_p->free); 646cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 647cb5caa98Sdjl ctrl_p->allocated); 648cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 649cb5caa98Sdjl ctrl_p->first); 650cb5caa98Sdjl _nscd_logit(me, "number of waiter = %d\n", 651cb5caa98Sdjl ctrl_p->waiter); 652cb5caa98Sdjl } 653cb5caa98Sdjl } 654cb5caa98Sdjl else 655cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 656cb5caa98Sdjl (me, "got old nsw state %p\n", ret); 657cb5caa98Sdjl 658*cfed26cbSMichen Chang /* 659*cfed26cbSMichen Chang * reference count the nsswitch state base bfore handing out 660*cfed26cbSMichen Chang * the nsswitch state 661*cfed26cbSMichen Chang */ 662*cfed26cbSMichen Chang ret->base = (nscd_nsw_state_base_t *) 663*cfed26cbSMichen Chang _nscd_get((nscd_acc_data_t *)base); 664*cfed26cbSMichen Chang 665cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 666cb5caa98Sdjl 667cb5caa98Sdjl rootp->s = (struct nss_db_state *)ret; 668cb5caa98Sdjl 669cb5caa98Sdjl return (NSCD_SUCCESS); 670cb5caa98Sdjl } 671cb5caa98Sdjl 672cb5caa98Sdjl nscd_rc_t 673cb5caa98Sdjl _nscd_get_nsw_state( 674cb5caa98Sdjl nss_db_root_t *rootp, 675cb5caa98Sdjl nscd_nsw_params_t *params) 676cb5caa98Sdjl { 677cb5caa98Sdjl return (_get_nsw_state_int(rootp, params, NULL)); 678cb5caa98Sdjl } 679cb5caa98Sdjl 680cb5caa98Sdjl nscd_rc_t 681cb5caa98Sdjl _nscd_get_nsw_state_thread( 682cb5caa98Sdjl nss_db_root_t *rootp, 683cb5caa98Sdjl nscd_nsw_params_t *params) 684cb5caa98Sdjl { 685cb5caa98Sdjl thread_t tid = thr_self(); 686cb5caa98Sdjl return (_get_nsw_state_int(rootp, params, &tid)); 687cb5caa98Sdjl } 688cb5caa98Sdjl 689cb5caa98Sdjl 690cb5caa98Sdjl static void 691cb5caa98Sdjl _put_nsw_state_int( 692cb5caa98Sdjl nscd_nsw_state_t *s, 693cb5caa98Sdjl thread_t *tid) 694cb5caa98Sdjl { 695cb5caa98Sdjl 696cb5caa98Sdjl nscd_nsw_state_base_t *base; 697cb5caa98Sdjl nscd_state_ctrl_t *ctrl_p; 698cb5caa98Sdjl int thread_only = 0; 699cb5caa98Sdjl char *me = "_put_nsw_state_int"; 700cb5caa98Sdjl 701cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 702cb5caa98Sdjl (me, "put back a nsw state\n"); 703cb5caa98Sdjl 704cb5caa98Sdjl if (s == NULL) { 705cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 706cb5caa98Sdjl (me, "nsw state is NULL, nothing to put back\n"); 707cb5caa98Sdjl return; 708cb5caa98Sdjl } 709cb5caa98Sdjl 710cb5caa98Sdjl /* 711cb5caa98Sdjl * no need to put back if the nsw state is not on any base 712cb5caa98Sdjl * but need to free the resources used 713cb5caa98Sdjl */ 714cb5caa98Sdjl if ((*s->nsw_cfg_p)->nobase == 1) { 715cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 716cb5caa98Sdjl (me, "no base nsw state, freeing resources ...\n"); 717cb5caa98Sdjl 718cb5caa98Sdjl _nscd_free_nsw_state(s); 719cb5caa98Sdjl return; 720cb5caa98Sdjl } 721cb5caa98Sdjl 722cb5caa98Sdjl if (tid != NULL) 723cb5caa98Sdjl thread_only = 1; 724cb5caa98Sdjl 725cb5caa98Sdjl base = s->base; 726cb5caa98Sdjl 727cb5caa98Sdjl if (_nscd_mutex_lock((nscd_acc_data_t *)base) == NULL) { 728*cfed26cbSMichen Chang /* base has been freed or no longer valid, free the nsw state */ 729cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 730*cfed26cbSMichen Chang (me, "nsw state base gone or no longer valid, freeing %p\n", s); 731cb5caa98Sdjl _nscd_free_nsw_state(s); 732cb5caa98Sdjl return; 733cb5caa98Sdjl } 734cb5caa98Sdjl 735cb5caa98Sdjl if (thread_only) 736cb5caa98Sdjl ctrl_p = &base->nsw_state_thr; 737cb5caa98Sdjl else 738cb5caa98Sdjl ctrl_p = &base->nsw_state; 739cb5caa98Sdjl 740cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 741cb5caa98Sdjl _nscd_logit(me, "before returning the nsw state: \n"); 742cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", (tid == NULL) ? -1 : *tid); 743cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 744cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 745cb5caa98Sdjl ctrl_p->free); 746cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 747cb5caa98Sdjl ctrl_p->allocated); 748cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 749cb5caa98Sdjl ctrl_p->first); 750bf1e3beeSmichen _nscd_logit(me, "number of waiter = %d\n", ctrl_p->waiter); 751cb5caa98Sdjl } 752cb5caa98Sdjl 753cb5caa98Sdjl if (ctrl_p->first != NULL) { 754cb5caa98Sdjl s->next = ctrl_p->first; 755cb5caa98Sdjl ctrl_p->first = s; 756cb5caa98Sdjl } else { 757cb5caa98Sdjl ctrl_p->first = s; 758cb5caa98Sdjl s->next = NULL; 759cb5caa98Sdjl } 760cb5caa98Sdjl ctrl_p->free++; 761cb5caa98Sdjl 762*cfed26cbSMichen Chang /* 763*cfed26cbSMichen Chang * Remove reference to the nsswitch state base. 764*cfed26cbSMichen Chang */ 765*cfed26cbSMichen Chang _nscd_release((nscd_acc_data_t *)base); 766*cfed26cbSMichen Chang s->base = NULL; 767*cfed26cbSMichen Chang 768cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 769cb5caa98Sdjl (me, "signaling waiter thread_only = %d..\n", thread_only); 770cb5caa98Sdjl 771cb5caa98Sdjl if (thread_only && ctrl_p->free == ctrl_p->allocated) { 772cb5caa98Sdjl assert(ctrl_p->first != NULL); 773cb5caa98Sdjl base->used_by_thr = 0; 774cb5caa98Sdjl if (ctrl_p->waiter > 0) { 775cb5caa98Sdjl (void) cond_signal(&base->thr_cond); 776cb5caa98Sdjl } 777cb5caa98Sdjl } 778cb5caa98Sdjl 779cb5caa98Sdjl if (!thread_only && ctrl_p->waiter > 0) { 780cb5caa98Sdjl 781cb5caa98Sdjl _nscd_cond_signal((nscd_acc_data_t *)base); 782cb5caa98Sdjl } 783cb5caa98Sdjl 784cb5caa98Sdjl _NSCD_LOG_IF(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) { 785cb5caa98Sdjl _nscd_logit(me, "after the nsw state is returned: \n"); 786cb5caa98Sdjl _nscd_logit(me, "tid = %d\n", (tid == NULL) ? -1 : *tid); 787cb5caa98Sdjl _nscd_logit(me, "tid in base = %d\n", base->tid); 788cb5caa98Sdjl _nscd_logit(me, "number of free nsw_state = %d\n", 789cb5caa98Sdjl ctrl_p->free); 790cb5caa98Sdjl _nscd_logit(me, "number od nsw state allocated = %d\n", 791cb5caa98Sdjl ctrl_p->allocated); 792cb5caa98Sdjl _nscd_logit(me, "first nsw state on list = %p\n", 793cb5caa98Sdjl ctrl_p->first); 794bf1e3beeSmichen _nscd_logit(me, "tnumber of waiter = %d\n", ctrl_p->waiter); 795cb5caa98Sdjl } 796cb5caa98Sdjl 797cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE, NSCD_LOG_LEVEL_DEBUG) 798cb5caa98Sdjl (me, "done putting back nsw state %p, thread_only = %d\n", 799cb5caa98Sdjl s, thread_only); 800cb5caa98Sdjl 801cb5caa98Sdjl _nscd_mutex_unlock((nscd_acc_data_t *)base); 802cb5caa98Sdjl 803cb5caa98Sdjl } 804cb5caa98Sdjl 805cb5caa98Sdjl void 806cb5caa98Sdjl _nscd_put_nsw_state( 807cb5caa98Sdjl nscd_nsw_state_t *s) 808cb5caa98Sdjl { 809cb5caa98Sdjl _put_nsw_state_int(s, NULL); 810cb5caa98Sdjl } 811cb5caa98Sdjl 812cb5caa98Sdjl void 813cb5caa98Sdjl _nscd_put_nsw_state_thread( 814cb5caa98Sdjl nscd_nsw_state_t *s) 815cb5caa98Sdjl { 816cb5caa98Sdjl thread_t tid = thr_self(); 817cb5caa98Sdjl _put_nsw_state_int(s, &tid); 818cb5caa98Sdjl } 819cb5caa98Sdjl 820cb5caa98Sdjl nscd_rc_t 821cb5caa98Sdjl _nscd_init_nsw_state_base( 822cb5caa98Sdjl int dbi, 823ad0e80f7Smichen int compat_basei, 824cb5caa98Sdjl int lock) 825cb5caa98Sdjl { 826ad0e80f7Smichen int cfgdbi; 827cb5caa98Sdjl nscd_nsw_state_base_t *base = NULL; 828cb5caa98Sdjl char *me = "_nscd_init_nsw_state_base"; 829cb5caa98Sdjl 830cb5caa98Sdjl if (lock) 831cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 832cb5caa98Sdjl 833cb5caa98Sdjl base = (nscd_nsw_state_base_t *)_nscd_alloc( 834cb5caa98Sdjl NSCD_DATA_NSW_STATE_BASE, 835cb5caa98Sdjl sizeof (nscd_nsw_state_base_t), 836cb5caa98Sdjl _nscd_free_nsw_state_base, 837cb5caa98Sdjl NSCD_ALLOC_MUTEX | NSCD_ALLOC_COND); 838cb5caa98Sdjl 839cb5caa98Sdjl if (base == NULL) { 840cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 841cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 842cb5caa98Sdjl (me, "not able to allocate a nsw state base\n"); 843cb5caa98Sdjl if (lock) 844cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 845cb5caa98Sdjl return (NSCD_NO_MEMORY); 846cb5caa98Sdjl } 847bf1e3beeSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 848cb5caa98Sdjl (me, "nsw state base %p allocated\n", base); 849cb5caa98Sdjl 850cb5caa98Sdjl /* 851cb5caa98Sdjl * initialize and activate the new nss_nsw_state base 852cb5caa98Sdjl */ 853cb5caa98Sdjl base->dbi = dbi; 854ad0e80f7Smichen if (compat_basei != -1) 855ad0e80f7Smichen cfgdbi = compat_basei; 856ad0e80f7Smichen else 857ad0e80f7Smichen cfgdbi = dbi; 858ad0e80f7Smichen 859ad0e80f7Smichen base->nsw_state.max = NSCD_SW_CFG(cfgdbi).max_nsw_state_per_db; 860ad0e80f7Smichen base->nsw_state_thr.max = NSCD_SW_CFG(cfgdbi).max_nsw_state_per_thread; 861cb5caa98Sdjl 862cb5caa98Sdjl nscd_nsw_state_base[dbi] = (nscd_nsw_state_base_t *)_nscd_set( 863cb5caa98Sdjl (nscd_acc_data_t *)nscd_nsw_state_base[dbi], 864cb5caa98Sdjl (nscd_acc_data_t *)base); 865cb5caa98Sdjl 866cb5caa98Sdjl if (lock) 867cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 868cb5caa98Sdjl 869cb5caa98Sdjl return (NSCD_SUCCESS); 870cb5caa98Sdjl } 871cb5caa98Sdjl 872cb5caa98Sdjl nscd_rc_t 873cb5caa98Sdjl _nscd_init_all_nsw_state_base() 874cb5caa98Sdjl { 875cb5caa98Sdjl int i; 876cb5caa98Sdjl nscd_rc_t rc; 877cb5caa98Sdjl char *me = "_nscd_init_all_nsw_state_base"; 878cb5caa98Sdjl 879cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 880cb5caa98Sdjl 881cb5caa98Sdjl for (i = 0; i < NSCD_NUM_DB; i++) { 882cb5caa98Sdjl 883ad0e80f7Smichen rc = _nscd_init_nsw_state_base(i, -1, 0); 884cb5caa98Sdjl 885cb5caa98Sdjl if (rc != NSCD_SUCCESS) { 886cb5caa98Sdjl _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, 887cb5caa98Sdjl NSCD_LOG_LEVEL_ERROR) 888cb5caa98Sdjl (me, "not able to initialize a nsw db state " 889cb5caa98Sdjl "base (%d)\n", i); 890cb5caa98Sdjl 891cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 892cb5caa98Sdjl return (rc); 893cb5caa98Sdjl } 894cb5caa98Sdjl } 895bf1e3beeSmichen _NSCD_LOG(NSCD_LOG_NSW_STATE | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG) 896cb5caa98Sdjl (me, "all nsw state base initialized\n"); 897cb5caa98Sdjl 898cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 899cb5caa98Sdjl 900cb5caa98Sdjl return (NSCD_SUCCESS); 901cb5caa98Sdjl } 902cb5caa98Sdjl 903cb5caa98Sdjl nscd_rc_t 904cb5caa98Sdjl _nscd_alloc_nsw_state_base() 905cb5caa98Sdjl { 906cb5caa98Sdjl 907cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 908cb5caa98Sdjl 909cb5caa98Sdjl nscd_nsw_state_base = calloc(NSCD_NUM_DB, 910cb5caa98Sdjl sizeof (nscd_nsw_state_base_t *)); 911cb5caa98Sdjl if (nscd_nsw_state_base == NULL) { 912cb5caa98Sdjl (void) rw_unlock(&nscd_nsw_state_base_lock); 913cb5caa98Sdjl return (NSCD_NO_MEMORY); 914cb5caa98Sdjl } 915cb5caa98Sdjl 916cb5caa98Sdjl (void) rw_rdlock(&nscd_nsw_state_base_lock); 917cb5caa98Sdjl 918cb5caa98Sdjl return (NSCD_SUCCESS); 919cb5caa98Sdjl } 920