/* * adjust_idl_switch * if the current nsslapd-idl-switch is different from ldbmversion, * update the value of nsslapd-idl-switch (in LDBM_CONFIG_ENTRY) */ int adjust_idl_switch(char *ldbmversion, struct ldbminfo *li) { int rval = 0; li->li_flags |= LI_FORCE_MOD_CONFIG; if ((0 == PL_strncasecmp(ldbmversion, BDB_IMPL, strlen(BDB_IMPL))) || (0 == PL_strcmp(ldbmversion, LDBM_VERSION))) /* db: new idl */ { if (!idl_get_idl_new()) /* config: old idl */ { replace_ldbm_config_value(CONFIG_IDL_SWITCH, "new", li); LDAPDebug(LDAP_DEBUG_ANY, "Warning: Dbversion %s does not meet nsslapd-idl-switch: \"old\"; " "nsslapd-idl-switch is updated to \"new\"\n", ldbmversion, 0, 0); } } else if ((0 == strcmp(ldbmversion, LDBM_VERSION_OLD)) || (0 == PL_strcmp(ldbmversion, LDBM_VERSION_61)) || (0 == PL_strcmp(ldbmversion, LDBM_VERSION_62)) || (0 == strcmp(ldbmversion, LDBM_VERSION_60))) /* db: old */ { if (idl_get_idl_new()) /* config: new */ { replace_ldbm_config_value(CONFIG_IDL_SWITCH, "old", li); LDAPDebug(LDAP_DEBUG_ANY, "Warning: Dbversion %s does not meet nsslapd-idl-switch: \"new\"; " "nsslapd-idl-switch is updated to \"old\"\n", ldbmversion, 0, 0); } } else { LDAPDebug(LDAP_DEBUG_ANY, "Warning: Dbversion %s is not supported\n", ldbmversion, 0, 0); rval = 1; } /* ldbminfo is a common resource; should clean up when the job is done */ li->li_flags &= ~LI_FORCE_MOD_CONFIG; return rval; }
static int dbverify_ext( ldbm_instance *inst, int verbose ) { char dbdir[MAXPATHLEN]; char *filep = NULL; PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; DB *dbp = NULL; size_t tmplen = 0; size_t filelen = 0; int rval = 1; int rval_main = 0; struct ldbminfo *li = inst->inst_li; dblayer_private *priv = (dblayer_private*)li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; dbdir[sizeof(dbdir)-1] = '\0'; PR_snprintf(dbdir, sizeof(dbdir), "%s/%s", inst->inst_parent_dir_name, inst->inst_dir_name); if ('\0' != dbdir[sizeof(dbdir)-1]) /* overflown */ { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", inst->inst_parent_dir_name, inst->inst_dir_name); return 1; } tmplen = strlen(dbdir); filep = dbdir + tmplen; filelen = sizeof(dbdir) - tmplen; /* run dbverify on each each db file */ dirhandle = PR_OpenDir(dbdir); if (! dirhandle) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "PR_OpenDir (%s) failed (%d): %s\n", dbdir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return 1; } while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { /* struct attrinfo *ai = NULL; */ dbp = NULL; if (!direntry->name) { break; } if (!strstr(direntry->name, LDBM_FILENAME_SUFFIX)) /* non db file */ { continue; } if (sizeof(direntry->name) + 2 > filelen) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "db path too long: %s/%s\n", dbdir, direntry->name); continue; } PR_snprintf(filep, filelen, "/%s", direntry->name); rval = db_create(&dbp, pEnv->dblayer_DB_ENV, 0); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to create id2entry db file %d\n", rval); return rval; } #define VLVPREFIX "vlv#" if (0 != strncmp(direntry->name, ID2ENTRY, strlen(ID2ENTRY))) { struct attrinfo *ai = NULL; char *p = NULL; p = strstr(filep, LDBM_FILENAME_SUFFIX); /* since already checked, it must have it */ if(p) *p = '\0'; ainfo_get( inst->inst_be, filep+1, &ai ); if(p) *p = '.'; if (ai->ai_key_cmp_fn) { dbp->app_private = (void *)ai->ai_key_cmp_fn; dbp->set_bt_compare(dbp, dblayer_bt_compare); } if (idl_get_idl_new()) { rval = dbp->set_pagesize(dbp, (priv->dblayer_index_page_size == 0) ? DBLAYER_INDEX_PAGESIZE : priv->dblayer_index_page_size); } else { rval = dbp->set_pagesize(dbp, (priv->dblayer_page_size == 0) ? DBLAYER_PAGESIZE : priv->dblayer_page_size); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "DB verify", "Unable to set pagesize flags to db (%d)\n", rval); return rval; } if (0 == strncmp(direntry->name, VLVPREFIX, strlen(VLVPREFIX))) { rval = dbp->set_flags(dbp, DB_RECNUM); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set RECNUM flag to vlv index (%d)\n", rval); return rval; } } else if (idl_get_idl_new()) { rval = dbp->set_flags(dbp, DB_DUP | DB_DUPSORT); if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set DUP flags to db (%d)\n", rval); return rval; } if (ai->ai_dup_cmp_fn) { /* If set, use the special dup compare callback */ rval = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn); } else { rval = dbp->set_dup_compare(dbp, idl_new_compare_dups); } if (0 != rval) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "Unable to set dup_compare to db (%d)\n", rval); return rval; } } } #undef VLVPREFIX rval = dbp->verify(dbp, dbdir, NULL, NULL, 0); if (0 == rval) { if (verbose) { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "%s: ok\n", dbdir); } } else { slapi_log_err(SLAPI_LOG_ERR, "dbverify_ext", "verify failed(%d): %s\n", rval, dbdir); } rval_main |= rval; *filep = '\0'; } PR_CloseDir(dirhandle); return rval_main; }
/* * this function reads the db/<inst>/DBVERSION file and check * 1) if the db version is supported, and * 2) if the db version matches the idl configuration * (nsslapd-idl-switch: new|old) * note that old idl will disappear from the next major update (6.5? 7.0?) * * return: 0: supported and the version matched * DBVERSION_NEED_IDL_OLD2NEW: old->new uprev is needed * (used in convindices) * DBVERSION_NEED_IDL_NEW2OLD: old db is found, for the new idl config * DBVERSION_NOT_SUPPORTED: not supported * * DBVERSION_UPGRADE_3_4: db3->db4 uprev is needed * DBVERSION_UPGRADE_4_4: db4->db4 uprev is needed * DBVERSION_UPGRADE_4_5: db4->db uprev is needed */ int check_db_inst_version( ldbm_instance *inst ) { int value = 0; char *ldbmversion = NULL; char *dataversion = NULL; int rval = 0; char inst_dir[MAXPATHLEN*2]; char *inst_dirp = NULL; inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst, inst_dir, MAXPATHLEN*2); dbversion_read(inst->inst_li, inst_dirp, &ldbmversion, &dataversion); if (NULL == ldbmversion || '\0' == *ldbmversion) { return rval; } value = lookup_dbversion( ldbmversion, DBVERSION_TYPE | DBVERSION_ACTION ); if ( !value ) { LDAPDebug( LDAP_DEBUG_ANY, "ERROR: Database version mismatch (expecting " "'%s' but found '%s' in directory %s)\n", LDBM_VERSION, ldbmversion, inst->inst_dir_name ); /* * A non-zero return here will cause slapd to exit during startup. */ slapi_ch_free_string(&ldbmversion); slapi_ch_free_string(&dataversion); return DBVERSION_NOT_SUPPORTED; } /* recognize the difference between an old/new database regarding idl * (406922) */ if (idl_get_idl_new() && !(value & DBVERSION_NEW_IDL) ) { rval |= DBVERSION_NEED_IDL_OLD2NEW; } else if (!idl_get_idl_new() && !(value & DBVERSION_OLD_IDL) ) { rval |= DBVERSION_NEED_IDL_NEW2OLD; } if ( value & DBVERSION_UPGRADE_3_4 ) { rval |= DBVERSION_UPGRADE_3_4; } else if ( value & DBVERSION_UPGRADE_4_4 ) { rval |= DBVERSION_UPGRADE_4_4; } else if ( value & DBVERSION_UPGRADE_4_5 ) { rval |= DBVERSION_UPGRADE_4_5; } if (value & DBVERSION_RDN_FORMAT) { if (entryrdn_get_switch()) { /* nothing to do */ } else { rval |= DBVERSION_NEED_RDN2DN; } } else { if (entryrdn_get_switch()) { rval |= DBVERSION_NEED_DN2RDN; } else { /* nothing to do */ } } if (inst_dirp != inst_dir) slapi_ch_free_string(&inst_dirp); slapi_ch_free_string(&ldbmversion); slapi_ch_free_string(&dataversion); return rval; }
static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv, ldbm_instance *inst) { int retval = 0; int retval_cleanup = 0; DB *source_file = NULL; DB *destination_file = NULL; DBC *source_cursor = NULL; DBTYPE dbtype = 0; PRUint32 dbflags = 0; PRUint32 dbpagesize = 0; int cursor_flag = 0; int finished = 0; int mode = 0; char *p = NULL; slapi_log_err(SLAPI_LOG_TRACE, "dblayer_copy_file_keybykey", "=>\n"); if (!env) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Out of memory\n"); goto error; } if (priv->dblayer_file_mode) mode = priv->dblayer_file_mode; dblayer_set_env_debugging(env, priv); /* Open the source file */ retval = db_create(&source_file, env, 0); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Create error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = (source_file->open)(source_file, NULL, source_file_name, NULL, DB_UNKNOWN, DB_RDONLY, 0); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Open error %d: %s\n", retval, db_strerror(retval)); goto error; } /* Get the info we need from the source file */ retval = source_file->get_flags(source_file, &dbflags); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "get_flags error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = source_file->get_type(source_file, &dbtype); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "get_type error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = source_file->get_pagesize(source_file, &dbpagesize); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "get_pagesize error %d: %s\n", retval, db_strerror(retval)); goto error; } /* Open the destination file * and make sure that it has the correct page size, the correct access method, and the correct flags (dup etc) */ retval = db_create(&destination_file, env, 0); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Create error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = destination_file->set_flags(destination_file,dbflags); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Set_flags error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = destination_file->set_pagesize(destination_file,dbpagesize); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "set_pagesize error %d: %s\n", retval, db_strerror(retval)); goto error; } /* TEL 20130412: Make sure to set the dup comparison function if needed. * We key our decision off of the presence of new IDL and dup flags on * the source database. This is similar dblayer_open_file, except that * we don't have the attribute info index mask for VLV. That should be OK * since the DB_DUP and DB_DUPSORT flags wouldn't have been toggled on * unless they passed the check on the source. */ /* Entryrdn index has its own dup compare function */ if ((p = PL_strcasestr(source_file_name, LDBM_ENTRYRDN_STR)) && (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) { /* entryrdn.db */ struct attrinfo *ai = NULL; if (NULL == inst) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "(entryrdn) - " "dup_cmp_fn cannot be retrieved since inst is NULL.\n"); goto error; } ainfo_get(inst->inst_be, LDBM_ENTRYRDN_STR, &ai); if (ai->ai_dup_cmp_fn) { /* If set, use the special dup compare callback */ retval = destination_file->set_dup_compare(destination_file, ai->ai_dup_cmp_fn); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "(entryrdn) - set_dup_compare error %d: %s\n", retval, db_strerror(retval)); goto error; } } } else if (idl_get_idl_new() && (dbflags & DB_DUP) && (dbflags & DB_DUPSORT)) { retval = destination_file->set_dup_compare(destination_file, idl_new_compare_dups); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "set_dup_compare error %d: %s\n", retval, db_strerror(retval)); goto error; } } retval = (destination_file->open)(destination_file, NULL, destination_file_name, NULL, dbtype, DB_CREATE | DB_EXCL, mode); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Open error %d: %s\n", retval, db_strerror(retval)); goto error; } /* Open a cursor on the source file */ retval = source_file->cursor(source_file,NULL,&source_cursor,0); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Create cursor error %d: %s\n", retval, db_strerror(retval)); goto error; } /* Seek to the first key */ cursor_flag = DB_FIRST; /* Loop seeking to the next key until they're all done */ while (!finished) { DBT key = {0}; DBT data = {0}; retval = source_cursor->c_get(source_cursor, &key, &data, cursor_flag); if (retval) { /* DB_NOTFOUND is expected when we find the end, log a message for any other error. * In either case, set finished=1 so we can hop down and close the cursor. */ if ( DB_NOTFOUND != retval ) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "c_get error %d: %s\n", retval, db_strerror(retval)); goto error; } retval = 0; /* DB_NOTFOUND was OK... */ finished = 1; } else { /* For each key, insert into the destination file */ retval = destination_file->put(destination_file, NULL, &key, &data, 0); if (retval) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "put error %d: %s\n", retval, db_strerror(retval)); goto error; } cursor_flag = DB_NEXT; } } error: /* Close the cursor */ if (source_cursor) { retval_cleanup = source_cursor->c_close(source_cursor); if (retval_cleanup) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Close cursor error %d: %s\n", retval_cleanup, db_strerror(retval_cleanup)); retval += retval_cleanup; } } /* Close the source file */ if (source_file) { retval_cleanup = source_file->close(source_file,0); source_file = NULL; if (retval_cleanup) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Close error %d: %s\n", retval_cleanup, db_strerror(retval_cleanup)); retval += retval_cleanup; } } /* Close the destination file */ if (destination_file) { retval_cleanup = destination_file->close(destination_file,0); destination_file = NULL; if (retval_cleanup) { slapi_log_err(SLAPI_LOG_ERR, "dblayer_copy_file_keybykey", "Close error %d: %s\n", retval_cleanup, db_strerror(retval_cleanup)); retval += retval_cleanup; } } slapi_log_err(SLAPI_LOG_TRACE, "dblayer_copy_file_keybykey", "<=\n"); return retval; }