]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/init.c
comment cleanup
[openldap] / servers / slapd / back-bdb / init.c
1 /* init.c - initialize bdb backend */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12 #include <ac/unistd.h>
13 #include <ac/stdlib.h>
14
15 #include "back-bdb.h"
16 #include "external.h"
17 #include <lutil.h>
18
19 static const struct bdbi_database {
20         char *file;
21         char *name;
22         int type;
23         int flags;
24 } bdbi_databases[] = {
25         { "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 },
26         { "dn2id" BDB_SUFFIX, "dn2id", DB_BTREE, 0 },
27         { NULL, NULL, 0, 0 }
28 };
29
30 struct berval bdb_uuid = { 0, NULL };
31
32 typedef void * db_malloc(size_t);
33 typedef void * db_realloc(void *, size_t);
34
35 #if 0
36 static int
37 bdb_open( BackendInfo *bi )
38 {
39         return 0;
40 }
41
42 static int
43 bdb_destroy( BackendInfo *bi )
44 {
45         return 0;
46 }
47
48 static int
49 bdb_close( BackendInfo *bi )
50 {
51         /* terminate the underlying database system */
52         return 0;
53 }
54 #endif
55
56 static int
57 bdb_db_init( BackendDB *be )
58 {
59         struct bdb_info *bdb;
60
61 #ifdef NEW_LOGGING
62         LDAP_LOG( BACK_BDB, ENTRY, "bdb_db_init", 0, 0, 0 );
63 #else
64         Debug( LDAP_DEBUG_ANY,
65                 "bdb_db_init: Initializing BDB database\n",
66                 0, 0, 0 );
67 #endif
68
69         /* indicate system schema supported */
70         be->be_flags |=
71 #ifdef BDB_SUBENTRIES
72                 SLAP_BFLAG_SUBENTRIES |
73 #endif
74 #ifdef BDB_ALIASES
75                 SLAP_BFLAG_ALIASES |
76 #endif
77                 SLAP_BFLAG_REFERRALS;
78
79         /* allocate backend-database-specific stuff */
80         bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) );
81
82         /* DBEnv parameters */
83         bdb->bi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
84         bdb->bi_dbenv_xflags = 0;
85         bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
86
87         bdb->bi_cache.c_maxsize = DEFAULT_CACHE_SIZE;
88
89         bdb->bi_lock_detect = DB_LOCK_DEFAULT;
90         bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
91         bdb->bi_search_stack = NULL;
92
93 #if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
94         LDAP_LIST_INIT (&bdb->bi_psearch_list);
95 #endif
96
97         ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex );
98         ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_mutex );
99         ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
100         ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
101
102         be->be_private = bdb;
103
104         return 0;
105 }
106
107 int
108 bdb_bt_compare(
109         DB *db, 
110         const DBT *usrkey,
111         const DBT *curkey
112 )
113 {
114         unsigned char *u, *c;
115         int i, x;
116
117         u = usrkey->data;
118         c = curkey->data;
119
120 #ifdef WORDS_BIGENDIAN
121         for( i = 0; i < (int)sizeof(ID); i++)
122 #else
123         for( i = sizeof(ID)-1; i >= 0; i--)
124 #endif
125         {
126                 x = u[i] - c[i];
127                 if( x ) return x;
128         }
129
130         return 0;
131 }
132
133 static int
134 bdb_db_open( BackendDB *be )
135 {
136         int rc, i;
137         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
138         u_int32_t flags;
139 #ifdef HAVE_EBCDIC
140         char path[MAXPATHLEN];
141 #endif
142
143 #ifdef NEW_LOGGING
144         LDAP_LOG( BACK_BDB, ARGS, 
145                 "bdb_db_open: %s\n", be->be_suffix[0].bv_val, 0, 0 );
146 #else
147         Debug( LDAP_DEBUG_ARGS,
148                 "bdb_db_open: %s\n",
149                 be->be_suffix[0].bv_val, 0, 0 );
150 #endif
151
152 #ifndef BDB_MULTIPLE_SUFFIXES
153         if ( be->be_suffix[1].bv_val ) {
154 #ifdef NEW_LOGGING
155         LDAP_LOG( BACK_BDB, ERR, 
156                 "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
157 #else
158         Debug( LDAP_DEBUG_ANY,
159                 "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
160 #endif
161                 return -1;
162         }
163 #endif
164         /* we should check existance of dbenv_home and db_directory */
165
166         rc = db_env_create( &bdb->bi_dbenv, 0 );
167         if( rc != 0 ) {
168 #ifdef NEW_LOGGING
169                 LDAP_LOG( BACK_BDB, ERR, 
170                         "bdb_db_open: db_env_create failed: %s (%d)\n", 
171                         db_strerror(rc), rc, 0 );
172 #else
173                 Debug( LDAP_DEBUG_ANY,
174                         "bdb_db_open: db_env_create failed: %s (%d)\n",
175                         db_strerror(rc), rc, 0 );
176 #endif
177                 return rc;
178         }
179
180         flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE
181                 | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
182         
183 #if 0
184         /* Never do automatic recovery, must perform it manually.
185          * Otherwise restarting with gentlehup will corrupt the
186          * database.
187          */
188         if( !(slapMode & SLAP_TOOL_MODE) ) flags |= DB_RECOVER;
189 #endif
190
191         /* If a key was set, use shared memory for the BDB environment */
192         if ( bdb->bi_shm_key ) {
193                 bdb->bi_dbenv->set_shm_key( bdb->bi_dbenv, bdb->bi_shm_key );
194                 flags |= DB_SYSTEM_MEM;
195         }
196
197         bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
198         bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
199         bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
200
201 #ifdef SLAP_IDL_CACHE
202         if ( bdb->bi_idl_cache_max_size ) {
203                 ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
204                 ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
205                 bdb->bi_idl_cache_size = 0;
206         }
207 #endif
208
209 #ifdef BDB_SUBDIRS
210         {
211                 char dir[MAXPATHLEN], *ptr;
212                 
213                 if (bdb->bi_dbenv_home[0] == '.') {
214                         /* If home is a relative path, relative subdirs
215                          * are just concat'd by BDB. We don't want the
216                          * path to be concat'd twice, e.g.
217                          * ./test-db/./test-db/tmp
218                          */
219                         ptr = dir;
220                 } else {
221                         ptr = lutil_strcopy( dir, bdb->bi_dbenv_home );
222                         *ptr++ = LDAP_DIRSEP[0];
223 #ifdef HAVE_EBCDIC
224                         __atoe( dir );
225 #endif
226                 }
227
228                 strcpy( ptr, BDB_TMP_SUBDIR );
229 #ifdef HAVE_EBCDIC
230                 __atoe( ptr );
231 #endif
232                 rc = bdb->bi_dbenv->set_tmp_dir( bdb->bi_dbenv, dir );
233                 if( rc != 0 ) {
234 #ifdef NEW_LOGGING
235                         LDAP_LOG( BACK_BDB, ERR, 
236                                 "bdb_db_open: set_tmp_dir(%s) failed: %s (%d)\n", 
237                                 dir, db_strerror(rc), rc );
238 #else
239                         Debug( LDAP_DEBUG_ANY,
240                                 "bdb_db_open: set_tmp_dir(%s) failed: %s (%d)\n",
241                                 dir, db_strerror(rc), rc );
242 #endif
243                         return rc;
244                 }
245
246                 strcpy( ptr, BDB_LG_SUBDIR );
247 #ifdef HAVE_EBCDIC
248                 __atoe( ptr );
249 #endif
250                 rc = bdb->bi_dbenv->set_lg_dir( bdb->bi_dbenv, dir );
251                 if( rc != 0 ) {
252 #ifdef NEW_LOGGING
253                         LDAP_LOG( BACK_BDB, ERR, 
254                                 "bdb_db_open: set_lg_dir(%s) failed: %s (%d)\n", 
255                                 dir, db_strerror(rc), rc );
256 #else
257                         Debug( LDAP_DEBUG_ANY,
258                                 "bdb_db_open: set_lg_dir(%s) failed: %s (%d)\n",
259                                 dir, db_strerror(rc), rc );
260 #endif
261                         return rc;
262                 }
263
264                 strcpy( ptr, BDB_DATA_SUBDIR );
265 #ifdef HAVE_EBCDIC
266                 __atoe( ptr );
267 #endif
268                 rc = bdb->bi_dbenv->set_data_dir( bdb->bi_dbenv, dir );
269                 if( rc != 0 ) {
270 #ifdef NEW_LOGGING
271                         LDAP_LOG( BACK_BDB, ERR, 
272                                 "bdb_db_open: set_data_dir(%s) failed: %s (%d)\n",
273                                 dir, db_strerror(rc), rc );
274 #else
275                         Debug( LDAP_DEBUG_ANY,
276                                 "bdb_db_open: set_data_dir(%s) failed: %s (%d)\n",
277                                 dir, db_strerror(rc), rc );
278 #endif
279                         return rc;
280                 }
281         }
282 #endif
283
284 #ifdef NEW_LOGGING
285         LDAP_LOG( BACK_BDB, DETAIL1, 
286                 "bdb_db_open: dbenv_open %s\n", bdb->bi_dbenv_home, 0, 0 );
287 #else
288         Debug( LDAP_DEBUG_TRACE,
289                 "bdb_db_open: dbenv_open(%s)\n",
290                 bdb->bi_dbenv_home, 0, 0);
291 #endif
292
293 #ifdef HAVE_EBCDIC
294         strcpy( path, bdb->bi_dbenv_home );
295         __atoe( path );
296         rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
297                 path,
298                 flags,
299                 bdb->bi_dbenv_mode );
300 #else
301         rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
302                 bdb->bi_dbenv_home,
303                 flags,
304                 bdb->bi_dbenv_mode );
305 #endif
306         if( rc != 0 ) {
307 #ifdef NEW_LOGGING
308                 LDAP_LOG( BACK_BDB, ERR, 
309                         "bdb_db_open: dbenv_open failed: %s (%d)\n", 
310                         db_strerror(rc), rc, 0 );
311 #else
312                 Debug( LDAP_DEBUG_ANY,
313                         "bdb_db_open: dbenv_open failed: %s (%d)\n",
314                         db_strerror(rc), rc, 0 );
315 #endif
316                 return rc;
317         }
318
319         if( bdb->bi_dbenv_xflags != 0 ) {
320                 rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv,
321                         bdb->bi_dbenv_xflags, 1);
322                 if( rc != 0 ) {
323 #ifdef NEW_LOGGING
324                         LDAP_LOG( BACK_BDB, ERR, 
325                                 "bdb_db_open: dbenv_set_flags failed: %s (%d)\n", 
326                                 db_strerror(rc), rc, 0 );
327 #else
328                         Debug( LDAP_DEBUG_ANY,
329                                 "bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
330                                 db_strerror(rc), rc, 0 );
331 #endif
332                         return rc;
333                 }
334         }
335
336         flags = DB_THREAD | DB_CREATE | bdb->bi_db_opflags;
337
338         bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
339                 BDB_INDICES * sizeof(struct bdb_db_info *) );
340
341         /* open (and create) main database */
342         for( i = 0; bdbi_databases[i].name; i++ ) {
343                 struct bdb_db_info *db;
344
345                 db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
346
347                 rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
348                 if( rc != 0 ) {
349 #ifdef NEW_LOGGING
350                         LDAP_LOG( BACK_BDB, ERR, 
351                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n", 
352                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
353 #else
354                         Debug( LDAP_DEBUG_ANY,
355                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n",
356                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
357 #endif
358                         return rc;
359                 }
360
361                 if( i == BDB_ID2ENTRY ) {
362                         rc = db->bdi_db->set_bt_compare( db->bdi_db,
363                                 bdb_bt_compare );
364                         rc = db->bdi_db->set_pagesize( db->bdi_db,
365                                 BDB_ID2ENTRY_PAGESIZE );
366                 } else {
367                         rc = db->bdi_db->set_flags( db->bdi_db, 
368                                 DB_DUP | DB_DUPSORT );
369 #ifndef BDB_HIER
370                         rc = db->bdi_db->set_dup_compare( db->bdi_db,
371                                 bdb_bt_compare );
372 #else
373                         rc = db->bdi_db->set_dup_compare( db->bdi_db,
374                                 bdb_dup_compare );
375                         rc = db->bdi_db->set_bt_compare( db->bdi_db,
376                                 bdb_bt_compare );
377 #endif
378                         rc = db->bdi_db->set_pagesize( db->bdi_db,
379                                 BDB_PAGESIZE );
380                 }
381
382 #ifdef HAVE_EBCDIC
383                 strcpy( path, bdbi_databases[i].file );
384                 __atoe( path );
385                 rc = DB_OPEN( db->bdi_db, NULL,
386                         path,
387                 /*      bdbi_databases[i].name, */ NULL,
388                         bdbi_databases[i].type,
389                         bdbi_databases[i].flags | flags | DB_AUTO_COMMIT,
390                         bdb->bi_dbenv_mode );
391 #else
392                 rc = DB_OPEN( db->bdi_db, NULL,
393                         bdbi_databases[i].file,
394                 /*      bdbi_databases[i].name, */ NULL,
395                         bdbi_databases[i].type,
396                         bdbi_databases[i].flags | flags | DB_AUTO_COMMIT,
397                         bdb->bi_dbenv_mode );
398 #endif
399
400                 if( rc != 0 ) {
401 #ifdef NEW_LOGGING
402                         LDAP_LOG( BACK_BDB, ERR, 
403                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n", 
404                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
405 #else
406                         Debug( LDAP_DEBUG_ANY,
407                                 "bdb_db_open: db_open(%s) failed: %s (%d)\n",
408                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
409 #endif
410                         return rc;
411                 }
412
413                 db->bdi_name = bdbi_databases[i].name;
414                 bdb->bi_databases[i] = db;
415         }
416
417         bdb->bi_databases[i] = NULL;
418         bdb->bi_ndatabases = i;
419
420         /* get nextid */
421         rc = bdb_last_id( be, NULL );
422         if( rc != 0 ) {
423 #ifdef NEW_LOGGING
424                         LDAP_LOG( BACK_BDB, ERR, 
425                                 "bdb_db_open: last_id(%s) failed: %s (%d)\n", 
426                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
427 #else
428                 Debug( LDAP_DEBUG_ANY,
429                         "bdb_db_open: last_id(%s) failed: %s (%d)\n",
430                         bdb->bi_dbenv_home, db_strerror(rc), rc );
431 #endif
432                 return rc;
433         }
434
435         /* <insert> open (and create) index databases */
436         return 0;
437 }
438
439 static int
440 bdb_db_close( BackendDB *be )
441 {
442         int rc;
443         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
444         struct bdb_db_info *db;
445 #ifdef SLAP_IDL_CACHE
446         bdb_idl_cache_entry_t *entry, *next_entry;
447 #endif
448
449         while( bdb->bi_ndatabases-- ) {
450                 db = bdb->bi_databases[bdb->bi_ndatabases];
451                 rc = db->bdi_db->close( db->bdi_db, 0 );
452                 /* Lower numbered names are not strdup'd */
453                 if( bdb->bi_ndatabases >= BDB_NDB )
454                         free( db->bdi_name );
455                 free( db );
456         }
457         free( bdb->bi_databases );
458         bdb_attr_index_destroy( bdb->bi_attrs );
459
460         bdb_cache_release_all (&bdb->bi_cache);
461
462 #ifdef SLAP_IDL_CACHE
463         if ( bdb->bi_idl_cache_max_size ) {
464                 ldap_pvt_thread_rdwr_wlock ( &bdb->bi_idl_tree_rwlock );
465                 avl_free( bdb->bi_idl_tree, NULL );
466                 entry = bdb->bi_idl_lru_head;
467                 while ( entry != NULL ) {
468                         next_entry = entry->idl_lru_next;
469                         if ( entry->idl )
470                                 free( entry->idl );
471                         free( entry->kstr.bv_val );
472                         free( entry );
473                         entry = next_entry;
474                 }
475                 ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
476         }
477 #endif
478
479         return 0;
480 }
481
482 static int
483 bdb_db_destroy( BackendDB *be )
484 {
485         int rc;
486         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
487
488         /* close db environment */
489         if( bdb->bi_dbenv ) {
490                 /* force a checkpoint */
491                 rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
492                 if( rc != 0 ) {
493 #ifdef NEW_LOGGING
494                         LDAP_LOG( BACK_BDB, ERR, 
495                                 "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
496                                 db_strerror(rc), rc, 0 );
497 #else
498                         Debug( LDAP_DEBUG_ANY,
499                                 "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
500                                 db_strerror(rc), rc, 0 );
501 #endif
502                 }
503
504                 rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
505                 bdb->bi_dbenv = NULL;
506                 if( rc != 0 ) {
507 #ifdef NEW_LOGGING
508                         LDAP_LOG( BACK_BDB, ERR, 
509                                 "bdb_db_destroy: close failed: %s (%d)\n", 
510                                 db_strerror(rc), rc, 0 );
511 #else
512                         Debug( LDAP_DEBUG_ANY,
513                                 "bdb_db_destroy: close failed: %s (%d)\n",
514                                 db_strerror(rc), rc, 0 );
515 #endif
516                         return rc;
517                 }
518         }
519
520         if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
521
522         ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
523         ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
524         ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
525         ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
526 #ifdef SLAP_IDL_CACHE
527         if ( bdb->bi_idl_cache_max_size ) {
528                 ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
529                 ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
530         }
531 #endif
532
533         ch_free( bdb );
534         be->be_private = NULL;
535
536         return 0;
537 }
538
539 #ifdef SLAPD_BDB_DYNAMIC
540 int back_bdb_LTX_init_module( int argc, char *argv[] ) {
541         BackendInfo bi;
542
543         memset( &bi, '\0', sizeof(bi) );
544         bi.bi_type = "bdb";
545         bi.bi_init = bdb_initialize;
546
547         backend_add( &bi );
548         return 0;
549 }
550 #endif /* SLAPD_BDB_DYNAMIC */
551
552 int
553 bdb_initialize(
554         BackendInfo     *bi
555 )
556 {
557         static char *controls[] = {
558                 LDAP_CONTROL_MANAGEDSAIT,
559                 LDAP_CONTROL_NOOP,
560 #ifdef LDAP_CONTROL_PAGEDRESULTS
561                 LDAP_CONTROL_PAGEDRESULTS,
562 #endif
563                 LDAP_CONTROL_VALUESRETURNFILTER,
564 #ifdef LDAP_CONTROL_SUBENTRIES
565                 LDAP_CONTROL_SUBENTRIES,
566 #endif
567 #ifdef LDAP_CLIENT_UPDATE
568                 LDAP_CONTROL_CLIENT_UPDATE,
569 #endif
570                 NULL
571         };
572
573         bi->bi_controls = controls;
574
575         /* initialize the underlying database system */
576 #ifdef NEW_LOGGING
577         LDAP_LOG( BACK_BDB, ENTRY, "bdb_db_initialize\n", 0, 0, 0 );
578 #else
579         Debug( LDAP_DEBUG_TRACE, "bdb_initialize: initialize BDB backend\n",
580                 0, 0, 0 );
581 #endif
582
583         {       /* version check */
584                 int major, minor, patch;
585                 char *version = db_version( &major, &minor, &patch );
586 #ifdef HAVE_EBCDIC
587                 char v2[1024];
588
589                 /* All our stdio does an ASCII to EBCDIC conversion on
590                  * the output. Strings from the BDB library are already
591                  * in EBCDIC; we have to go back and forth...
592                  */
593                 strcpy( v2, version );
594                 __etoa( v2 );
595                 version = v2;
596 #endif
597
598                 if( major != DB_VERSION_MAJOR ||
599                         minor != DB_VERSION_MINOR ||
600                         patch < DB_VERSION_PATCH )
601                 {
602 #ifdef NEW_LOGGING
603                         LDAP_LOG( BACK_BDB, ERR, 
604                                 "bdb_db_initialize: version mismatch: "
605                                 "\texpected: %s \tgot: %s\n", DB_VERSION_STRING, version, 0 );
606 #else
607                         Debug( LDAP_DEBUG_ANY,
608                                 "bdb_initialize: version mismatch\n"
609                                 "\texpected: " DB_VERSION_STRING "\n"
610                                 "\tgot: %s \n", version, 0, 0 );
611 #endif
612                 }
613
614 #ifdef NEW_LOGGING
615                 LDAP_LOG( BACK_BDB, DETAIL1, 
616                         "bdb_db_initialize: %s\n", version, 0, 0 );
617 #else
618                 Debug( LDAP_DEBUG_ANY, "bdb_initialize: %s\n",
619                         version, 0, 0 );
620 #endif
621         }
622
623         db_env_set_func_free( ber_memfree );
624         db_env_set_func_malloc( (db_malloc *)ber_memalloc );
625         db_env_set_func_realloc( (db_realloc *)ber_memrealloc );
626 #ifndef NO_THREAD
627         /* This is a no-op on a NO_THREAD build. Leave the default
628          * alone so that BDB will sleep on interprocess conflicts.
629          */
630         db_env_set_func_yield( ldap_pvt_thread_yield );
631 #endif
632
633         {
634                 static char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
635
636                 bdb_uuid.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ));
637                 bdb_uuid.bv_val = uuidbuf;
638         }
639
640         bi->bi_open = 0;
641         bi->bi_close = 0;
642         bi->bi_config = 0;
643         bi->bi_destroy = 0;
644
645         bi->bi_db_init = bdb_db_init;
646         bi->bi_db_config = bdb_db_config;
647         bi->bi_db_open = bdb_db_open;
648         bi->bi_db_close = bdb_db_close;
649         bi->bi_db_destroy = bdb_db_destroy;
650
651         bi->bi_op_add = bdb_add;
652         bi->bi_op_bind = bdb_bind;
653         bi->bi_op_compare = bdb_compare;
654         bi->bi_op_delete = bdb_delete;
655         bi->bi_op_modify = bdb_modify;
656         bi->bi_op_modrdn = bdb_modrdn;
657         bi->bi_op_search = bdb_search;
658
659         bi->bi_op_unbind = 0;
660
661 #ifdef LDAP_CLIENT_UPDATE
662         bi->bi_op_abandon = bdb_abandon;
663         bi->bi_op_cancel = bdb_cancel;
664 #else
665         bi->bi_op_abandon = 0;
666         bi->bi_op_cancel = 0;
667 #endif
668
669         bi->bi_extended = bdb_extended;
670
671         bi->bi_chk_referrals = bdb_referrals;
672         bi->bi_operational = bdb_operational;
673         bi->bi_has_subordinates = bdb_hasSubordinates;
674         bi->bi_entry_release_rw = bdb_entry_release;
675         bi->bi_entry_get_rw = bdb_entry_get;
676
677         /*
678          * hooks for slap tools
679          */
680         bi->bi_tool_entry_open = bdb_tool_entry_open;
681         bi->bi_tool_entry_close = bdb_tool_entry_close;
682         bi->bi_tool_entry_first = bdb_tool_entry_next;
683         bi->bi_tool_entry_next = bdb_tool_entry_next;
684         bi->bi_tool_entry_get = bdb_tool_entry_get;
685         bi->bi_tool_entry_put = bdb_tool_entry_put;
686         bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
687         bi->bi_tool_sync = 0;
688
689         bi->bi_connection_init = 0;
690         bi->bi_connection_destroy = 0;
691
692         return 0;
693 }