]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/init.c
Misc code cleanup
[openldap] / servers / slapd / back-bdb / init.c
1 /* init.c - initialize bdb backend */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 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
13 #include "back-bdb.h"
14 #include "external.h"
15
16 static struct bdbi_database {
17         char *file;
18         char *name;
19         int type;
20         int flags;
21 } bdbi_databases[] = {
22         { "nextid" BDB_SUFFIX, "nextid", DB_BTREE, 0 },
23         { "id2entry" BDB_SUFFIX, "id2entry", DB_BTREE, 0 },
24         { "dn2id" BDB_SUFFIX, "dn2id", DB_BTREE, 0 },
25         { NULL, NULL, 0, 0 }
26 };
27
28 #if 0
29 static int
30 bdb_destroy( BackendInfo *bi )
31 {
32         return 0;
33 }
34
35 static int
36 bdb_open( BackendInfo *bi )
37 {
38         /* initialize the underlying database system */
39         Debug( LDAP_DEBUG_TRACE, "bdb_open: initialize BDB backend\n",
40                 0, 0, 0 );
41
42         return 0;
43 }
44
45 static int
46 bdb_close( BackendInfo *bi )
47 {
48         /* terminate the underlying database system */
49         return 0;
50 }
51 #endif
52
53 static int
54 bdb_db_init( BackendDB *be )
55 {
56         struct bdb_info *bdb;
57
58         Debug( LDAP_DEBUG_ANY,
59                 "bdb_db_init: Initializing BDB database\n",
60                 0, 0, 0 );
61
62         /* allocate backend-database-specific stuff */
63         bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) );
64
65         /* DBEnv parameters */
66         bdb->bi_dbenv_home = ch_strdup( BDB_DBENV_HOME );
67         bdb->bi_dbenv_xflags = 0;
68         bdb->bi_dbenv_mode = DEFAULT_MODE;
69         bdb->bi_txn = 1;        /* default to using transactions */
70
71 #ifndef NO_THREADS
72         bdb->bi_lock_detect = DB_LOCK_NORUN;
73 #endif
74
75         ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex );
76
77         be->be_private = bdb;
78         return 0;
79 }
80
81 #ifndef NO_THREADS
82 static void *lock_detect_task( void *arg )
83 {
84         struct bdb_info *bdb = (struct bdb_info *) arg;
85
86         while( bdb->bi_dbenv != NULL ) {
87                 int rc;
88                 sleep( bdb->bi_lock_detect_seconds );
89
90                 rc = lock_detect( bdb->bi_dbenv, 0,
91                         bdb->bi_lock_detect, NULL );
92
93                 if( rc != 0 ) {
94                         break;
95                 }
96         }
97
98         return NULL;
99 }
100 #endif
101
102 static int
103 bdb_db_open( BackendDB *be )
104 {
105         int rc, i;
106         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
107         u_int32_t flags;
108
109         Debug( LDAP_DEBUG_ARGS,
110                 "bdb_db_open: %s\n",
111                 be->be_suffix[0], 0, 0 );
112
113         /* we should check existance of dbenv_home and db_directory */
114
115         rc = db_env_create( &bdb->bi_dbenv, 0 );
116         if( rc != 0 ) {
117                 Debug( LDAP_DEBUG_ANY,
118                         "bdb_db_open: db_env_create failed: %s (%d)\n",
119                         db_strerror(rc), rc, 0 );
120                 return rc;
121         }
122
123         flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE;
124
125         if( bdb->bi_txn ) {
126                 flags |= DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN | DB_RECOVER;
127
128         } else {
129                 flags |= DB_INIT_CDB;
130                 bdb->bi_txn_cp = 0;
131                 bdb->bi_dbenv->set_lk_detect(bdb->bi_dbenv, DB_LOCK_DEFAULT);
132         }
133
134         bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0] );
135         bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
136
137 #ifdef BDB_SUBDIRS
138         {
139                 char dir[MAXPATHLEN];
140                 size_t len = strlen( bdb->bi_dbenv_home );
141
142                 strcpy( dir, bdb->bi_dbenv_home );
143                 strcat( &dir[len], BDB_TMP_SUBDIR );
144                 
145                 rc = bdb->bi_dbenv->set_tmp_dir( bdb->bi_dbenv, dir );
146                 if( rc != 0 ) {
147                         Debug( LDAP_DEBUG_ANY,
148                                 "bdb_db_open: set_tmp_dir(%s) failed: %s (%d)\n",
149                                 dir, db_strerror(rc), rc );
150                         return rc;
151                 }
152
153                 strcat( &dir[len], BDB_LG_SUBDIR );
154
155                 rc = bdb->bi_dbenv->set_lg_dir( bdb->bi_dbenv, dir );
156                 if( rc != 0 ) {
157                         Debug( LDAP_DEBUG_ANY,
158                                 "bdb_db_open: set_lg_dir(%s) failed: %s (%d)\n",
159                                 dir, db_strerror(rc), rc );
160                         return rc;
161                 }
162
163                 strcat( &dir[len], BDB_DATA_SUBDIR );
164
165                 rc = bdb->bi_dbenv->set_data_dir( bdb->bi_dbenv, dir );
166                 if( rc != 0 ) {
167                         Debug( LDAP_DEBUG_ANY,
168                                 "bdb_db_open: set_data_dir(%s) failed: %s (%d)\n",
169                                 dir, db_strerror(rc), rc );
170                         return rc;
171                 }
172         }
173 #endif
174
175         Debug( LDAP_DEBUG_TRACE,
176                 "bdb_db_open: dbenv_open(%s)\n",
177                 bdb->bi_dbenv_home, 0, 0);
178
179         rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
180                 bdb->bi_dbenv_home,
181                 flags,
182                 bdb->bi_dbenv_mode );
183         if( rc != 0 ) {
184                 Debug( LDAP_DEBUG_ANY,
185                         "bdb_db_open: dbenv_open failed: %s (%d)\n",
186                         db_strerror(rc), rc, 0 );
187                 return rc;
188         }
189
190         if( bdb->bi_dbenv_xflags != 0 ) {
191                 rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv,
192                         bdb->bi_dbenv_xflags, 1);
193                 if( rc != 0 ) {
194                         Debug( LDAP_DEBUG_ANY,
195                                 "bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
196                                 db_strerror(rc), rc, 0 );
197                         return rc;
198                 }
199         }
200
201         flags = DB_THREAD | DB_CREATE;
202
203         bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
204                 BDB_INDICES * sizeof(struct bdb_db_info *) );
205
206         /* open (and create) main database */
207         for( i = 0; bdbi_databases[i].name; i++ ) {
208                 struct bdb_db_info *db;
209
210                 db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
211
212                 rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
213                 if( rc != 0 ) {
214                         Debug( LDAP_DEBUG_ANY,
215                                 "bdb_db_open: db_create(%s) failed: %s (%d)\n",
216                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
217                         return rc;
218                 }
219
220                 rc = db->bdi_db->open( db->bdi_db,
221                         bdbi_databases[i].file,
222                         bdbi_databases[i].name,
223                         bdbi_databases[i].type,
224                         bdbi_databases[i].flags | flags,
225                         bdb->bi_dbenv_mode );
226
227                 if( rc != 0 ) {
228                         Debug( LDAP_DEBUG_ANY,
229                                 "bdb_db_open: db_open(%s) failed: %s (%d)\n",
230                                 bdb->bi_dbenv_home, db_strerror(rc), rc );
231                         return rc;
232                 }
233
234                 db->bdi_name = bdbi_databases[i].name;
235                 bdb->bi_databases[i] = db;
236         }
237
238         bdb->bi_databases[i] = NULL;
239         bdb->bi_ndatabases = i;
240
241         /* get nextid */
242         rc = bdb_last_id( be, NULL );
243         if( rc != 0 ) {
244                 Debug( LDAP_DEBUG_ANY,
245                         "bdb_db_open: last_id(%s) failed: %s (%d)\n",
246                         bdb->bi_dbenv_home, db_strerror(rc), rc );
247                 return rc;
248         }
249
250         /* <insert> open (and create) index databases */
251
252 #ifndef NO_THREADS
253         if( bdb->bi_lock_detect != DB_LOCK_NORUN ) {
254                 /* listener as a separate THREAD */
255                 rc = ldap_pvt_thread_create( &bdb->bi_lock_detect_tid,
256                         1, lock_detect_task, bdb );
257         }
258 #endif
259         return 0;
260 }
261
262 static int
263 bdb_db_close( BackendDB *be )
264 {
265         int rc;
266         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
267
268         /* force a checkpoint */
269         if( bdb->bi_txn ) {
270                 rc = txn_checkpoint( bdb->bi_dbenv, 0, 0, DB_FORCE );
271                 if( rc != 0 ) {
272                         Debug( LDAP_DEBUG_ANY,
273                                 "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
274                                 db_strerror(rc), rc, 0 );
275                         return rc;
276                 }
277         }
278
279         while( bdb->bi_ndatabases-- ) {
280                 rc = bdb->bi_databases[bdb->bi_ndatabases]->bdi_db->close(
281                         bdb->bi_databases[bdb->bi_ndatabases]->bdi_db, 0 );
282         }
283
284         return 0;
285 }
286
287 static int
288 bdb_db_destroy( BackendDB *be )
289 {
290         int rc;
291         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
292
293         /* close db environment */
294         if( bdb->bi_dbenv ) {
295                 rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
296                 bdb->bi_dbenv = NULL;
297                 if( rc != 0 ) {
298                         Debug( LDAP_DEBUG_ANY,
299                                 "bdb_db_destroy: close failed: %s (%d)\n",
300                                 db_strerror(rc), rc, 0 );
301                         return rc;
302                 }
303         }
304
305         return 0;
306 }
307
308 #ifdef SLAPD_BDB_DYNAMIC
309 int back_bdb_LTX_init_module( int argc, char *argv[] ) {
310         BackendInfo bi;
311
312         memset( &bi, '\0', sizeof(bi) );
313         bi.bi_type = "bdb";
314         bi.bi_init = bdb_initialize;
315
316         backend_add( &bi );
317         return 0;
318 }
319 #endif /* SLAPD_BDB_DYNAMIC */
320
321 int
322 bdb_initialize(
323         BackendInfo     *bi
324 )
325 {
326         static char *controls[] = {
327                 LDAP_CONTROL_MANAGEDSAIT,
328                 NULL
329         };
330
331         {       /* version check */
332                 int major, minor, patch;
333                 char *version = db_version( &major, &minor, &patch );
334
335                 if( major != DB_VERSION_MAJOR ||
336                         minor != DB_VERSION_MINOR ||
337                         patch < DB_VERSION_PATCH )
338                 {
339                         Debug( LDAP_DEBUG_ANY,
340                                 "bi_back_initialize: version mismatch\n"
341                                 "\texpected: " DB_VERSION_STRING "\n"
342                                 "\tgot: %s \n", version, 0, 0 );
343                 }
344
345                 Debug( LDAP_DEBUG_ANY, "bdb_initialize: %s\n",
346                         version, 0, 0 );
347         }
348
349 #if 0
350         db_env_set_func_malloc( ch_malloc );
351         db_env_set_func_realloc( ch_realloc );
352         db_env_set_func_free( ch_free );
353 #endif
354
355         db_env_set_func_yield( ldap_pvt_thread_yield );
356
357         bi->bi_controls = controls;
358
359         bi->bi_open = 0;
360         bi->bi_close = 0;
361         bi->bi_config = 0;
362         bi->bi_destroy = 0;
363
364         bi->bi_db_init = bdb_db_init;
365         bi->bi_db_config = bdb_db_config;
366         bi->bi_db_open = bdb_db_open;
367         bi->bi_db_close = bdb_db_close;
368         bi->bi_db_destroy = bdb_db_destroy;
369
370         bi->bi_op_add = bdb_add;
371         bi->bi_op_bind = bdb_bind;
372         bi->bi_op_compare = bdb_compare;
373         bi->bi_op_delete = bdb_delete;
374         bi->bi_op_modify = bdb_modify;
375         bi->bi_op_modrdn = bdb_modrdn;
376         bi->bi_op_search = bdb_search;
377
378 #if 0
379         bi->bi_op_unbind = bdb_unbind;
380         bi->bi_op_abandon = bdb_abandon;
381
382         bi->bi_extended = bdb_extended;
383 #endif
384         bi->bi_acl_group = bdb_group;
385         bi->bi_acl_attribute = bdb_attribute;
386         bi->bi_chk_referrals = bdb_referrals;
387
388         bi->bi_entry_release_rw = 0;
389
390         /*
391          * hooks for slap tools
392          */
393         bi->bi_tool_entry_open = bdb_tool_entry_open;
394         bi->bi_tool_entry_close = bdb_tool_entry_close;
395         bi->bi_tool_entry_first = bdb_tool_entry_next;
396         bi->bi_tool_entry_next = bdb_tool_entry_next;
397         bi->bi_tool_entry_get = bdb_tool_entry_get;
398         bi->bi_tool_entry_put = bdb_tool_entry_put;
399         bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
400         bi->bi_tool_sync = 0;
401
402         bi->bi_connection_init = 0;
403         bi->bi_connection_destroy = 0;
404
405         return 0;
406 }