static int mdb_db_open( BackendDB *be, ConfigReply *cr ) { int rc, i; struct mdb_info *mdb = (struct mdb_info *) be->be_private; struct stat stat1; uint32_t flags; char *dbhome; MDB_txn *txn; if ( be->be_suffix == NULL ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": need suffix.\n", 1, 0, 0 ); return -1; } Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(mdb_db_open) ": \"%s\"\n", be->be_suffix[0].bv_val, 0, 0 ); /* Check existence of dbenv_home. Any error means trouble */ rc = stat( mdb->mi_dbenv_home, &stat1 ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "cannot access database directory \"%s\" (%d).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, errno ); return -1; } /* mdb is always clean */ be->be_flags |= SLAP_DBFLAG_CLEAN; rc = mdb_env_create( &mdb->mi_dbenv ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_create failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } if ( mdb->mi_readers ) { rc = mdb_env_set_maxreaders( mdb->mi_dbenv, mdb->mi_readers ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxreaders failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } } rc = mdb_env_set_mapsize( mdb->mi_dbenv, mdb->mi_mapsize ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_mapsize failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } rc = mdb_env_set_maxdbs( mdb->mi_dbenv, MDB_INDICES ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxdbs failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } #ifdef HAVE_EBCDIC strcpy( path, mdb->mi_dbenv_home ); __atoe( path ); dbhome = path; #else dbhome = mdb->mi_dbenv_home; #endif Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "dbenv_open(%s).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, 0); flags = mdb->mi_dbenv_flags; if ( slapMode & SLAP_TOOL_QUICK ) flags |= MDB_NOSYNC|MDB_WRITEMAP; if ( slapMode & SLAP_TOOL_READONLY) flags |= MDB_RDONLY; rc = mdb_env_open( mdb->mi_dbenv, dbhome, flags, mdb->mi_dbenv_mode ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). " "Restore from backup!\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } rc = mdb_txn_begin( mdb->mi_dbenv, NULL, flags & MDB_RDONLY, &txn ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). " "Restore from backup!\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } /* open (and create) main databases */ for( i = 0; mdmi_databases[i].bv_val; i++ ) { flags = MDB_INTEGERKEY; if( i == MDB_ID2ENTRY ) { if ( !(slapMode & (SLAP_TOOL_READMAIN|SLAP_TOOL_READONLY) )) flags |= MDB_CREATE; } else { if ( i == MDB_DN2ID ) flags |= MDB_DUPSORT; if ( !(slapMode & SLAP_TOOL_READONLY) ) flags |= MDB_CREATE; } rc = mdb_dbi_open( txn, mdmi_databases[i].bv_val, flags, &mdb->mi_dbis[i] ); if ( rc != 0 ) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " "mdb_dbi_open(%s/%s) failed: %s (%d).", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, mdmi_databases[i].bv_val, mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg, 0, 0 ); goto fail; } if ( i == MDB_ID2ENTRY ) mdb_set_compare( txn, mdb->mi_dbis[i], mdb_id_compare ); else if ( i == MDB_DN2ID ) { MDB_cursor *mc; MDB_val key, data; ID id; mdb_set_dupsort( txn, mdb->mi_dbis[i], mdb_dup_compare ); /* check for old dn2id format */ rc = mdb_cursor_open( txn, mdb->mi_dbis[i], &mc ); /* first record is always ID 0 */ rc = mdb_cursor_get( mc, &key, &data, MDB_FIRST ); if ( rc == 0 ) { rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT ); if ( rc == 0 ) { int len; unsigned char *ptr; ptr = data.mv_data; len = (ptr[0] & 0x7f) << 8 | ptr[1]; if (data.mv_size < 2*len + 4 + 2*sizeof(ID)) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": DN index needs upgrade, " "run \"slapindex entryDN\".", be->be_suffix[0].bv_val ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg, 0, 0 ); if ( !(slapMode & SLAP_TOOL_READMAIN )) rc = LDAP_OTHER; mdb->mi_flags |= MDB_NEED_UPGRADE; } } } mdb_cursor_close( mc ); if ( rc == LDAP_OTHER ) goto fail; } } rc = mdb_ad_read( mdb, txn ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } /* slapcat doesn't need indexes. avoid a failure if * a configured index wasn't created yet. */ if ( !(slapMode & SLAP_TOOL_READONLY) ) { rc = mdb_attr_dbs_open( be, txn, cr ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } } rc = mdb_txn_commit(txn); if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database %s: " "txn_commit failed: %s (%d)\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } /* monitor setup */ rc = mdb_monitor_db_open( be ); if ( rc != 0 ) { goto fail; } mdb->mi_flags |= MDB_IS_OPEN; return 0; fail: mdb_db_close( be, NULL ); return rc; }
static int mdb_db_open( BackendDB *be, ConfigReply *cr ) { int rc, i; struct mdb_info *mdb = (struct mdb_info *) be->be_private; struct stat stat1; uint32_t flags; char *dbhome; MDB_txn *txn; if ( be->be_suffix == NULL ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": need suffix.\n" ); return -1; } Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(mdb_db_open) ": \"%s\"\n", be->be_suffix[0].bv_val ); /* Check existence of dbenv_home. Any error means trouble */ rc = stat( mdb->mi_dbenv_home, &stat1 ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "cannot access database directory \"%s\" (%d).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, errno ); return -1; } /* mdb is always clean */ be->be_flags |= SLAP_DBFLAG_CLEAN; rc = mdb_env_create( &mdb->mi_dbenv ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_create failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } mdb_env_set_userctx(mdb->mi_dbenv, mdb); if ( mdb->mi_readers ) { rc = mdb_env_set_maxreaders( mdb->mi_dbenv, mdb->mi_readers ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxreaders failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } } rc = mdb_env_set_mapsize( mdb->mi_dbenv, mdb->mi_mapsize ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_mapsize failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } rc = mdb_env_set_maxdbs( mdb->mi_dbenv, MDB_INDICES ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxdbs failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } #ifdef MDBX_LIFORECLAIM #if MDBX_MODE_ENABLED rc = mdbx_env_set_syncbytes( mdb->mi_dbenv, mdb->mi_txn_cp_kbyte * 1024ul); #else rc = mdb_env_set_syncbytes( mdb->mi_dbenv, mdb->mi_txn_cp_kbyte * 1024ul); #endif /* MDBX_MODE_ENABLED */ if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_sync_threshold failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } #if MDBX_MODE_ENABLED mdbx_env_set_oomfunc( mdb->mi_dbenv, mdb_oom_handler ); #else mdb_env_set_oomfunc( mdb->mi_dbenv, mdb_oom_handler ); #endif /* MDBX_MODE_ENABLED */ if ( (slapMode & SLAP_SERVER_MODE) && SLAP_MULTIMASTER(be) && ((MDBX_OOM_YIELD & mdb->mi_oom_flags) == 0 || mdb->mi_renew_lag == 0)) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " "for properly operation in multi-master mode" " 'oom-handler yield' and 'dreamcatcher' are recommended", be->be_suffix[0].bv_val ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg ); } #endif /* MDBX_LIFORECLAIM */ dbhome = mdb->mi_dbenv_home; Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "dbenv_open(%s).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home); flags = mdb->mi_dbenv_flags; #ifdef MDBX_PAGEPERTURB if (reopenldap_mode_check()) flags |= MDBX_PAGEPERTURB; #endif if ( slapMode & SLAP_TOOL_QUICK ) flags |= MDB_NOSYNC|MDB_WRITEMAP; if ( slapMode & SLAP_TOOL_READONLY) flags |= MDB_RDONLY; rc = mdb_env_open( mdb->mi_dbenv, dbhome, flags, mdb->mi_dbenv_mode ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). " "Restore from backup!\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } rc = mdb_txn_begin( mdb->mi_dbenv, NULL, flags & MDB_RDONLY, &txn ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened: %s (%d). " "Restore from backup!\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } /* open (and create) main databases */ for( i = 0; mdmi_databases[i].bv_val; i++ ) { flags = MDB_INTEGERKEY; if( i == MDB_ID2ENTRY ) { if ( !(slapMode & (SLAP_TOOL_READMAIN|SLAP_TOOL_READONLY) )) flags |= MDB_CREATE; } else { if ( i == MDB_DN2ID ) flags |= MDB_DUPSORT; if ( !(slapMode & SLAP_TOOL_READONLY) ) flags |= MDB_CREATE; } rc = mdb_dbi_open( txn, mdmi_databases[i].bv_val, flags, &mdb->mi_dbis[i] ); if ( rc != 0 ) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " "mdb_dbi_open(%s/%s) failed: %s (%d).", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, mdmi_databases[i].bv_val, mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg ); goto fail; } if ( i == MDB_ID2ENTRY ) mdb_set_compare( txn, mdb->mi_dbis[i], mdb_id_compare ); else if ( i == MDB_DN2ID ) { MDB_cursor *mc; MDB_val key, data; mdb_set_dupsort( txn, mdb->mi_dbis[i], mdb_dup_compare ); /* check for old dn2id format */ rc = mdb_cursor_open( txn, mdb->mi_dbis[i], &mc ); /* first record is always ID 0 */ rc = mdb_cursor_get( mc, &key, &data, MDB_FIRST ); if ( rc == 0 ) { rc = mdb_cursor_get( mc, &key, &data, MDB_NEXT ); if ( rc == 0 ) { int len; unsigned char *ptr; ptr = data.mv_data; len = (ptr[0] & 0x7f) << 8 | ptr[1]; if (data.mv_size < 2*len + 4 + 2*sizeof(ID)) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": DN index needs upgrade, " "run \"slapindex entryDN\".", be->be_suffix[0].bv_val ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg ); if ( !(slapMode & SLAP_TOOL_READMAIN )) rc = LDAP_OTHER; mdb->mi_flags |= MDB_NEED_UPGRADE; } } } mdb_cursor_close( mc ); if ( rc == LDAP_OTHER ) goto fail; } } rc = mdb_ad_read( mdb, txn ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } /* slapcat doesn't need indexes. avoid a failure if * a configured index wasn't created yet. */ if ( !(slapMode & SLAP_TOOL_READONLY) ) { rc = mdb_attr_dbs_open( be, txn, cr ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } } rc = mdb_txn_commit(txn); if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database %s: " "txn_commit failed: %s (%d)\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } /* monitor setup */ rc = mdb_monitor_db_open( be ); if ( rc != 0 ) { goto fail; } mdb->mi_flags |= MDB_IS_OPEN; return 0; fail: mdb_db_close( be, NULL ); return rc; }
static int mdb_db_open( BackendDB *be, ConfigReply *cr ) { int rc, i; struct mdb_info *mdb = (struct mdb_info *) be->be_private; struct stat stat1; uint32_t flags; char *dbhome; MDB_txn *txn; if ( be->be_suffix == NULL ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": need suffix.\n", 1, 0, 0 ); return -1; } Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(mdb_db_open) ": \"%s\"\n", be->be_suffix[0].bv_val, 0, 0 ); /* Check existence of dbenv_home. Any error means trouble */ rc = stat( mdb->mi_dbenv_home, &stat1 ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "cannot access database directory \"%s\" (%d).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, errno ); return -1; } /* mdb is always clean */ be->be_flags |= SLAP_DBFLAG_CLEAN; rc = mdb_env_create( &mdb->mi_dbenv ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_create failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } if ( mdb->mi_readers ) { rc = mdb_env_set_maxreaders( mdb->mi_dbenv, mdb->mi_readers ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxreaders failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } } rc = mdb_env_set_mapsize( mdb->mi_dbenv, mdb->mi_mapsize ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_mapsize failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } rc = mdb_env_set_maxdbs( mdb->mi_dbenv, MDB_INDICES ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "mdb_env_set_maxdbs failed: %s (%d).\n", be->be_suffix[0].bv_val, mdb_strerror(rc), rc ); goto fail; } #ifdef HAVE_EBCDIC strcpy( path, mdb->mi_dbenv_home ); __atoe( path ); dbhome = path; #else dbhome = mdb->mi_dbenv_home; #endif Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_db_open) ": database \"%s\": " "dbenv_open(%s).\n", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, 0); flags = mdb->mi_dbenv_flags; if ( slapMode & SLAP_TOOL_QUICK ) flags |= MDB_NOSYNC; if ( slapMode & SLAP_TOOL_READONLY) flags |= MDB_RDONLY; rc = mdb_env_open( mdb->mi_dbenv, dbhome, flags, mdb->mi_dbenv_mode ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened, err %d. " "Restore from backup!\n", be->be_suffix[0].bv_val, rc, 0 ); goto fail; } rc = mdb_txn_begin( mdb->mi_dbenv, NULL, 0, &txn ); if ( rc ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": database \"%s\" cannot be opened, err %d. " "Restore from backup!\n", be->be_suffix[0].bv_val, rc, 0 ); goto fail; } /* open (and create) main databases */ for( i = 0; mdmi_databases[i].bv_val; i++ ) { flags = MDB_INTEGERKEY; if( i == MDB_ID2ENTRY ) { if ( !(slapMode & (SLAP_TOOL_READMAIN|SLAP_TOOL_READONLY) )) flags |= MDB_CREATE; } else { if ( i == MDB_DN2ID ) flags |= MDB_DUPSORT; if ( !(slapMode & SLAP_TOOL_READONLY) ) flags |= MDB_CREATE; } rc = mdb_open( txn, mdmi_databases[i].bv_val, flags, &mdb->mi_dbis[i] ); if ( rc != 0 ) { snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " "mdb_open(%s/%s) failed: %s (%d).", be->be_suffix[0].bv_val, mdb->mi_dbenv_home, mdmi_databases[i].bv_val, mdb_strerror(rc), rc ); Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(mdb_db_open) ": %s\n", cr->msg, 0, 0 ); goto fail; } if ( i == MDB_ID2ENTRY ) mdb_set_compare( txn, mdb->mi_dbis[i], mdb_id_compare ); else if ( i == MDB_DN2ID ) mdb_set_dupsort( txn, mdb->mi_dbis[i], mdb_dup_compare ); } rc = mdb_ad_read( mdb, txn ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } rc = mdb_attr_dbs_open( be, txn, cr ); if ( rc ) { mdb_txn_abort( txn ); goto fail; } rc = mdb_txn_commit(txn); if ( rc != 0 ) { goto fail; } /* monitor setup */ rc = mdb_monitor_db_open( be ); if ( rc != 0 ) { goto fail; } mdb->mi_flags |= MDB_IS_OPEN; return 0; fail: mdb_db_close( be, NULL ); return rc; }