Home | History | Annotate | Line # | Download | only in back-mdb
init.c revision 1.1.1.1
      1  1.1  tron /*	$NetBSD: init.c,v 1.1.1.1 2014/05/28 09:58:50 tron Exp $	*/
      2  1.1  tron 
      3  1.1  tron /* init.c - initialize mdb backend */
      4  1.1  tron /* $OpenLDAP$ */
      5  1.1  tron /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  1.1  tron  *
      7  1.1  tron  * Copyright 2000-2014 The OpenLDAP Foundation.
      8  1.1  tron  * All rights reserved.
      9  1.1  tron  *
     10  1.1  tron  * Redistribution and use in source and binary forms, with or without
     11  1.1  tron  * modification, are permitted only as authorized by the OpenLDAP
     12  1.1  tron  * Public License.
     13  1.1  tron  *
     14  1.1  tron  * A copy of this license is available in the file LICENSE in the
     15  1.1  tron  * top-level directory of the distribution or, alternatively, at
     16  1.1  tron  * <http://www.OpenLDAP.org/license.html>.
     17  1.1  tron  */
     18  1.1  tron 
     19  1.1  tron #include "portable.h"
     20  1.1  tron 
     21  1.1  tron #include <stdio.h>
     22  1.1  tron #include <ac/string.h>
     23  1.1  tron #include <ac/unistd.h>
     24  1.1  tron #include <ac/stdlib.h>
     25  1.1  tron #include <ac/errno.h>
     26  1.1  tron #include <sys/stat.h>
     27  1.1  tron #include "back-mdb.h"
     28  1.1  tron #include <lutil.h>
     29  1.1  tron #include <ldap_rq.h>
     30  1.1  tron #include "config.h"
     31  1.1  tron 
     32  1.1  tron static const struct berval mdmi_databases[] = {
     33  1.1  tron 	BER_BVC("ad2i"),
     34  1.1  tron 	BER_BVC("dn2i"),
     35  1.1  tron 	BER_BVC("id2e"),
     36  1.1  tron 	BER_BVNULL
     37  1.1  tron };
     38  1.1  tron 
     39  1.1  tron static int
     40  1.1  tron mdb_id_compare( const MDB_val *a, const MDB_val *b )
     41  1.1  tron {
     42  1.1  tron 	return *(ID *)a->mv_data < *(ID *)b->mv_data ? -1 : *(ID *)a->mv_data > *(ID *)b->mv_data;
     43  1.1  tron }
     44  1.1  tron 
     45  1.1  tron static int
     46  1.1  tron mdb_db_init( BackendDB *be, ConfigReply *cr )
     47  1.1  tron {
     48  1.1  tron 	struct mdb_info	*mdb;
     49  1.1  tron 	int rc;
     50  1.1  tron 
     51  1.1  tron 	Debug( LDAP_DEBUG_TRACE,
     52  1.1  tron 		LDAP_XSTRING(mdb_db_init) ": Initializing mdb database\n",
     53  1.1  tron 		0, 0, 0 );
     54  1.1  tron 
     55  1.1  tron 	/* allocate backend-database-specific stuff */
     56  1.1  tron 	mdb = (struct mdb_info *) ch_calloc( 1, sizeof(struct mdb_info) );
     57  1.1  tron 
     58  1.1  tron 	/* DBEnv parameters */
     59  1.1  tron 	mdb->mi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
     60  1.1  tron 	mdb->mi_dbenv_flags = 0;
     61  1.1  tron 	mdb->mi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
     62  1.1  tron 
     63  1.1  tron 	mdb->mi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
     64  1.1  tron 	mdb->mi_search_stack = NULL;
     65  1.1  tron 
     66  1.1  tron 	mdb->mi_mapsize = DEFAULT_MAPSIZE;
     67  1.1  tron 
     68  1.1  tron 	be->be_private = mdb;
     69  1.1  tron 	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
     70  1.1  tron 
     71  1.1  tron #ifndef MDB_MULTIPLE_SUFFIXES
     72  1.1  tron 	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX;
     73  1.1  tron #endif
     74  1.1  tron 
     75  1.1  tron 	rc = mdb_monitor_db_init( be );
     76  1.1  tron 
     77  1.1  tron 	return rc;
     78  1.1  tron }
     79  1.1  tron 
     80  1.1  tron static int
     81  1.1  tron mdb_db_close( BackendDB *be, ConfigReply *cr );
     82  1.1  tron 
     83  1.1  tron static int
     84  1.1  tron mdb_db_open( BackendDB *be, ConfigReply *cr )
     85  1.1  tron {
     86  1.1  tron 	int rc, i;
     87  1.1  tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
     88  1.1  tron 	struct stat stat1;
     89  1.1  tron 	uint32_t flags;
     90  1.1  tron 	char *dbhome;
     91  1.1  tron 	MDB_txn *txn;
     92  1.1  tron 
     93  1.1  tron 	if ( be->be_suffix == NULL ) {
     94  1.1  tron 		Debug( LDAP_DEBUG_ANY,
     95  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": need suffix.\n",
     96  1.1  tron 			1, 0, 0 );
     97  1.1  tron 		return -1;
     98  1.1  tron 	}
     99  1.1  tron 
    100  1.1  tron 	Debug( LDAP_DEBUG_ARGS,
    101  1.1  tron 		LDAP_XSTRING(mdb_db_open) ": \"%s\"\n",
    102  1.1  tron 		be->be_suffix[0].bv_val, 0, 0 );
    103  1.1  tron 
    104  1.1  tron 	/* Check existence of dbenv_home. Any error means trouble */
    105  1.1  tron 	rc = stat( mdb->mi_dbenv_home, &stat1 );
    106  1.1  tron 	if( rc != 0 ) {
    107  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    108  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    109  1.1  tron 			"cannot access database directory \"%s\" (%d).\n",
    110  1.1  tron 			be->be_suffix[0].bv_val, mdb->mi_dbenv_home, errno );
    111  1.1  tron 		return -1;
    112  1.1  tron 	}
    113  1.1  tron 
    114  1.1  tron 	/* mdb is always clean */
    115  1.1  tron 	be->be_flags |= SLAP_DBFLAG_CLEAN;
    116  1.1  tron 
    117  1.1  tron 	rc = mdb_env_create( &mdb->mi_dbenv );
    118  1.1  tron 	if( rc != 0 ) {
    119  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    120  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    121  1.1  tron 			"mdb_env_create failed: %s (%d).\n",
    122  1.1  tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    123  1.1  tron 		goto fail;
    124  1.1  tron 	}
    125  1.1  tron 
    126  1.1  tron 	if ( mdb->mi_readers ) {
    127  1.1  tron 		rc = mdb_env_set_maxreaders( mdb->mi_dbenv, mdb->mi_readers );
    128  1.1  tron 		if( rc != 0 ) {
    129  1.1  tron 			Debug( LDAP_DEBUG_ANY,
    130  1.1  tron 				LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    131  1.1  tron 				"mdb_env_set_maxreaders failed: %s (%d).\n",
    132  1.1  tron 				be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    133  1.1  tron 			goto fail;
    134  1.1  tron 		}
    135  1.1  tron 	}
    136  1.1  tron 
    137  1.1  tron 	rc = mdb_env_set_mapsize( mdb->mi_dbenv, mdb->mi_mapsize );
    138  1.1  tron 	if( rc != 0 ) {
    139  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    140  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    141  1.1  tron 			"mdb_env_set_mapsize failed: %s (%d).\n",
    142  1.1  tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    143  1.1  tron 		goto fail;
    144  1.1  tron 	}
    145  1.1  tron 
    146  1.1  tron 	rc = mdb_env_set_maxdbs( mdb->mi_dbenv, MDB_INDICES );
    147  1.1  tron 	if( rc != 0 ) {
    148  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    149  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    150  1.1  tron 			"mdb_env_set_maxdbs failed: %s (%d).\n",
    151  1.1  tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    152  1.1  tron 		goto fail;
    153  1.1  tron 	}
    154  1.1  tron 
    155  1.1  tron #ifdef HAVE_EBCDIC
    156  1.1  tron 	strcpy( path, mdb->mi_dbenv_home );
    157  1.1  tron 	__atoe( path );
    158  1.1  tron 	dbhome = path;
    159  1.1  tron #else
    160  1.1  tron 	dbhome = mdb->mi_dbenv_home;
    161  1.1  tron #endif
    162  1.1  tron 
    163  1.1  tron 	Debug( LDAP_DEBUG_TRACE,
    164  1.1  tron 		LDAP_XSTRING(mdb_db_open) ": database \"%s\": "
    165  1.1  tron 		"dbenv_open(%s).\n",
    166  1.1  tron 		be->be_suffix[0].bv_val, mdb->mi_dbenv_home, 0);
    167  1.1  tron 
    168  1.1  tron 	flags = mdb->mi_dbenv_flags;
    169  1.1  tron 
    170  1.1  tron 	if ( slapMode & SLAP_TOOL_QUICK )
    171  1.1  tron 		flags |= MDB_NOSYNC|MDB_WRITEMAP;
    172  1.1  tron 
    173  1.1  tron 	if ( slapMode & SLAP_TOOL_READONLY)
    174  1.1  tron 		flags |= MDB_RDONLY;
    175  1.1  tron 
    176  1.1  tron 	rc = mdb_env_open( mdb->mi_dbenv, dbhome,
    177  1.1  tron 			flags, mdb->mi_dbenv_mode );
    178  1.1  tron 
    179  1.1  tron 	if ( rc ) {
    180  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    181  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened, err %d. "
    182  1.1  tron 			"Restore from backup!\n",
    183  1.1  tron 			be->be_suffix[0].bv_val, rc, 0 );
    184  1.1  tron 		goto fail;
    185  1.1  tron 	}
    186  1.1  tron 
    187  1.1  tron 	rc = mdb_txn_begin( mdb->mi_dbenv, NULL, flags & MDB_RDONLY, &txn );
    188  1.1  tron 	if ( rc ) {
    189  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    190  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened, err %d. "
    191  1.1  tron 			"Restore from backup!\n",
    192  1.1  tron 			be->be_suffix[0].bv_val, rc, 0 );
    193  1.1  tron 		goto fail;
    194  1.1  tron 	}
    195  1.1  tron 
    196  1.1  tron 	/* open (and create) main databases */
    197  1.1  tron 	for( i = 0; mdmi_databases[i].bv_val; i++ ) {
    198  1.1  tron 		flags = MDB_INTEGERKEY;
    199  1.1  tron 		if( i == MDB_ID2ENTRY ) {
    200  1.1  tron 			if ( !(slapMode & (SLAP_TOOL_READMAIN|SLAP_TOOL_READONLY) ))
    201  1.1  tron 				flags |= MDB_CREATE;
    202  1.1  tron 		} else {
    203  1.1  tron 			if ( i == MDB_DN2ID )
    204  1.1  tron 				flags |= MDB_DUPSORT;
    205  1.1  tron 			if ( !(slapMode & SLAP_TOOL_READONLY) )
    206  1.1  tron 				flags |= MDB_CREATE;
    207  1.1  tron 		}
    208  1.1  tron 
    209  1.1  tron 		rc = mdb_dbi_open( txn,
    210  1.1  tron 			mdmi_databases[i].bv_val,
    211  1.1  tron 			flags,
    212  1.1  tron 			&mdb->mi_dbis[i] );
    213  1.1  tron 
    214  1.1  tron 		if ( rc != 0 ) {
    215  1.1  tron 			snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
    216  1.1  tron 				"mdb_dbi_open(%s/%s) failed: %s (%d).",
    217  1.1  tron 				be->be_suffix[0].bv_val,
    218  1.1  tron 				mdb->mi_dbenv_home, mdmi_databases[i].bv_val,
    219  1.1  tron 				mdb_strerror(rc), rc );
    220  1.1  tron 			Debug( LDAP_DEBUG_ANY,
    221  1.1  tron 				LDAP_XSTRING(mdb_db_open) ": %s\n",
    222  1.1  tron 				cr->msg, 0, 0 );
    223  1.1  tron 			goto fail;
    224  1.1  tron 		}
    225  1.1  tron 
    226  1.1  tron 		if ( i == MDB_ID2ENTRY )
    227  1.1  tron 			mdb_set_compare( txn, mdb->mi_dbis[i], mdb_id_compare );
    228  1.1  tron 		else if ( i == MDB_DN2ID ) {
    229  1.1  tron 			MDB_cursor *mc;
    230  1.1  tron 			MDB_val key, data;
    231  1.1  tron 			ID id;
    232  1.1  tron 			mdb_set_dupsort( txn, mdb->mi_dbis[i], mdb_dup_compare );
    233  1.1  tron 			/* check for old dn2id format */
    234  1.1  tron 			rc = mdb_cursor_open( txn, mdb->mi_dbis[i], &mc );
    235  1.1  tron 			/* first record is always ID 0 */
    236  1.1  tron 			rc = mdb_cursor_get( mc, &key, &data, MDB_FIRST );
    237  1.1  tron 			if ( rc == 0 ) {
    238  1.1  tron 				rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT );
    239  1.1  tron 				if ( rc == 0 ) {
    240  1.1  tron 					int len;
    241  1.1  tron 					unsigned char *ptr;
    242  1.1  tron 					ptr = data.mv_data;
    243  1.1  tron 					len = (ptr[0] & 0x7f) << 8 | ptr[1];
    244  1.1  tron 					if (data.mv_size < 2*len + 4 + 2*sizeof(ID)) {
    245  1.1  tron 						snprintf( cr->msg, sizeof(cr->msg),
    246  1.1  tron 						"database \"%s\": DN index needs upgrade, "
    247  1.1  tron 						"run \"slapindex entryDN\".",
    248  1.1  tron 						be->be_suffix[0].bv_val );
    249  1.1  tron 						Debug( LDAP_DEBUG_ANY,
    250  1.1  tron 							LDAP_XSTRING(mdb_db_open) ": %s\n",
    251  1.1  tron 							cr->msg, 0, 0 );
    252  1.1  tron 						if ( !(slapMode & SLAP_TOOL_READMAIN ))
    253  1.1  tron 							rc = LDAP_OTHER;
    254  1.1  tron 						mdb->mi_flags |= MDB_NEED_UPGRADE;
    255  1.1  tron 					}
    256  1.1  tron 				}
    257  1.1  tron 			}
    258  1.1  tron 			mdb_cursor_close( mc );
    259  1.1  tron 			if ( rc == LDAP_OTHER )
    260  1.1  tron 				goto fail;
    261  1.1  tron 		}
    262  1.1  tron 	}
    263  1.1  tron 
    264  1.1  tron 	rc = mdb_ad_read( mdb, txn );
    265  1.1  tron 	if ( rc ) {
    266  1.1  tron 		mdb_txn_abort( txn );
    267  1.1  tron 		goto fail;
    268  1.1  tron 	}
    269  1.1  tron 
    270  1.1  tron 	rc = mdb_attr_dbs_open( be, txn, cr );
    271  1.1  tron 	if ( rc ) {
    272  1.1  tron 		mdb_txn_abort( txn );
    273  1.1  tron 		goto fail;
    274  1.1  tron 	}
    275  1.1  tron 
    276  1.1  tron 	rc = mdb_txn_commit(txn);
    277  1.1  tron 	if ( rc != 0 ) {
    278  1.1  tron 		Debug( LDAP_DEBUG_ANY,
    279  1.1  tron 			LDAP_XSTRING(mdb_db_open) ": database %s: "
    280  1.1  tron 			"txn_commit failed: %s (%d)\n",
    281  1.1  tron 			be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    282  1.1  tron 		goto fail;
    283  1.1  tron 	}
    284  1.1  tron 
    285  1.1  tron 	/* monitor setup */
    286  1.1  tron 	rc = mdb_monitor_db_open( be );
    287  1.1  tron 	if ( rc != 0 ) {
    288  1.1  tron 		goto fail;
    289  1.1  tron 	}
    290  1.1  tron 
    291  1.1  tron 	mdb->mi_flags |= MDB_IS_OPEN;
    292  1.1  tron 
    293  1.1  tron 	return 0;
    294  1.1  tron 
    295  1.1  tron fail:
    296  1.1  tron 	mdb_db_close( be, NULL );
    297  1.1  tron 	return rc;
    298  1.1  tron }
    299  1.1  tron 
    300  1.1  tron static int
    301  1.1  tron mdb_db_close( BackendDB *be, ConfigReply *cr )
    302  1.1  tron {
    303  1.1  tron 	int rc;
    304  1.1  tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
    305  1.1  tron 
    306  1.1  tron 	/* monitor handling */
    307  1.1  tron 	(void)mdb_monitor_db_close( be );
    308  1.1  tron 
    309  1.1  tron 	mdb->mi_flags &= ~MDB_IS_OPEN;
    310  1.1  tron 
    311  1.1  tron 	if( mdb->mi_dbenv ) {
    312  1.1  tron 		mdb_reader_flush( mdb->mi_dbenv );
    313  1.1  tron 	}
    314  1.1  tron 
    315  1.1  tron 	if ( mdb->mi_dbenv ) {
    316  1.1  tron 		if ( mdb->mi_dbis[0] ) {
    317  1.1  tron 			int i;
    318  1.1  tron 
    319  1.1  tron 			mdb_attr_dbs_close( mdb );
    320  1.1  tron 			for ( i=0; i<MDB_NDB; i++ )
    321  1.1  tron 				mdb_dbi_close( mdb->mi_dbenv, mdb->mi_dbis[i] );
    322  1.1  tron 
    323  1.1  tron 			/* force a sync, but not if we were ReadOnly,
    324  1.1  tron 			 * and not in Quick mode.
    325  1.1  tron 			 */
    326  1.1  tron 			if (!(slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY))) {
    327  1.1  tron 				rc = mdb_env_sync( mdb->mi_dbenv, 1 );
    328  1.1  tron 				if( rc != 0 ) {
    329  1.1  tron 					Debug( LDAP_DEBUG_ANY,
    330  1.1  tron 						"mdb_db_close: database \"%s\": "
    331  1.1  tron 						"mdb_env_sync failed: %s (%d).\n",
    332  1.1  tron 						be->be_suffix[0].bv_val, mdb_strerror(rc), rc );
    333  1.1  tron 				}
    334  1.1  tron 			}
    335  1.1  tron 		}
    336  1.1  tron 
    337  1.1  tron 		mdb_env_close( mdb->mi_dbenv );
    338  1.1  tron 		mdb->mi_dbenv = NULL;
    339  1.1  tron 	}
    340  1.1  tron 
    341  1.1  tron 	return 0;
    342  1.1  tron }
    343  1.1  tron 
    344  1.1  tron static int
    345  1.1  tron mdb_db_destroy( BackendDB *be, ConfigReply *cr )
    346  1.1  tron {
    347  1.1  tron 	struct mdb_info *mdb = (struct mdb_info *) be->be_private;
    348  1.1  tron 
    349  1.1  tron 	/* stop and remove checkpoint task */
    350  1.1  tron 	if ( mdb->mi_txn_cp_task ) {
    351  1.1  tron 		struct re_s *re = mdb->mi_txn_cp_task;
    352  1.1  tron 		mdb->mi_txn_cp_task = NULL;
    353  1.1  tron 		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
    354  1.1  tron 		if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
    355  1.1  tron 			ldap_pvt_runqueue_stoptask( &slapd_rq, re );
    356  1.1  tron 		ldap_pvt_runqueue_remove( &slapd_rq, re );
    357  1.1  tron 		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
    358  1.1  tron 	}
    359  1.1  tron 
    360  1.1  tron 	/* monitor handling */
    361  1.1  tron 	(void)mdb_monitor_db_destroy( be );
    362  1.1  tron 
    363  1.1  tron 	if( mdb->mi_dbenv_home ) ch_free( mdb->mi_dbenv_home );
    364  1.1  tron 
    365  1.1  tron 	mdb_attr_index_destroy( mdb );
    366  1.1  tron 
    367  1.1  tron 	ch_free( mdb );
    368  1.1  tron 	be->be_private = NULL;
    369  1.1  tron 
    370  1.1  tron 	return 0;
    371  1.1  tron }
    372  1.1  tron 
    373  1.1  tron int
    374  1.1  tron mdb_back_initialize(
    375  1.1  tron 	BackendInfo	*bi )
    376  1.1  tron {
    377  1.1  tron 	int rc;
    378  1.1  tron 
    379  1.1  tron 	static char *controls[] = {
    380  1.1  tron 		LDAP_CONTROL_ASSERT,
    381  1.1  tron 		LDAP_CONTROL_MANAGEDSAIT,
    382  1.1  tron 		LDAP_CONTROL_NOOP,
    383  1.1  tron 		LDAP_CONTROL_PAGEDRESULTS,
    384  1.1  tron 		LDAP_CONTROL_PRE_READ,
    385  1.1  tron 		LDAP_CONTROL_POST_READ,
    386  1.1  tron 		LDAP_CONTROL_SUBENTRIES,
    387  1.1  tron 		LDAP_CONTROL_X_PERMISSIVE_MODIFY,
    388  1.1  tron #ifdef LDAP_X_TXN
    389  1.1  tron 		LDAP_CONTROL_X_TXN_SPEC,
    390  1.1  tron #endif
    391  1.1  tron 		NULL
    392  1.1  tron 	};
    393  1.1  tron 
    394  1.1  tron 	/* initialize the underlying database system */
    395  1.1  tron 	Debug( LDAP_DEBUG_TRACE,
    396  1.1  tron 		LDAP_XSTRING(mdb_back_initialize) ": initialize "
    397  1.1  tron 		MDB_UCTYPE " backend\n", 0, 0, 0 );
    398  1.1  tron 
    399  1.1  tron 	bi->bi_flags |=
    400  1.1  tron 		SLAP_BFLAG_INCREMENT |
    401  1.1  tron 		SLAP_BFLAG_SUBENTRIES |
    402  1.1  tron 		SLAP_BFLAG_ALIASES |
    403  1.1  tron 		SLAP_BFLAG_REFERRALS;
    404  1.1  tron 
    405  1.1  tron 	bi->bi_controls = controls;
    406  1.1  tron 
    407  1.1  tron 	{	/* version check */
    408  1.1  tron 		int major, minor, patch, ver;
    409  1.1  tron 		char *version = mdb_version( &major, &minor, &patch );
    410  1.1  tron #ifdef HAVE_EBCDIC
    411  1.1  tron 		char v2[1024];
    412  1.1  tron 
    413  1.1  tron 		/* All our stdio does an ASCII to EBCDIC conversion on
    414  1.1  tron 		 * the output. Strings from the MDB library are already
    415  1.1  tron 		 * in EBCDIC; we have to go back and forth...
    416  1.1  tron 		 */
    417  1.1  tron 		strcpy( v2, version );
    418  1.1  tron 		__etoa( v2 );
    419  1.1  tron 		version = v2;
    420  1.1  tron #endif
    421  1.1  tron 		ver = (major << 24) | (minor << 16) | patch;
    422  1.1  tron 		if( ver != MDB_VERSION_FULL ) {
    423  1.1  tron 			/* fail if a versions don't match */
    424  1.1  tron 			Debug( LDAP_DEBUG_ANY,
    425  1.1  tron 				LDAP_XSTRING(mdb_back_initialize) ": "
    426  1.1  tron 				"MDB library version mismatch:"
    427  1.1  tron 				" expected " MDB_VERSION_STRING ","
    428  1.1  tron 				" got %s\n", version, 0, 0 );
    429  1.1  tron 			return -1;
    430  1.1  tron 		}
    431  1.1  tron 
    432  1.1  tron 		Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_back_initialize)
    433  1.1  tron 			": %s\n", version, 0, 0 );
    434  1.1  tron 	}
    435  1.1  tron 
    436  1.1  tron 	bi->bi_open = 0;
    437  1.1  tron 	bi->bi_close = 0;
    438  1.1  tron 	bi->bi_config = 0;
    439  1.1  tron 	bi->bi_destroy = 0;
    440  1.1  tron 
    441  1.1  tron 	bi->bi_db_init = mdb_db_init;
    442  1.1  tron 	bi->bi_db_config = config_generic_wrapper;
    443  1.1  tron 	bi->bi_db_open = mdb_db_open;
    444  1.1  tron 	bi->bi_db_close = mdb_db_close;
    445  1.1  tron 	bi->bi_db_destroy = mdb_db_destroy;
    446  1.1  tron 
    447  1.1  tron 	bi->bi_op_add = mdb_add;
    448  1.1  tron 	bi->bi_op_bind = mdb_bind;
    449  1.1  tron 	bi->bi_op_compare = mdb_compare;
    450  1.1  tron 	bi->bi_op_delete = mdb_delete;
    451  1.1  tron 	bi->bi_op_modify = mdb_modify;
    452  1.1  tron 	bi->bi_op_modrdn = mdb_modrdn;
    453  1.1  tron 	bi->bi_op_search = mdb_search;
    454  1.1  tron 
    455  1.1  tron 	bi->bi_op_unbind = 0;
    456  1.1  tron 
    457  1.1  tron 	bi->bi_extended = mdb_extended;
    458  1.1  tron 
    459  1.1  tron 	bi->bi_chk_referrals = 0;
    460  1.1  tron 	bi->bi_operational = mdb_operational;
    461  1.1  tron 
    462  1.1  tron 	bi->bi_has_subordinates = mdb_hasSubordinates;
    463  1.1  tron 	bi->bi_entry_release_rw = mdb_entry_release;
    464  1.1  tron 	bi->bi_entry_get_rw = mdb_entry_get;
    465  1.1  tron 
    466  1.1  tron 	/*
    467  1.1  tron 	 * hooks for slap tools
    468  1.1  tron 	 */
    469  1.1  tron 	bi->bi_tool_entry_open = mdb_tool_entry_open;
    470  1.1  tron 	bi->bi_tool_entry_close = mdb_tool_entry_close;
    471  1.1  tron 	bi->bi_tool_entry_first = backend_tool_entry_first;
    472  1.1  tron 	bi->bi_tool_entry_first_x = mdb_tool_entry_first_x;
    473  1.1  tron 	bi->bi_tool_entry_next = mdb_tool_entry_next;
    474  1.1  tron 	bi->bi_tool_entry_get = mdb_tool_entry_get;
    475  1.1  tron 	bi->bi_tool_entry_put = mdb_tool_entry_put;
    476  1.1  tron 	bi->bi_tool_entry_reindex = mdb_tool_entry_reindex;
    477  1.1  tron 	bi->bi_tool_sync = 0;
    478  1.1  tron 	bi->bi_tool_dn2id_get = mdb_tool_dn2id_get;
    479  1.1  tron 	bi->bi_tool_entry_modify = mdb_tool_entry_modify;
    480  1.1  tron 
    481  1.1  tron 	bi->bi_connection_init = 0;
    482  1.1  tron 	bi->bi_connection_destroy = 0;
    483  1.1  tron 
    484  1.1  tron 	rc = mdb_back_init_cf( bi );
    485  1.1  tron 
    486  1.1  tron 	return rc;
    487  1.1  tron }
    488  1.1  tron 
    489  1.1  tron #if	(SLAPD_MDB == SLAPD_MOD_DYNAMIC)
    490  1.1  tron 
    491  1.1  tron SLAP_BACKEND_INIT_MODULE( mdb )
    492  1.1  tron 
    493  1.1  tron #endif /* SLAPD_MDB == SLAPD_MOD_DYNAMIC */
    494  1.1  tron 
    495