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 34extern "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 */ 110typedef 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 120typedef 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 127typedef 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 137typedef 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 */ 145typedef 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} 184typedef 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} 196typedef 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} 224typedef 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 237typedef 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 277typedef 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 298typedef 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 */ 308extern void passwd_init_ctx(nsc_ctx_t *); 309extern void group_init_ctx(nsc_ctx_t *); 310extern void host_init_ctx(nsc_ctx_t *); 311extern void ipnode_init_ctx(nsc_ctx_t *); 312extern void exec_init_ctx(nsc_ctx_t *); 313extern void prof_init_ctx(nsc_ctx_t *); 314extern void user_init_ctx(nsc_ctx_t *); 315extern void ether_init_ctx(nsc_ctx_t *); 316extern void rpc_init_ctx(nsc_ctx_t *); 317extern void proto_init_ctx(nsc_ctx_t *); 318extern void net_init_ctx(nsc_ctx_t *); 319extern void bootp_init_ctx(nsc_ctx_t *); 320extern void auth_init_ctx(nsc_ctx_t *); 321extern void serv_init_ctx(nsc_ctx_t *); 322extern void netmask_init_ctx(nsc_ctx_t *); 323extern void printer_init_ctx(nsc_ctx_t *); 324extern void project_init_ctx(nsc_ctx_t *); 325extern void tnrhtp_init_ctx(nsc_ctx_t *); 326extern void tnrhdb_init_ctx(nsc_ctx_t *); 327 328/* Functions used to throttle threads */ 329extern int nscd_wait(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *); 330extern int nscd_signal(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *); 331 332/* Cache creation and initialization */ 333extern nscd_rc_t init_cache(); 334extern 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 */ 341extern void nsc_lookup(nsc_lookup_args_t *, int); 342 343/* Cache backend info */ 344extern void nsc_info(nsc_ctx_t *, char *, nscd_cfg_cache_t cfg[], 345 nscd_cfg_stat_cache_t stats[]); 346#ifdef NSCD_DEBUG 347extern int nsc_dump(char *, int); 348#endif /* NSCD_DEBUG */ 349 350/* Cache invalidate */ 351extern void nsc_invalidate(nsc_ctx_t *, char *, nsc_ctx_t **); 352 353/* Keep hot functions */ 354extern nsc_keephot_t *maken(int); 355extern void *insertn(nsc_keephot_t *, uint_t, void *); 356 357/* hash related routines */ 358extern uint_t cis_gethash(const char *, int); 359extern uint_t ces_gethash(const char *, int); 360extern uint_t db_gethash(const void *, int, int); 361 362extern void leave(int n); 363extern int get_cache_idx(char *); 364 365#ifdef __cplusplus 366} 367#endif 368 369#endif /* _NSCD_H */ 370