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