#ifndef _NSCD_H
#define _NSCD_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/avl.h>
#include <thread.h>
#include <synch.h>
#include <nss_dbdefs.h>
#include "getxby_door.h"
#include "nscd_common.h"
#include "nscd_config.h"
#define UPDATEBIT (1<<30)
#define MASKUPDATEBIT(a) ((~UPDATEBIT)&(a))
#define DBG_OFF 0
#define DBG_CANT_FIND 2
#define DBG_NETLOOKUPS 4
#define DBG_ALL 6
#define NSCDMAXNAMELEN 255
#define ST_UPDATE_PENDING 0x1
#define ST_LOOKUP_PENDING 0x2
#define ST_PENDING (ST_LOOKUP_PENDING | ST_UPDATE_PENDING)
#define ST_NEW_ENTRY 0x4
#define ST_DISCARD 0x8
#define _NSC_EVICTION_START_LEVEL 90
#define _NSC_EVICTION_SAFE_LEVEL 80
#define _NSC_MAX_DB 3
#define _NSC_PUBLIC_ACCESS -1
#define _NSC_FILE_CHECK_TIME 0
#define yes_no(flag) (flag == nscd_true)?"yes":"no"
#define check_null(str) (str)?str:"<null>"
#define _NSC_INT_KEY_CMP(n1, n2) \
(n1 > n2)?1:((n1 == n2)?0:-1)
#define _NSC_GET_HITRATE(sp) \
sp->hitrate = sp->pos_misses + sp->neg_misses + \
sp->pos_hits + sp->neg_hits; \
if (sp->hitrate > 0.0) \
sp->hitrate = (100.0 * \
((double)sp->pos_hits + \
(double)sp->neg_hits)) / sp->hitrate;
typedef enum {
_NSC_NSLOOKUP = 0,
_NSC_WAIT,
_NSC_USECACHED
} nsc_action_t;
typedef struct nsc_entry_stat {
uint_t hits;
uint8_t status;
time_t timestamp;
int refcount;
} nsc_entry_stat_t;
typedef struct nsc_entry {
avl_node_t avl_link;
struct nsc_entry *qnext;
struct nsc_entry *qprev;
nsc_entry_stat_t stats;
nss_XbyY_key_t key;
void *buffer;
size_t bufsize;
} nsc_entry_t;
typedef struct nsc_keephot {
void *ptr;
uint_t num;
} nsc_keephot_t;
typedef struct waiter {
cond_t w_waitcv;
uint8_t w_signaled;
nsc_entry_t *w_key;
struct waiter *w_next, *w_prev;
} waiter_t;
#define _NSC_INIT_HTSIZE_PRIME 211
#define _NSC_INIT_HTSIZE_POWER2 256
#define _NSC_INIT_HTSIZE_SLOT_VALUE 2896
#define _NSC_HTSIZE_NUM_SLOTS 10
#define _NSC_HTSIZE_PRIMES 211, 509, 1021, 2053, 4099, 8191, \
16381, 32771, 65537, 131071, 262147
#define _NSC_DB_CES_KEY(ptr) \
((ptr)->db_type == nsc_key_ces)
#define _NSC_DB_CIS_KEY(ptr) \
((ptr)->db_type == nsc_key_cis)
#define _NSC_DB_STR_KEY(ptr) \
_NSC_DB_CES_KEY(ptr) || _NSC_DB_CIS_KEY(ptr)
#define _NSC_DB_INT_KEY(ptr) \
((ptr)->db_type == nsc_key_int)
#define NSCD_CFG_GROUP_INFO_GLOBAL_CACHE {1, 0x0001}
typedef struct nscd_cfg_global_cache {
nscd_cfg_group_info_t gi;
nscd_bool_t enable;
} nscd_cfg_global_cache_t;
#define NSCD_CFG_GLOBAL_CACHE_DEFAULTS \
{ NSCD_CFG_GROUP_INFO_GLOBAL_CACHE, nscd_true }
#define NSCD_CFG_GROUP_INFO_CACHE {12, 0x0fff}
typedef struct nscd_cfg_cache {
nscd_cfg_group_info_t gi;
nscd_bool_t enable;
nscd_bool_t per_user;
nscd_bool_t avoid_ns;
nscd_bool_t check_files;
int check_interval;
int pos_ttl;
int neg_ttl;
int keephot;
int hint_size;
ulong_t maxentries;
int suggestedsize;
nscd_bool_t old_data_ok;
} nscd_cfg_cache_t;
#define NSCD_CFG_CACHE_DEFAULTS \
{ \
NSCD_CFG_GROUP_INFO_CACHE, \
nscd_true, nscd_false, nscd_false, nscd_true, \
_NSC_FILE_CHECK_TIME, 600, 10, 0, 1 << 11, 0, \
0, nscd_false \
}
#define NSCD_CFG_STAT_GROUP_INFO_CACHE {9, 0x01ff}
typedef struct nscd_cfg_stat_cache {
nscd_cfg_group_info_t gi;
ulong_t pos_hits;
ulong_t neg_hits;
ulong_t pos_misses;
ulong_t neg_misses;
ulong_t entries;
ulong_t drop_count;
ulong_t wait_count;
ulong_t invalidate_count;
double hitrate;
} nscd_cfg_stat_cache_t;
typedef struct nsc_db {
avl_tree_t tree;
nsc_entry_t **htable;
nsc_entry_t *qhead;
nsc_entry_t *qtail;
nsc_entry_t *reap_node;
int callnumber;
int dbop;
char *name;
mutex_t db_mutex;
waiter_t db_wait;
int htsize;
enum hash_type {
nsc_ht_default = 0,
nsc_ht_prime = 1,
nsc_ht_power2 = 2
} hash_type;
enum db_type {
nsc_key_ces = 0,
nsc_key_cis = 1,
nsc_key_int = 2,
nsc_key_other = 3
} db_type;
uint_t (*gethash)(nss_XbyY_key_t *, int);
int (*compar)(const void *, const void *);
void (*getlogstr)(char *, char *, size_t, nss_XbyY_args_t *);
nscd_cfg_cache_t cfg;
time_t cfg_mtime;
} nsc_db_t;
typedef struct nsc_ctx {
char *dbname;
nscd_cfg_stat_cache_t stats;
nscd_cfg_cache_t cfg;
time_t cfg_mtime;
rwlock_t cfg_rwlp;
mutex_t stats_mutex;
mutex_t file_mutex;
time_t file_mtime;
time_t file_chktime;
off_t file_size;
ino_t file_ino;
const char *file_name;
int db_count;
nsc_db_t *nsc_db[_NSC_MAX_DB];
sema_t throttle_sema;
sema_t revalidate_sema;
nscd_bool_t revalidate_on;
nscd_bool_t reaper_on;
} nsc_ctx_t;
typedef struct nsc_lookup_args {
nsc_ctx_t *ctx;
nsc_db_t *nscdb;
void *buffer;
size_t bufsize;
} nsc_lookup_args_t;
#define CACHE_CTX_COUNT 19
extern void passwd_init_ctx(nsc_ctx_t *);
extern void group_init_ctx(nsc_ctx_t *);
extern void host_init_ctx(nsc_ctx_t *);
extern void ipnode_init_ctx(nsc_ctx_t *);
extern void exec_init_ctx(nsc_ctx_t *);
extern void prof_init_ctx(nsc_ctx_t *);
extern void user_init_ctx(nsc_ctx_t *);
extern void ether_init_ctx(nsc_ctx_t *);
extern void rpc_init_ctx(nsc_ctx_t *);
extern void proto_init_ctx(nsc_ctx_t *);
extern void net_init_ctx(nsc_ctx_t *);
extern void bootp_init_ctx(nsc_ctx_t *);
extern void auth_init_ctx(nsc_ctx_t *);
extern void serv_init_ctx(nsc_ctx_t *);
extern void netmask_init_ctx(nsc_ctx_t *);
extern void printer_init_ctx(nsc_ctx_t *);
extern void project_init_ctx(nsc_ctx_t *);
extern void tnrhtp_init_ctx(nsc_ctx_t *);
extern void tnrhdb_init_ctx(nsc_ctx_t *);
extern int nscd_wait(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *);
extern int nscd_signal(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *);
extern nscd_rc_t init_cache();
extern nsc_db_t *make_cache(enum db_type, int, char *,
int (*compar) (const void *, const void *),
void (*getlogstr)(char *, char *, size_t, nss_XbyY_args_t *),
uint_t (*gethash)(nss_XbyY_key_t *, int),
enum hash_type, int);
extern void nsc_lookup(nsc_lookup_args_t *, int);
extern void nsc_info(nsc_ctx_t *, char *, nscd_cfg_cache_t cfg[],
nscd_cfg_stat_cache_t stats[]);
#ifdef NSCD_DEBUG
extern int nsc_dump(char *, int);
#endif
extern void nsc_invalidate(nsc_ctx_t *, char *, nsc_ctx_t **);
extern nsc_keephot_t *maken(int);
extern void *insertn(nsc_keephot_t *, uint_t, void *);
extern uint_t cis_gethash(const char *, int);
extern uint_t ces_gethash(const char *, int);
extern uint_t db_gethash(const void *, int, int);
extern void leave(int n);
extern int get_cache_idx(char *);
#ifdef __cplusplus
}
#endif
#endif