1/* $NetBSD: back-bdb.h,v 1.1.1.3 2010/12/12 15:22:53 adam Exp $ */ 2 3/* back-bdb.h - bdb back-end header file */ 4/* OpenLDAP: pkg/ldap/servers/slapd/back-bdb/back-bdb.h,v 1.141.2.24 2010/04/13 20:23:23 kurt Exp */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2000-2010 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 19#ifndef _BACK_BDB_H_ 20#define _BACK_BDB_H_ 21 22#include <portable.h> 23#include "slap.h" 24#include <db.h> 25#include "alock.h" 26 27LDAP_BEGIN_DECL 28 29#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH) 30 31#define DN_BASE_PREFIX SLAP_INDEX_EQUALITY_PREFIX 32#define DN_ONE_PREFIX '%' 33#define DN_SUBTREE_PREFIX '@' 34 35#define DBTzero(t) (memset((t), 0, sizeof(DBT))) 36#define DBT2bv(t,bv) ((bv)->bv_val = (t)->data, \ 37 (bv)->bv_len = (t)->size) 38#define bv2DBT(bv,t) ((t)->data = (bv)->bv_val, \ 39 (t)->size = (bv)->bv_len ) 40 41#define BDB_TXN_RETRIES 16 42 43#define BDB_MAX_ADD_LOOP 30 44 45#define BDB_SUFFIX ".bdb" 46#define BDB_ID2ENTRY 0 47#define BDB_DN2ID 1 48#define BDB_NDB 2 49 50/* The bdb on-disk entry format is pretty space-inefficient. Average 51 * sized user entries are 3-4K each. You need at least two entries to 52 * fit into a single database page, more is better. 64K is BDB's 53 * upper bound. Smaller pages are better for concurrency. 54 */ 55#ifndef BDB_ID2ENTRY_PAGESIZE 56#define BDB_ID2ENTRY_PAGESIZE 16384 57#endif 58 59#define DEFAULT_CACHE_SIZE 1000 60 61/* The default search IDL stack cache depth */ 62#define DEFAULT_SEARCH_STACK_DEPTH 16 63 64/* The minimum we can function with */ 65#define MINIMUM_SEARCH_STACK_DEPTH 8 66 67typedef struct bdb_idl_cache_entry_s { 68 struct berval kstr; 69 ID *idl; 70 DB *db; 71 int idl_flags; 72 struct bdb_idl_cache_entry_s* idl_lru_prev; 73 struct bdb_idl_cache_entry_s* idl_lru_next; 74} bdb_idl_cache_entry_t; 75 76/* BDB backend specific entry info */ 77typedef struct bdb_entry_info { 78 struct bdb_entry_info *bei_parent; 79 ID bei_id; 80 81 /* we use the bei_id as a lockobj, but we need to make the size != 4 82 * to avoid conflicting with BDB's internal locks. So add a byte here 83 * that is always zero. 84 */ 85 short bei_lockpad; 86 87 short bei_state; 88#define CACHE_ENTRY_DELETED 1 89#define CACHE_ENTRY_NO_KIDS 2 90#define CACHE_ENTRY_NOT_LINKED 4 91#define CACHE_ENTRY_NO_GRANDKIDS 8 92#define CACHE_ENTRY_LOADING 0x10 93#define CACHE_ENTRY_WALKING 0x20 94#define CACHE_ENTRY_ONELEVEL 0x40 95#define CACHE_ENTRY_REFERENCED 0x80 96#define CACHE_ENTRY_NOT_CACHED 0x100 97 int bei_finders; 98 99 /* 100 * remaining fields require backend cache lock to access 101 */ 102 struct berval bei_nrdn; 103#ifdef BDB_HIER 104 struct berval bei_rdn; 105 int bei_modrdns; /* track renames */ 106 int bei_ckids; /* number of kids cached */ 107 int bei_dkids; /* number of kids on-disk, plus 1 */ 108#endif 109 Entry *bei_e; 110 Avlnode *bei_kids; 111#ifdef SLAP_ZONE_ALLOC 112 struct bdb_info *bei_bdb; 113 int bei_zseq; 114#endif 115 ldap_pvt_thread_mutex_t bei_kids_mutex; 116 117 struct bdb_entry_info *bei_lrunext; /* for cache lru list */ 118 struct bdb_entry_info *bei_lruprev; 119} EntryInfo; 120#undef BEI 121#define BEI(e) ((EntryInfo *) ((e)->e_private)) 122 123/* for the in-core cache of entries */ 124typedef struct bdb_cache { 125 EntryInfo *c_eifree; /* free list */ 126 Avlnode *c_idtree; 127 EntryInfo *c_lruhead; /* lru - add accessed entries here */ 128 EntryInfo *c_lrutail; /* lru - rem lru entries from here */ 129 EntryInfo c_dntree; 130 ID c_maxsize; 131 ID c_cursize; 132 ID c_minfree; 133 ID c_eimax; 134 ID c_eiused; /* EntryInfo's in use */ 135 ID c_leaves; /* EntryInfo leaf nodes */ 136 int c_purging; 137 DB_TXN *c_txn; /* used by lru cleaner */ 138 ldap_pvt_thread_rdwr_t c_rwlock; 139 ldap_pvt_thread_mutex_t c_lru_mutex; 140 ldap_pvt_thread_mutex_t c_count_mutex; 141 ldap_pvt_thread_mutex_t c_eifree_mutex; 142#ifdef SLAP_ZONE_ALLOC 143 void *c_zctx; 144#endif 145} Cache; 146 147#define CACHE_READ_LOCK 0 148#define CACHE_WRITE_LOCK 1 149 150#define BDB_INDICES 128 151 152struct bdb_db_info { 153 struct berval bdi_name; 154 DB *bdi_db; 155}; 156 157struct bdb_db_pgsize { 158 struct bdb_db_pgsize *bdp_next; 159 struct berval bdp_name; 160 int bdp_size; 161}; 162 163#ifdef LDAP_DEVEL 164#define BDB_MONITOR_IDX 165#endif /* LDAP_DEVEL */ 166 167typedef struct bdb_monitor_t { 168 void *bdm_cb; 169 struct berval bdm_ndn; 170} bdb_monitor_t; 171 172/* From ldap_rq.h */ 173struct re_s; 174 175struct bdb_info { 176 DB_ENV *bi_dbenv; 177 178 /* DB_ENV parameters */ 179 /* The DB_ENV can be tuned via DB_CONFIG */ 180 char *bi_dbenv_home; 181 u_int32_t bi_dbenv_xflags; /* extra flags */ 182 int bi_dbenv_mode; 183 184 int bi_ndatabases; 185 int bi_db_opflags; /* db-specific flags */ 186 struct bdb_db_info **bi_databases; 187 ldap_pvt_thread_mutex_t bi_database_mutex; 188 struct bdb_db_pgsize *bi_pagesizes; 189 190 slap_mask_t bi_defaultmask; 191 Cache bi_cache; 192 struct bdb_attrinfo **bi_attrs; 193 int bi_nattrs; 194 void *bi_search_stack; 195 int bi_search_stack_depth; 196 int bi_linear_index; 197 198 int bi_txn_cp; 199 u_int32_t bi_txn_cp_min; 200 u_int32_t bi_txn_cp_kbyte; 201 struct re_s *bi_txn_cp_task; 202 struct re_s *bi_index_task; 203 204 u_int32_t bi_lock_detect; 205 long bi_shm_key; 206 207 ID bi_lastid; 208 ldap_pvt_thread_mutex_t bi_lastid_mutex; 209 ID bi_idl_cache_max_size; 210 ID bi_idl_cache_size; 211 Avlnode *bi_idl_tree; 212 bdb_idl_cache_entry_t *bi_idl_lru_head; 213 bdb_idl_cache_entry_t *bi_idl_lru_tail; 214 ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock; 215 ldap_pvt_thread_mutex_t bi_idl_tree_lrulock; 216 alock_info_t bi_alock_info; 217 char *bi_db_config_path; 218 BerVarray bi_db_config; 219 char *bi_db_crypt_file; 220 struct berval bi_db_crypt_key; 221 bdb_monitor_t bi_monitor; 222 223#ifdef BDB_MONITOR_IDX 224 ldap_pvt_thread_mutex_t bi_idx_mutex; 225 Avlnode *bi_idx; 226#endif /* BDB_MONITOR_IDX */ 227 228 int bi_flags; 229#define BDB_IS_OPEN 0x01 230#define BDB_HAS_CONFIG 0x02 231#define BDB_UPD_CONFIG 0x04 232#define BDB_DEL_INDEX 0x08 233#define BDB_RE_OPEN 0x10 234#define BDB_CHKSUM 0x20 235#ifdef BDB_HIER 236 int bi_modrdns; /* number of modrdns completed */ 237 ldap_pvt_thread_mutex_t bi_modrdns_mutex; 238#endif 239}; 240 241#define bi_id2entry bi_databases[BDB_ID2ENTRY] 242#define bi_dn2id bi_databases[BDB_DN2ID] 243 244 245struct bdb_lock_info { 246 struct bdb_lock_info *bli_next; 247 DB_LOCK bli_lock; 248 ID bli_id; 249 int bli_flag; 250}; 251#define BLI_DONTFREE 1 252 253struct bdb_op_info { 254 OpExtra boi_oe; 255 DB_TXN* boi_txn; 256 struct bdb_lock_info *boi_locks; /* used when no txn */ 257 u_int32_t boi_err; 258 char boi_acl_cache; 259 char boi_flag; 260}; 261#define BOI_DONTFREE 1 262 263#define DB_OPEN(db, file, name, type, flags, mode) \ 264 ((db)->open)(db, file, name, type, flags, mode) 265 266#if DB_VERSION_MAJOR < 4 267#define LOCK_DETECT(env,f,t,a) lock_detect(env, f, t, a) 268#define LOCK_GET(env,i,f,o,m,l) lock_get(env, i, f, o, m, l) 269#define LOCK_PUT(env,l) lock_put(env, l) 270#define TXN_CHECKPOINT(env,k,m,f) txn_checkpoint(env, k, m, f) 271#define TXN_BEGIN(env,p,t,f) txn_begin((env), p, t, f) 272#define TXN_PREPARE(txn,gid) txn_prepare((txn), (gid)) 273#define TXN_COMMIT(txn,f) txn_commit((txn), (f)) 274#define TXN_ABORT(txn) txn_abort((txn)) 275#define TXN_ID(txn) txn_id(txn) 276#define XLOCK_ID(env, locker) lock_id(env, locker) 277#define XLOCK_ID_FREE(env, locker) lock_id_free(env, locker) 278#else 279#define LOCK_DETECT(env,f,t,a) (env)->lock_detect(env, f, t, a) 280#define LOCK_GET(env,i,f,o,m,l) (env)->lock_get(env, i, f, o, m, l) 281#define LOCK_PUT(env,l) (env)->lock_put(env, l) 282#define TXN_CHECKPOINT(env,k,m,f) (env)->txn_checkpoint(env, k, m, f) 283#define TXN_BEGIN(env,p,t,f) (env)->txn_begin((env), p, t, f) 284#define TXN_PREPARE(txn,g) (txn)->prepare((txn), (g)) 285#define TXN_COMMIT(txn,f) (txn)->commit((txn), (f)) 286#define TXN_ABORT(txn) (txn)->abort((txn)) 287#define TXN_ID(txn) (txn)->id(txn) 288#define XLOCK_ID(env, locker) (env)->lock_id(env, locker) 289#define XLOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker) 290 291/* BDB 4.1.17 adds txn arg to db->open */ 292#if DB_VERSION_FULL >= 0x04010011 293#undef DB_OPEN 294#define DB_OPEN(db, file, name, type, flags, mode) \ 295 ((db)->open)(db, NULL, file, name, type, flags, mode) 296#endif 297 298/* #undef BDB_LOG_DEBUG */ 299 300#ifdef BDB_LOG_DEBUG 301 302/* env->log_printf appeared in 4.4 */ 303#if DB_VERSION_FULL >= 0x04040000 304#define BDB_LOG_PRINTF(env,txn,fmt,...) (env)->log_printf((env),(txn),(fmt),__VA_ARGS__) 305#else 306extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags, 307 const char *fmt,...); 308#define BDB_LOG_PRINTF(env,txn,fmt,...) __db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__) 309#endif 310 311/* !BDB_LOG_DEBUG */ 312#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ 313 (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__)) 314#define BDB_LOG_PRINTF(a,b,c,...) 315#else 316#define BDB_LOG_PRINTF (void) /* will evaluate and discard the arguments */ 317 318#endif /* BDB_LOG_DEBUG */ 319 320#endif 321 322#ifndef DB_BUFFER_SMALL 323#define DB_BUFFER_SMALL ENOMEM 324#endif 325 326#define BDB_CSN_COMMIT 0 327#define BDB_CSN_ABORT 1 328#define BDB_CSN_RETRY 2 329 330/* Copy an ID "src" to pointer "dst" in big-endian byte order */ 331#define BDB_ID2DISK( src, dst ) \ 332 do { int i0; ID tmp; unsigned char *_p; \ 333 tmp = (src); _p = (unsigned char *)(dst); \ 334 for ( i0=sizeof(ID)-1; i0>=0; i0-- ) { \ 335 _p[i0] = tmp & 0xff; tmp >>= 8; \ 336 } \ 337 } while(0) 338 339/* Copy a pointer "src" to a pointer "dst" from big-endian to native order */ 340#define BDB_DISK2ID( src, dst ) \ 341 do { unsigned i0; ID tmp = 0; unsigned char *_p; \ 342 _p = (unsigned char *)(src); \ 343 for ( i0=0; i0<sizeof(ID); i0++ ) { \ 344 tmp <<= 8; tmp |= *_p++; \ 345 } *(dst) = tmp; \ 346 } while (0) 347 348LDAP_END_DECL 349 350/* for the cache of attribute information (which are indexed, etc.) */ 351typedef struct bdb_attrinfo { 352 AttributeDescription *ai_desc; /* attribute description cn;lang-en */ 353 slap_mask_t ai_indexmask; /* how the attr is indexed */ 354 slap_mask_t ai_newmask; /* new settings to replace old mask */ 355#ifdef LDAP_COMP_MATCH 356 ComponentReference* ai_cr; /*component indexing*/ 357#endif 358} AttrInfo; 359 360/* These flags must not clash with SLAP_INDEX flags or ops in slap.h! */ 361#define BDB_INDEX_DELETING 0x8000U /* index is being modified */ 362#define BDB_INDEX_UPDATE_OP 0x03 /* performing an index update */ 363 364/* For slapindex to record which attrs in an entry belong to which 365 * index database 366 */ 367typedef struct AttrList { 368 struct AttrList *next; 369 Attribute *attr; 370} AttrList; 371 372typedef struct IndexRec { 373 AttrInfo *ai; 374 AttrList *attrs; 375} IndexRec; 376 377#include "proto-bdb.h" 378 379#endif /* _BACK_BDB_H_ */ 380