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