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.
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.
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]
22 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
29 * This is a private header file. Applications should not directly include
40 #include <nss_dbdefs.h>
41 #include "getxby_door.h"
42 #include "nscd_common.h"
43 #include "nscd_config.h"
46 * OR'D in by server to call self for updates
48 #define UPDATEBIT (1<<30)
49 #define MASKUPDATEBIT(a) ((~UPDATEBIT)&(a))
55 #define DBG_CANT_FIND 2
56 #define DBG_NETLOOKUPS 4
60 * Max size name we allow to be passed to avoid
61 * buffer overflow problems
63 #define NSCDMAXNAMELEN 255
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
75 * Cache eviction start and stop levels
77 #define _NSC_EVICTION_START_LEVEL 90
78 #define _NSC_EVICTION_SAFE_LEVEL 80
81 * other internal constants
84 #define _NSC_PUBLIC_ACCESS -1
85 #define _NSC_FILE_CHECK_TIME 0 /* check always for backwards compat */
88 * Macros used for logging purposes
90 #define yes_no(flag) (flag == nscd_true)?"yes":"no"
91 #define check_null(str) (str)?str:"<null>"
94 * Macros used by compare routines
96 #define _NSC_INT_KEY_CMP(n1, n2) \
97 (n1 > n2)?1:((n1 == n2)?0:-1)
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;
117 * What each entry in the nameserver cache looks like.
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 */
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 */
137 typedef struct nsc_keephot
{
143 * Structure to handle waiting for pending name service requests
145 typedef struct waiter
{
149 struct waiter
*w_next
, *w_prev
;
153 * Macros used by hash table
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.
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
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)
181 * cache backend param group (global)
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 */
187 } nscd_cfg_global_cache_t
;
189 #define NSCD_CFG_GLOBAL_CACHE_DEFAULTS \
190 { NSCD_CFG_GROUP_INFO_GLOBAL_CACHE, nscd_true }
193 * cache backend param group (per database)
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 */
212 #define NSCD_CFG_CACHE_DEFAULTS \
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, \
221 * cache backend stat group (per database)
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
;
237 typedef struct nsc_db
{
242 nsc_entry_t
**htable
;
245 nsc_entry_t
*reap_node
;
250 waiter_t db_wait
; /* lookup wait CV */
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
*);
272 nscd_cfg_cache_t cfg
;
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 */
298 typedef struct nsc_lookup_args
{
305 #define CACHE_CTX_COUNT 19
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
*);
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
*);
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);
340 /* Cache backend lookup */
341 extern void nsc_lookup(nsc_lookup_args_t
*, int);
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
[]);
347 extern int nsc_dump(char *, int);
348 #endif /* NSCD_DEBUG */
350 /* Cache invalidate */
351 extern void nsc_invalidate(nsc_ctx_t
*, char *, nsc_ctx_t
**);
353 /* Keep hot functions */
354 extern nsc_keephot_t
*maken(int);
355 extern void *insertn(nsc_keephot_t
*, uint_t
, void *);
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);
362 extern void leave(int n
);
363 extern int get_cache_idx(char *);