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