1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _NSCD_H 27 #define _NSCD_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * This is a private header file. Applications should not directly include 33 * this file. 34 */ 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #include <sys/avl.h> 41 #include <thread.h> 42 #include <synch.h> 43 #include <nss_dbdefs.h> 44 #include "getxby_door.h" 45 #include "nscd_common.h" 46 #include "nscd_config.h" 47 48 /* 49 * OR'D in by server to call self for updates 50 */ 51 #define UPDATEBIT (1<<30) 52 #define MASKUPDATEBIT(a) ((~UPDATEBIT)&(a)) 53 54 /* 55 * debug levels 56 */ 57 #define DBG_OFF 0 58 #define DBG_CANT_FIND 2 59 #define DBG_NETLOOKUPS 4 60 #define DBG_ALL 6 61 62 /* 63 * Max size name we allow to be passed to avoid 64 * buffer overflow problems 65 */ 66 #define NSCDMAXNAMELEN 255 67 68 /* 69 * cached entry status 70 */ 71 #define ST_UPDATE_PENDING 0x1 72 #define ST_LOOKUP_PENDING 0x2 73 #define ST_PENDING (ST_LOOKUP_PENDING | ST_UPDATE_PENDING) 74 #define ST_NEW_ENTRY 0x4 75 #define ST_DISCARD 0x8 76 77 /* 78 * Cache eviction start and stop levels 79 */ 80 #define _NSC_EVICTION_START_LEVEL 90 81 #define _NSC_EVICTION_SAFE_LEVEL 80 82 83 /* 84 * other internal constants 85 */ 86 #define _NSC_MAX_DB 2 87 #define _NSC_PUBLIC_ACCESS -1 88 #define _NSC_FILE_CHECK_TIME 0 /* check always for backwards compat */ 89 90 /* 91 * Macros used for logging purposes 92 */ 93 #define yes_no(flag) (flag == nscd_true)?"yes":"no" 94 #define check_null(str) (str)?str:"<null>" 95 96 /* 97 * Macros used by compare routines 98 */ 99 #define _NSC_INT_KEY_CMP(n1, n2) \ 100 (n1 > n2)?1:((n1 == n2)?0:-1) 101 102 #define _NSC_GET_HITRATE(sp) \ 103 sp->hitrate = sp->pos_misses + sp->neg_misses + \ 104 sp->pos_hits + sp->neg_hits; \ 105 if (sp->hitrate > 0.0) \ 106 sp->hitrate = (100.0 * \ 107 ((double)sp->pos_hits + \ 108 (double)sp->neg_hits)) / sp->hitrate; 109 110 /* 111 * nsc_lookup action 112 */ 113 typedef enum { 114 _NSC_NSLOOKUP = 0, 115 _NSC_WAIT, 116 _NSC_USECACHED 117 } nsc_action_t; 118 119 /* 120 * Structure to handle waiting for pending name service requests 121 */ 122 typedef struct waiter { 123 cond_t w_waitcv; 124 uint8_t *w_key; 125 struct waiter *w_next, *w_prev; 126 } waiter_t; 127 128 /* 129 * What each entry in the nameserver cache looks like. 130 */ 131 132 typedef struct nsc_entry_stat { 133 uint_t hits; /* number of hits */ 134 uint8_t status; /* activity status */ 135 time_t timestamp; /* expiry time */ 136 int refcount; /* reference count */ 137 } nsc_entry_stat_t; 138 139 typedef struct nsc_entry { 140 avl_node_t avl_link; /* libavl requirement */ 141 struct nsc_entry *qnext; /* next on pqueue */ 142 struct nsc_entry *qprev; /* prev on pqueue */ 143 nsc_entry_stat_t stats; /* entry's statistics */ 144 nss_XbyY_key_t key; /* entry's key */ 145 void *buffer; /* data buffer */ 146 size_t bufsize; /* data buffer length */ 147 } nsc_entry_t; 148 149 typedef struct nsc_keephot { 150 void *ptr; 151 uint_t num; 152 } nsc_keephot_t; 153 154 /* 155 * Macros used by hash table 156 * 157 * _NSC_HTSIZE_PRIMES are prime numbers that are used as hash table 158 * sizes when hash table type is nsc_ht_prime. For hash tables of 159 * type nsc_ht_power2, the size is automatically calculated. 160 * Number of primes listed below is _NSC_HTSIZE_NUM_SLOTS + 1. 161 * Each number (except the first) is a prime closest to a 162 * power of 2 in increasing order. Ex: 509 is the closest prime to 163 * 512 (2**9), 1021 is closest to 1024 (2**10), and so on. 164 * The first prime is chosen as 211 for historical reasons. 165 */ 166 #define _NSC_INIT_HTSIZE_PRIME 211 167 #define _NSC_INIT_HTSIZE_POWER2 256 168 #define _NSC_INIT_HTSIZE_SLOT_VALUE 2896 169 #define _NSC_HTSIZE_NUM_SLOTS 10 170 #define _NSC_HTSIZE_PRIMES 211, 509, 1021, 2053, 4099, 8191, \ 171 16381, 32771, 65537, 131071, 262147 172 173 #define _NSC_DB_CES_KEY(ptr) \ 174 ((ptr)->db_type == nsc_key_ces) 175 #define _NSC_DB_CIS_KEY(ptr) \ 176 ((ptr)->db_type == nsc_key_cis) 177 #define _NSC_DB_STR_KEY(ptr) \ 178 _NSC_DB_CES_KEY(ptr) || _NSC_DB_CIS_KEY(ptr) 179 #define _NSC_DB_INT_KEY(ptr) \ 180 ((ptr)->db_type == nsc_key_int) 181 182 /* 183 * cache backend param group (global) 184 */ 185 #define NSCD_CFG_GROUP_INFO_GLOBAL_CACHE {1, 0x0001} 186 typedef struct nscd_cfg_global_cache { 187 nscd_cfg_group_info_t gi; /* config requirement */ 188 nscd_bool_t enable; 189 } nscd_cfg_global_cache_t; 190 191 #define NSCD_CFG_GLOBAL_CACHE_DEFAULTS \ 192 { NSCD_CFG_GROUP_INFO_GLOBAL_CACHE, nscd_true } 193 194 /* 195 * cache backend param group (per database) 196 */ 197 #define NSCD_CFG_GROUP_INFO_CACHE {12, 0x0fff} 198 typedef struct nscd_cfg_cache { 199 nscd_cfg_group_info_t gi; /* config requirement */ 200 nscd_bool_t enable; /* if false return NOSERVER */ 201 nscd_bool_t per_user; /* if true per user access */ 202 nscd_bool_t avoid_ns; /* if true avoid name service */ 203 nscd_bool_t check_files; /* if true check file */ 204 int check_interval; /* check interval */ 205 int pos_ttl; /* time to live for +ve entries */ 206 int neg_ttl; /* time to live for -ve entries */ 207 int keephot; /* keep hot count */ 208 int hint_size; /* size to return for a GETHINTS */ 209 ulong_t maxentries; /* maximum entries allowed */ 210 int suggestedsize; /* obsolete */ 211 nscd_bool_t old_data_ok; /* obsolete */ 212 } nscd_cfg_cache_t; 213 214 #define NSCD_CFG_CACHE_DEFAULTS \ 215 { \ 216 NSCD_CFG_GROUP_INFO_CACHE, \ 217 nscd_true, nscd_false, nscd_false, nscd_true, \ 218 _NSC_FILE_CHECK_TIME, 600, 10, 0, 1 << 11, 0, \ 219 0, nscd_false \ 220 } 221 222 /* 223 * cache backend stat group (per database) 224 */ 225 #define NSCD_CFG_STAT_GROUP_INFO_CACHE {9, 0x01ff} 226 typedef struct nscd_cfg_stat_cache { 227 nscd_cfg_group_info_t gi; /* config requirement */ 228 ulong_t pos_hits; /* hits on +ve entries */ 229 ulong_t neg_hits; /* hits on -ve entries */ 230 ulong_t pos_misses; /* misses on +ve entries */ 231 ulong_t neg_misses; /* misses on -ve entries */ 232 ulong_t entries; /* count of cache entries */ 233 ulong_t drop_count; /* cache queries dropped */ 234 ulong_t wait_count; /* cache queries queued */ 235 ulong_t invalidate_count; /* count for cache invalidation */ 236 double hitrate; /* computed from other fields */ 237 } nscd_cfg_stat_cache_t; 238 239 typedef struct nsc_db { 240 /* 241 * Data 242 */ 243 avl_tree_t tree; 244 nsc_entry_t **htable; 245 nsc_entry_t *qhead; 246 nsc_entry_t *qtail; 247 nsc_entry_t *reap_node; 248 int callnumber; 249 int dbop; 250 char *name; 251 mutex_t db_mutex; 252 int htsize; 253 enum hash_type { 254 nsc_ht_default = 0, 255 nsc_ht_prime = 1, 256 nsc_ht_power2 = 2 257 } hash_type; 258 enum db_type { 259 nsc_key_ces = 0, 260 nsc_key_cis = 1, 261 nsc_key_int = 2, 262 nsc_key_other = 3 263 } db_type; 264 /* 265 * Methods 266 */ 267 uint_t (*gethash)(nss_XbyY_key_t *, int); 268 int (*compar)(const void *, const void *); 269 void (*getlogstr)(char *, char *, size_t, nss_XbyY_args_t *); 270 /* 271 * Config 272 */ 273 nscd_cfg_cache_t cfg; 274 time_t cfg_mtime; 275 } nsc_db_t; 276 277 278 typedef struct nsc_ctx { 279 char *dbname; /* cache name */ 280 nscd_cfg_stat_cache_t stats; /* statistics */ 281 nscd_cfg_cache_t cfg; /* configs */ 282 time_t cfg_mtime; /* config last modified time */ 283 rwlock_t cfg_rwlp; /* config rwlock */ 284 mutex_t stats_mutex; /* stats mutex */ 285 mutex_t file_mutex; /* file mutex */ 286 time_t file_mtime; /* file last modified time */ 287 time_t file_chktime; /* file last checked time */ 288 off_t file_size; /* file size at last check */ 289 ino_t file_ino; /* file inode at last check */ 290 const char *file_name; /* filename for check_files */ 291 int db_count; /* number of caches */ 292 nsc_db_t *nsc_db[_NSC_MAX_DB]; /* caches */ 293 waiter_t wait; /* lookup wait CV */ 294 sema_t throttle_sema; /* throttle lookups */ 295 sema_t revalidate_sema; /* revalidation threads */ 296 nscd_bool_t revalidate_on; /* reval. thread started */ 297 nscd_bool_t reaper_on; /* reaper thread started */ 298 } nsc_ctx_t; 299 300 typedef struct nsc_lookup_args { 301 nsc_ctx_t *ctx; 302 nsc_db_t *nscdb; 303 void *buffer; 304 size_t bufsize; 305 } nsc_lookup_args_t; 306 307 #define CACHE_CTX_COUNT 20 308 309 /* Context initialization */ 310 extern void passwd_init_ctx(nsc_ctx_t *); 311 extern void group_init_ctx(nsc_ctx_t *); 312 extern void host_init_ctx(nsc_ctx_t *); 313 extern void ipnode_init_ctx(nsc_ctx_t *); 314 extern void exec_init_ctx(nsc_ctx_t *); 315 extern void prof_init_ctx(nsc_ctx_t *); 316 extern void user_init_ctx(nsc_ctx_t *); 317 extern void ether_init_ctx(nsc_ctx_t *); 318 extern void rpc_init_ctx(nsc_ctx_t *); 319 extern void proto_init_ctx(nsc_ctx_t *); 320 extern void net_init_ctx(nsc_ctx_t *); 321 extern void bootp_init_ctx(nsc_ctx_t *); 322 extern void auuser_init_ctx(nsc_ctx_t *); 323 extern void auth_init_ctx(nsc_ctx_t *); 324 extern void serv_init_ctx(nsc_ctx_t *); 325 extern void netmask_init_ctx(nsc_ctx_t *); 326 extern void printer_init_ctx(nsc_ctx_t *); 327 extern void project_init_ctx(nsc_ctx_t *); 328 extern void tnrhtp_init_ctx(nsc_ctx_t *); 329 extern void tnrhdb_init_ctx(nsc_ctx_t *); 330 331 /* Functions used to throttle threads */ 332 extern int nscd_wait(waiter_t *, mutex_t *, uint8_t *); 333 extern int nscd_signal(waiter_t *, uint8_t *); 334 335 /* Cache creation and initialization */ 336 extern nscd_rc_t init_cache(); 337 extern nsc_db_t *make_cache(enum db_type, int, char *, 338 int (*compar) (const void *, const void *), 339 void (*getlogstr)(char *, char *, size_t, nss_XbyY_args_t *), 340 uint_t (*gethash)(nss_XbyY_key_t *, int), 341 enum hash_type, int); 342 343 /* Cache backend lookup */ 344 extern void nsc_lookup(nsc_lookup_args_t *, int); 345 346 /* Cache backend info */ 347 extern void nsc_info(nsc_ctx_t *, char *, nscd_cfg_cache_t cfg[], 348 nscd_cfg_stat_cache_t stats[]); 349 #ifdef NSCD_DEBUG 350 extern int nsc_dump(char *, int); 351 #endif /* NSCD_DEBUG */ 352 353 /* Cache invalidate */ 354 extern void nsc_invalidate(nsc_ctx_t *, char *, nsc_ctx_t **); 355 356 /* Keep hot functions */ 357 extern nsc_keephot_t *maken(int); 358 extern void *insertn(nsc_keephot_t *, uint_t, void *); 359 360 /* hash related routines */ 361 extern uint_t cis_gethash(const char *, int); 362 extern uint_t ces_gethash(const char *, int); 363 extern uint_t db_gethash(const void *, int, int); 364 365 extern void leave(int n); 366 extern int get_cache_idx(char *); 367 368 #ifdef __cplusplus 369 } 370 #endif 371 372 #endif /* _NSCD_H */ 373