Back to index

openldap  2.4.31
back-bdb.h
Go to the documentation of this file.
00001 /* back-bdb.h - bdb back-end header file */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2000-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #ifndef _BACK_BDB_H_
00018 #define _BACK_BDB_H_
00019 
00020 #include <portable.h>
00021 #include "slap.h"
00022 #include <db.h>
00023 #include "alock.h"
00024 
00025 LDAP_BEGIN_DECL
00026 
00027 #define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)
00028 
00029 #define DN_BASE_PREFIX             SLAP_INDEX_EQUALITY_PREFIX
00030 #define DN_ONE_PREFIX              '%'
00031 #define DN_SUBTREE_PREFIX   '@'
00032 
00033 #define DBTzero(t)                 (memset((t), 0, sizeof(DBT)))
00034 #define DBT2bv(t,bv)        ((bv)->bv_val = (t)->data, \
00035                                                         (bv)->bv_len = (t)->size)
00036 #define bv2DBT(bv,t)        ((t)->data = (bv)->bv_val, \
00037                                                         (t)->size = (bv)->bv_len )
00038 
00039 #define BDB_TXN_RETRIES            16
00040 
00041 #define BDB_MAX_ADD_LOOP    30
00042 
00043 #define BDB_SUFFIX          ".bdb"
00044 #define BDB_ID2ENTRY 0
00045 #define BDB_DN2ID           1
00046 #define BDB_NDB                    2
00047 
00048 /* The bdb on-disk entry format is pretty space-inefficient. Average
00049  * sized user entries are 3-4K each. You need at least two entries to
00050  * fit into a single database page, more is better. 64K is BDB's
00051  * upper bound. Smaller pages are better for concurrency.
00052  */
00053 #ifndef BDB_ID2ENTRY_PAGESIZE
00054 #define       BDB_ID2ENTRY_PAGESIZE       16384
00055 #endif
00056 
00057 #define DEFAULT_CACHE_SIZE     1000
00058 
00059 /* The default search IDL stack cache depth */
00060 #define DEFAULT_SEARCH_STACK_DEPTH 16
00061 
00062 /* The minimum we can function with */
00063 #define MINIMUM_SEARCH_STACK_DEPTH 8
00064 
00065 typedef struct bdb_idl_cache_entry_s {
00066        struct berval kstr;
00067        ID      *idl;
00068        DB      *db;
00069        int           idl_flags;
00070        struct bdb_idl_cache_entry_s* idl_lru_prev;
00071        struct bdb_idl_cache_entry_s* idl_lru_next;
00072 } bdb_idl_cache_entry_t;
00073 
00074 /* BDB backend specific entry info */
00075 typedef struct bdb_entry_info {
00076        struct bdb_entry_info *bei_parent;
00077        ID bei_id;
00078 
00079        /* we use the bei_id as a lockobj, but we need to make the size != 4
00080         * to avoid conflicting with BDB's internal locks. So add a byte here
00081         * that is always zero.
00082         */
00083        short bei_lockpad;
00084 
00085        short bei_state;
00086 #define       CACHE_ENTRY_DELETED  1
00087 #define       CACHE_ENTRY_NO_KIDS  2
00088 #define       CACHE_ENTRY_NOT_LINKED      4
00089 #define CACHE_ENTRY_NO_GRANDKIDS   8
00090 #define       CACHE_ENTRY_LOADING  0x10
00091 #define       CACHE_ENTRY_WALKING  0x20
00092 #define       CACHE_ENTRY_ONELEVEL 0x40
00093 #define       CACHE_ENTRY_REFERENCED      0x80
00094 #define       CACHE_ENTRY_NOT_CACHED      0x100
00095        int bei_finders;
00096 
00097        /*
00098         * remaining fields require backend cache lock to access
00099         */
00100        struct berval bei_nrdn;
00101 #ifdef BDB_HIER
00102        struct berval bei_rdn;
00103        int    bei_modrdns;  /* track renames */
00104        int    bei_ckids;    /* number of kids cached */
00105        int    bei_dkids;    /* number of kids on-disk, plus 1 */
00106 #endif
00107        Entry  *bei_e;
00108        Avlnode       *bei_kids;
00109 #ifdef SLAP_ZONE_ALLOC
00110        struct bdb_info *bei_bdb;
00111        int bei_zseq; 
00112 #endif
00113        ldap_pvt_thread_mutex_t     bei_kids_mutex;
00114        
00115        struct bdb_entry_info       *bei_lrunext; /* for cache lru list */
00116        struct bdb_entry_info       *bei_lruprev;
00117 } EntryInfo;
00118 #undef BEI
00119 #define BEI(e)       ((EntryInfo *) ((e)->e_private))
00120 
00121 /* for the in-core cache of entries */
00122 typedef struct bdb_cache {
00123        EntryInfo     *c_eifree;    /* free list */
00124        Avlnode              *c_idtree;
00125        EntryInfo     *c_lruhead;   /* lru - add accessed entries here */
00126        EntryInfo     *c_lrutail;   /* lru - rem lru entries from here */
00127        EntryInfo     c_dntree;
00128        ID            c_maxsize;
00129        ID            c_cursize;
00130        ID            c_minfree;
00131        ID            c_eimax;
00132        ID            c_eiused;     /* EntryInfo's in use */
00133        ID            c_leaves;     /* EntryInfo leaf nodes */
00134        int           c_purging;
00135        DB_TXN *c_txn;       /* used by lru cleaner */
00136        ldap_pvt_thread_rdwr_t c_rwlock;
00137        ldap_pvt_thread_mutex_t c_lru_mutex;
00138        ldap_pvt_thread_mutex_t c_count_mutex;
00139        ldap_pvt_thread_mutex_t c_eifree_mutex;
00140 #ifdef SLAP_ZONE_ALLOC
00141        void *c_zctx;
00142 #endif
00143 } Cache;
00144  
00145 #define CACHE_READ_LOCK                0
00146 #define CACHE_WRITE_LOCK       1
00147  
00148 #define BDB_INDICES         128
00149 
00150 struct bdb_db_info {
00151        struct berval bdi_name;
00152        DB                   *bdi_db;
00153 };
00154 
00155 struct bdb_db_pgsize {
00156        struct bdb_db_pgsize *bdp_next;
00157        struct berval bdp_name;
00158        int    bdp_size;
00159 };
00160 
00161 #ifdef LDAP_DEVEL
00162 #define BDB_MONITOR_IDX
00163 #endif /* LDAP_DEVEL */
00164 
00165 typedef struct bdb_monitor_t {
00166        void          *bdm_cb;
00167        struct berval bdm_ndn;
00168 } bdb_monitor_t;
00169 
00170 /* From ldap_rq.h */
00171 struct re_s;
00172 
00173 struct bdb_info {
00174        DB_ENV        *bi_dbenv;
00175 
00176        /* DB_ENV parameters */
00177        /* The DB_ENV can be tuned via DB_CONFIG */
00178        char          *bi_dbenv_home;
00179        u_int32_t     bi_dbenv_xflags; /* extra flags */
00180        int                  bi_dbenv_mode;
00181 
00182        int                  bi_ndatabases;
00183        int           bi_db_opflags;       /* db-specific flags */
00184        struct bdb_db_info **bi_databases;
00185        ldap_pvt_thread_mutex_t     bi_database_mutex;
00186        struct bdb_db_pgsize *bi_pagesizes;
00187 
00188        slap_mask_t   bi_defaultmask;
00189        Cache         bi_cache;
00190        struct bdb_attrinfo         **bi_attrs;
00191        int                  bi_nattrs;
00192        void          *bi_search_stack;
00193        int           bi_search_stack_depth;
00194        int           bi_linear_index;
00195 
00196        int                  bi_txn_cp;
00197        u_int32_t     bi_txn_cp_min;
00198        u_int32_t     bi_txn_cp_kbyte;
00199        struct re_s          *bi_txn_cp_task;
00200        struct re_s          *bi_index_task;
00201 
00202        u_int32_t            bi_lock_detect;
00203        long          bi_shm_key;
00204 
00205        ID                   bi_lastid;
00206        ldap_pvt_thread_mutex_t     bi_lastid_mutex;
00207        ID     bi_idl_cache_max_size;
00208        ID            bi_idl_cache_size;
00209        Avlnode              *bi_idl_tree;
00210        bdb_idl_cache_entry_t       *bi_idl_lru_head;
00211        bdb_idl_cache_entry_t       *bi_idl_lru_tail;
00212        ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock;
00213        ldap_pvt_thread_mutex_t bi_idl_tree_lrulock;
00214        alock_info_t  bi_alock_info;
00215        char          *bi_db_config_path;
00216        BerVarray     bi_db_config;
00217        char          *bi_db_crypt_file;
00218        struct berval bi_db_crypt_key;
00219        bdb_monitor_t bi_monitor;
00220 
00221 #ifdef BDB_MONITOR_IDX
00222        ldap_pvt_thread_mutex_t     bi_idx_mutex;
00223        Avlnode              *bi_idx;
00224 #endif /* BDB_MONITOR_IDX */
00225 
00226        int           bi_flags;
00227 #define       BDB_IS_OPEN          0x01
00228 #define       BDB_HAS_CONFIG       0x02
00229 #define       BDB_UPD_CONFIG       0x04
00230 #define       BDB_DEL_INDEX 0x08
00231 #define       BDB_RE_OPEN          0x10
00232 #define BDB_CHKSUM          0x20
00233 #ifdef BDB_HIER
00234        int           bi_modrdns;          /* number of modrdns completed */
00235        ldap_pvt_thread_mutex_t     bi_modrdns_mutex;
00236 #endif
00237 };
00238 
00239 #define bi_id2entry  bi_databases[BDB_ID2ENTRY]
00240 #define bi_dn2id     bi_databases[BDB_DN2ID]
00241 
00242 
00243 struct bdb_lock_info {
00244        struct bdb_lock_info *bli_next;
00245        DB_LOCK       bli_lock;
00246        ID            bli_id;
00247        int           bli_flag;
00248 };
00249 #define       BLI_DONTFREE  1
00250 
00251 struct bdb_op_info {
00252        OpExtra boi_oe;
00253        DB_TXN*              boi_txn;
00254        struct bdb_lock_info *boi_locks;   /* used when no txn */
00255        u_int32_t     boi_err;
00256        char          boi_acl_cache;
00257        char          boi_flag;
00258 };
00259 #define BOI_DONTFREE 1
00260 
00261 #define       DB_OPEN(db, file, name, type, flags, mode) \
00262        ((db)->open)(db, file, name, type, flags, mode)
00263 
00264 #if DB_VERSION_MAJOR < 4
00265 #define LOCK_DETECT(env,f,t,a)            lock_detect(env, f, t, a)
00266 #define LOCK_GET(env,i,f,o,m,l)           lock_get(env, i, f, o, m, l)
00267 #define LOCK_PUT(env,l)                   lock_put(env, l)
00268 #define TXN_CHECKPOINT(env,k,m,f)  txn_checkpoint(env, k, m, f)
00269 #define TXN_BEGIN(env,p,t,f)              txn_begin((env), p, t, f)
00270 #define TXN_PREPARE(txn,gid)              txn_prepare((txn), (gid))
00271 #define TXN_COMMIT(txn,f)                 txn_commit((txn), (f))
00272 #define       TXN_ABORT(txn)                            txn_abort((txn))
00273 #define TXN_ID(txn)                              txn_id(txn)
00274 #define XLOCK_ID(env, locker)             lock_id(env, locker)
00275 #define XLOCK_ID_FREE(env, locker) lock_id_free(env, locker)
00276 #else
00277 #define LOCK_DETECT(env,f,t,a)            (env)->lock_detect(env, f, t, a)
00278 #define LOCK_GET(env,i,f,o,m,l)           (env)->lock_get(env, i, f, o, m, l)
00279 #define LOCK_PUT(env,l)                   (env)->lock_put(env, l)
00280 #define TXN_CHECKPOINT(env,k,m,f)  (env)->txn_checkpoint(env, k, m, f)
00281 #define TXN_BEGIN(env,p,t,f)              (env)->txn_begin((env), p, t, f)
00282 #define TXN_PREPARE(txn,g)                (txn)->prepare((txn), (g))
00283 #define TXN_COMMIT(txn,f)                 (txn)->commit((txn), (f))
00284 #define TXN_ABORT(txn)                           (txn)->abort((txn))
00285 #define TXN_ID(txn)                              (txn)->id(txn)
00286 #define XLOCK_ID(env, locker)             (env)->lock_id(env, locker)
00287 #define XLOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker)
00288 
00289 /* BDB 4.1.17 adds txn arg to db->open */
00290 #if DB_VERSION_FULL >= 0x04010011
00291 #undef DB_OPEN
00292 #define       DB_OPEN(db, file, name, type, flags, mode) \
00293        ((db)->open)(db, NULL, file, name, type, flags, mode)
00294 #endif
00295 
00296 /* #undef BDB_LOG_DEBUG */
00297 
00298 #ifdef BDB_LOG_DEBUG
00299 
00300 /* env->log_printf appeared in 4.4 */
00301 #if DB_VERSION_FULL >= 0x04040000
00302 #define       BDB_LOG_PRINTF(env,txn,fmt,...)    (env)->log_printf((env),(txn),(fmt),__VA_ARGS__)
00303 #else
00304 extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags,
00305        const char *fmt,...);
00306 #define       BDB_LOG_PRINTF(env,txn,fmt,...)    __db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__)
00307 #endif
00308 
00309 /* !BDB_LOG_DEBUG */
00310 #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
00311        (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__))
00312 #define BDB_LOG_PRINTF(a,b,c,...)
00313 #else
00314 #define BDB_LOG_PRINTF (void)      /* will evaluate and discard the arguments */
00315 
00316 #endif /* BDB_LOG_DEBUG */
00317 
00318 #endif
00319 
00320 #ifndef DB_BUFFER_SMALL
00321 #define DB_BUFFER_SMALL                   ENOMEM
00322 #endif
00323 
00324 #define BDB_CSN_COMMIT      0
00325 #define BDB_CSN_ABORT       1
00326 #define BDB_CSN_RETRY       2
00327 
00328 /* Copy an ID "src" to pointer "dst" in big-endian byte order */
00329 #define BDB_ID2DISK( src, dst )    \
00330        do { int i0; ID tmp; unsigned char *_p;   \
00331               tmp = (src); _p = (unsigned char *)(dst); \
00332               for ( i0=sizeof(ID)-1; i0>=0; i0-- ) {    \
00333                      _p[i0] = tmp & 0xff; tmp >>= 8;    \
00334               } \
00335        } while(0)
00336 
00337 /* Copy a pointer "src" to a pointer "dst" from big-endian to native order */
00338 #define BDB_DISK2ID( src, dst ) \
00339        do { unsigned i0; ID tmp = 0; unsigned char *_p; \
00340               _p = (unsigned char *)(src);       \
00341               for ( i0=0; i0<sizeof(ID); i0++ ) {       \
00342                      tmp <<= 8; tmp |= *_p++;    \
00343               } *(dst) = tmp; \
00344        } while (0)
00345 
00346 LDAP_END_DECL
00347 
00348 /* for the cache of attribute information (which are indexed, etc.) */
00349 typedef struct bdb_attrinfo {
00350        AttributeDescription *ai_desc; /* attribute description cn;lang-en */
00351        slap_mask_t ai_indexmask;   /* how the attr is indexed  */
00352        slap_mask_t ai_newmask;     /* new settings to replace old mask */
00353 #ifdef LDAP_COMP_MATCH
00354        ComponentReference* ai_cr; /*component indexing*/
00355 #endif
00356 } AttrInfo;
00357 
00358 /* These flags must not clash with SLAP_INDEX flags or ops in slap.h! */
00359 #define       BDB_INDEX_DELETING   0x8000U       /* index is being modified */
00360 #define       BDB_INDEX_UPDATE_OP  0x03   /* performing an index update */
00361 
00362 /* For slapindex to record which attrs in an entry belong to which
00363  * index database 
00364  */
00365 typedef struct AttrList {
00366        struct AttrList *next;
00367        Attribute *attr;
00368 } AttrList;
00369 
00370 typedef struct IndexRec {
00371        AttrInfo *ai;
00372        AttrList *attrs;
00373 } IndexRec;
00374 
00375 #include "proto-bdb.h"
00376 
00377 #endif /* _BACK_BDB_H_ */