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