/* * this function reads the db/DBVERSION file and check * 1) if the db version is supported, and * 2) if the db version requires some migration operation * * return: 0: supported * DBVERSION_NOT_SUPPORTED: not supported * * action: 0: nothing is needed * 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_version( struct ldbminfo *li, int *action ) { int value = 0; char *ldbmversion = NULL; char *dataversion = NULL; *action = 0; dbversion_read(li, li->li_directory, &ldbmversion, &dataversion); if (NULL == ldbmversion || '\0' == *ldbmversion) { slapi_ch_free_string(&dataversion); return 0; } 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, li->li_directory ); /* * 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; } if ( value & DBVERSION_UPGRADE_3_4 ) { dblayer_set_recovery_required(li); *action = DBVERSION_UPGRADE_3_4; } else if ( value & DBVERSION_UPGRADE_4_4 ) { dblayer_set_recovery_required(li); *action = DBVERSION_UPGRADE_4_4; } else if ( value & DBVERSION_UPGRADE_4_5 ) { dblayer_set_recovery_required(li); *action = DBVERSION_UPGRADE_4_5; } if (value & DBVERSION_RDN_FORMAT) { if (entryrdn_get_switch()) { /* nothing to do */ } else { *action |= DBVERSION_NEED_RDN2DN; } } else { if (entryrdn_get_switch()) { *action |= DBVERSION_NEED_DN2RDN; } else { /* nothing to do */ } } slapi_ch_free_string(&ldbmversion); slapi_ch_free_string(&dataversion); return 0; }
/* Stops a backend instance */ int ldbm_instance_stop(backend *be) { int rc; ldbm_instance *inst = (ldbm_instance *)be->be_instance_info; PR_Lock (be->be_state_lock); if (be->be_state != BE_STATE_STARTED) { slapi_log_err(SLAPI_LOG_WARNING, "ldbm_instance_stop", "Backend %s is in the wrong state - %d\n", inst ? inst->inst_name : "", be->be_state); PR_Unlock (be->be_state_lock); return 0; } rc = dblayer_instance_close(be); be->be_state = BE_STATE_STOPPED; PR_Unlock (be->be_state_lock); cache_destroy_please(&inst->inst_cache, CACHE_TYPE_ENTRY); if (entryrdn_get_switch()) { /* subtree-rename: on */ cache_destroy_please(&inst->inst_dncache, CACHE_TYPE_DN); } return rc; }
int ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) { char *instance_name; struct ldbminfo *li = (struct ldbminfo *)arg; struct ldbm_instance *inst = NULL; parse_ldbm_instance_entry(entryBefore, &instance_name); inst = ldbm_instance_find_by_name(li, instance_name); if (inst == NULL) { LDAPDebug(LDAP_DEBUG_ANY, "ldbm: instance '%s' does not exist! (2)\n", instance_name, 0, 0); if (returntext) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "No ldbm instance exists with the name '%s' (2)\n", instance_name); } if (returncode) { *returncode = LDAP_UNWILLING_TO_PERFORM; } slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_ERROR; } LDAPDebug(LDAP_DEBUG_ANY, "ldbm: removing '%s'.\n", instance_name, 0, 0); cache_destroy_please(&inst->inst_cache, CACHE_TYPE_ENTRY); if (entryrdn_get_switch()) { /* subtree-rename: on */ cache_destroy_please(&inst->inst_dncache, CACHE_TYPE_DN); } { struct ldbminfo *li = (struct ldbminfo *) inst->inst_be->be_database->plg_private; dblayer_private *priv = (dblayer_private*) li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; if(pEnv) { PRDir *dirhandle = NULL; char inst_dir[MAXPATHLEN*2]; char *inst_dirp = NULL; if (inst->inst_dir_name == NULL){ dblayer_get_instance_data_dir(inst->inst_be); } inst_dirp = dblayer_get_full_inst_dir(li, inst, inst_dir, MAXPATHLEN*2); if (NULL != inst_dirp) { dirhandle = PR_OpenDir(inst_dirp); /* the db dir instance may have been removed already */ if (dirhandle) { PRDirEntry *direntry = NULL; char *dbp = NULL; char *p = NULL; while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT|PR_SKIP_DOT_DOT))) { int rc; if (!direntry->name) break; dbp = PR_smprintf("%s/%s", inst_dirp, direntry->name); if (NULL == dbp) { LDAPDebug (LDAP_DEBUG_ANY, "ldbm_instance_post_delete_instance_entry_callback:" " failed to generate db path: %s/%s\n", inst_dirp, direntry->name, 0); break; } p = strstr(dbp, LDBM_FILENAME_SUFFIX); if (NULL != p && strlen(p) == strlen(LDBM_FILENAME_SUFFIX)) { rc = dblayer_db_remove(pEnv, dbp, 0); } else { rc = PR_Delete(dbp); } PR_ASSERT(rc == 0); PR_smprintf_free(dbp); } PR_CloseDir(dirhandle); } /* * When a backend was removed, the db instance directory * was removed as well (See also bz463774). * In case DB_RECOVER_FATAL is set in the DB open after * the removal (e.g., in restore), the logs in the transaction * logs are replayed and compared with the contents of the DB * files. At that time, if the db instance directory does not * exist, libdb returns FATAL error. To prevent the problem, * we have to leave the empty directory. (bz597375) * * PR_RmDir(inst_dirp); */ } /* non-null dirhandle */ if (inst_dirp != inst_dir) { slapi_ch_free_string(&inst_dirp); } } /* non-null pEnv */ } ldbm_instance_unregister_callbacks(inst); slapi_be_free(&inst->inst_be); ldbm_instance_destroy(inst); slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_OK; }
/* * 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; }
/* create the default indexes separately * (because when we're creating a new backend while the server is running, * the DSE needs to be pre-seeded first.) */ int ldbm_instance_create_default_indexes(backend *be) { Slapi_Entry *e; ldbm_instance *inst = (ldbm_instance *)be->be_instance_info; /* write the dse file only on the final index */ int flags = LDBM_INSTANCE_CONFIG_DONT_WRITE; /* * Always index (entrydn or entryrdn), parentid, objectclass, * subordinatecount, copiedFrom, and aci, * since they are used by some searches, replication and the * ACL routines. */ if (entryrdn_get_switch()) { /* subtree-rename: on */ e = ldbm_instance_init_config_entry(LDBM_ENTRYRDN_STR,"subtree", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); } else { e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); } e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry("objectclass","eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry("aci","pres", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); #if 0 /* don't need copiedfrom */ e = ldbm_instance_init_config_entry("copiedfrom","pres",0 ,0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); #endif e = ldbm_instance_init_config_entry(LDBM_NUMSUBORDINATES_STR,"pres", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry(SLAPI_ATTR_UNIQUEID,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* For MMR, we need this attribute (to replace use of dncomp in delete). */ e = ldbm_instance_init_config_entry(ATTR_NSDS5_REPLCONFLICT,"eq", "pres", 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* write the dse file only on the final index */ e = ldbm_instance_init_config_entry(SLAPI_ATTR_NSCP_ENTRYDN,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* ldbm_instance_config_add_index_entry(inst, 2, argv); */ e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT,"none", 0, 0, 0); attr_index_config( be, "ldbm index init", 0, e, 1, 0 ); slapi_entry_free(e); if (!entryrdn_get_noancestorid()) { /* * ancestorid is special, there is actually no such attr type * but we still want to use the attr index file APIs. */ e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR,"eq", 0, 0, 0); attr_index_config( be, "ldbm index init", 0, e, 1, 0 ); slapi_entry_free(e); } return 0; }