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