diff options
Diffstat (limited to 'ldap/servers/slapd/back-ldbm/dblayer.c')
-rw-r--r-- | ldap/servers/slapd/back-ldbm/dblayer.c | 155 |
1 files changed, 105 insertions, 50 deletions
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index 7cf407c4..e6d13faa 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -650,10 +650,6 @@ int dblayer_terminate(struct ldbminfo *li) } slapi_ch_free_string(&priv->dblayer_log_directory); - /* no need to release dblayer_home_directory, - * which is one of dblayer_data_directories */ - charray_free(priv->dblayer_data_directories); - priv->dblayer_data_directories = NULL; PR_DestroyCondVar(priv->thread_count_cv); priv->thread_count_cv = NULL; PR_DestroyLock(priv->thread_count_lock); @@ -1191,8 +1187,8 @@ dblayer_make_env(struct dblayer_private_env **env, struct ldbminfo *li) Object *inst_obj; ldbm_instance *inst = NULL; - pEnv = - (struct dblayer_private_env *) PR_Calloc(1, sizeof(dblayer_private_env)); + pEnv = (struct dblayer_private_env *)slapi_ch_calloc(1, + sizeof(dblayer_private_env)); if ((ret = db_env_create(&pEnv->dblayer_DB_ENV, 0)) != 0) { LDAPDebug(LDAP_DEBUG_ANY, @@ -1214,7 +1210,6 @@ dblayer_make_env(struct dblayer_private_env **env, struct ldbminfo *li) dblayer_dump_config_tracing(priv); /* set data dir to avoid having absolute paths in the transaction log */ - priv->dblayer_data_directories = NULL; for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj; inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) @@ -1226,7 +1221,7 @@ dblayer_make_env(struct dblayer_private_env **env, struct ldbminfo *li) inst->inst_parent_dir_name)) { charray_add(&(priv->dblayer_data_directories), - inst->inst_parent_dir_name); + slapi_ch_strdup(inst->inst_parent_dir_name)); } } } @@ -1260,28 +1255,35 @@ dblayer_make_env(struct dblayer_private_env **env, struct ldbminfo *li) return ret; } +static void +dblayer_free_env(struct dblayer_private_env **env) +{ + if (NULL == env || NULL == *env) { + return; + } + if ((*env)->dblayer_env_lock) { + PR_DestroyRWLock((*env)->dblayer_env_lock); + (*env)->dblayer_env_lock = NULL; + } + slapi_ch_free((void **)env); + return; +} + /* generate an absolute path if the given instance dir is not. */ char * dblayer_get_full_inst_dir(struct ldbminfo *li, ldbm_instance *inst, char *buf, int buflen) { - char *parent_dir; - int mylen; + char *parent_dir = NULL; + int mylen = 0; if (!inst) return NULL; - if (inst->inst_parent_dir_name) + if (inst->inst_parent_dir_name) /* e.g., /var/lib/dirsrv/slapd-ID/db */ { parent_dir = inst->inst_parent_dir_name; - if (inst->inst_parent_dir_name) - { - mylen = strlen(parent_dir) + strlen(inst->inst_dir_name) + 2; - } - else - { - mylen = strlen(parent_dir) + 1; - } + mylen = strlen(parent_dir) + 1; } else { @@ -1295,7 +1297,7 @@ dblayer_get_full_inst_dir(struct ldbminfo *li, ldbm_instance *inst, } - if (inst->inst_dir_name) + if (inst->inst_dir_name) /* e.g., userRoot */ { mylen += strlen(inst->inst_dir_name) + 2; if (!buf || mylen > buflen) @@ -1443,7 +1445,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) LDAPDebug(LDAP_DEBUG_ANY, "Error: DB directory is not specified.\n", 0, 0, 0); return -1; - } + } PR_Lock(li->li_config_mutex); priv->dblayer_home_directory = li->li_directory; /* nsslapd-directory */ priv->dblayer_cachesize = li->li_dbcachesize; @@ -1513,6 +1515,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) } } + dblayer_free_env(&priv->dblayer_env); priv->dblayer_env = pEnv; open_flags = DB_CREATE | DB_INIT_MPOOL | DB_THREAD; @@ -1583,6 +1586,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) "ERROR -- Failed to create DBENV (returned: %d).\n", return_value, 0, 0); } + dblayer_free_env(&priv->dblayer_env); priv->dblayer_env = pEnv; } @@ -1647,6 +1651,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) "mmap in opening database environment (recovery mode) " "failed trying to allocate %lu bytes. (OS err %d - %s)\n", li->li_dbcachesize, return_value, dblayer_strerror(return_value)); + dblayer_free_env(&priv->dblayer_env); priv->dblayer_env = CATASTROPHIC; } else { LDAPDebug(LDAP_DEBUG_ANY, "Database Recovery Process FAILED. " @@ -1667,6 +1672,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) return_value, 0, 0); return return_value; } + dblayer_free_env(&priv->dblayer_env); priv->dblayer_env = pEnv; dblayer_set_data_dir(priv, pEnv, priv->dblayer_data_directories); } @@ -1738,6 +1744,7 @@ int dblayer_start(struct ldbminfo *li, int dbmode) "mmap in opening database environment " "failed trying to allocate %d bytes. (OS err %lu - %s)\n", li->li_dbcachesize, return_value, dblayer_strerror(return_value)); + dblayer_free_env(&priv->dblayer_env); priv->dblayer_env = CATASTROPHIC; } else { LDAPDebug(LDAP_DEBUG_ANY, @@ -1819,7 +1826,7 @@ int dblayer_instance_start(backend *be, int mode) struct dblayer_private_env *pEnv; char inst_dir[MAXPATHLEN]; char *inst_dirp = NULL; - int return_value; + int return_value = -1; priv = (dblayer_private*)li->li_dblayer_private; pEnv = priv->dblayer_env; @@ -1827,7 +1834,7 @@ int dblayer_instance_start(backend *be, int mode) LDAPDebug(LDAP_DEBUG_ANY, "instance %s: dbenv is not available (0x%x).\n", inst?inst->inst_name:"unknown", pEnv, 0); - return -1; + return return_value; } if (NULL != inst->inst_id2entry) { @@ -1841,7 +1848,7 @@ int dblayer_instance_start(backend *be, int mode) LDAPDebug(LDAP_DEBUG_ANY, "Error: unable to initialize attrcrypt system for %s\n", inst->inst_name, 0, 0); - return -1; + return return_value; } /* Get the name of the directory that holds index files @@ -1849,7 +1856,7 @@ int dblayer_instance_start(backend *be, int mode) if (dblayer_get_instance_data_dir(be) != 0) { /* Problem getting the name of the directory that holds the * index files for this instance. */ - return -1; + return return_value; } inst_dirp = dblayer_get_full_inst_dir(li, inst, inst_dir, MAXPATHLEN); @@ -1902,19 +1909,23 @@ int dblayer_instance_start(backend *be, int mode) return_value = -1; goto errout; } - if (rval & DBVERSION_NEED_IDL_OLD2NEW) + else if (rval & DBVERSION_NEED_DN2RDN) { - LDAPDebug(LDAP_DEBUG_ANY, - "Instance %s: idl-switch is new while db idl format is " - "old, modify nsslapd-idl-switch in dse.ldif to old\n", - inst->inst_name, 0, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, + "%s is on, while the instance %s is in the DN format. " + "Please run dn2rdn to convert the database format.\n", + CONFIG_ENTRYRDN_SWITCH, inst->inst_name); + return_value = -1; + goto errout; } - if (rval & DBVERSION_NEED_IDL_NEW2OLD) + else if (rval & DBVERSION_NEED_RDN2DN) { - LDAPDebug(LDAP_DEBUG_ANY, - "Instance %s: idl-switch is old while db idl format is " - "new, modify nsslapd-idl-switch in dse.ldif to new\n", - inst->inst_name, 0, 0); + LDAPDebug2Args(LDAP_DEBUG_ANY, + "%s is off, while the instance %s is in the RDN " + "format. Please change the value to on in dse.ldif.\n", + CONFIG_ENTRYRDN_SWITCH, inst->inst_name); + return_value = -1; + goto errout; } /* record the dataversion */ @@ -1933,6 +1944,26 @@ int dblayer_instance_start(backend *be, int mode) return_value = -1; goto errout; } + /** + if (rval & DBVERSION_NEED_IDL_OLD2NEW) + { + LDAPDebug(LDAP_DEBUG_ANY, + "Instance %s: idl-switch is new while db idl format is " + "old, modify nsslapd-idl-switch in dse.ldif to old\n", + inst->inst_name, 0, 0); + return_value = -1; + goto errout; + } + else if (rval & DBVERSION_NEED_IDL_NEW2OLD) + { + LDAPDebug(LDAP_DEBUG_ANY, + "Instance %s: idl-switch is old while db idl format is " + "new, modify nsslapd-idl-switch in dse.ldif to new\n", + inst->inst_name, 0, 0); + return_value = -1; + goto errout; + } + **/ } } else { /* The dbversion file didn't exist, so we'll create one. */ @@ -2472,8 +2503,7 @@ int dblayer_instance_close(backend *be) slapi_ch_free_string(&inst_dirp); } PR_DestroyRWLock(inst->import_env->dblayer_env_lock); - PR_Free((void *)inst->import_env); - inst->import_env = NULL; + slapi_ch_free((void **)&inst->import_env); } else { be->be_state = BE_STATE_STOPPED; } @@ -2564,14 +2594,11 @@ int dblayer_post_close(struct ldbminfo *li, int dbmode) perfctrs_terminate(&priv->perf_private, priv->dblayer_env->dblayer_DB_ENV); } } - + /* Now release the db environment */ pEnv = priv->dblayer_env; return_value = pEnv->dblayer_DB_ENV->close(pEnv->dblayer_DB_ENV, 0); - PR_DestroyRWLock(priv->dblayer_env->dblayer_env_lock); - PR_Free((void *) priv->dblayer_env); - - priv->dblayer_env = NULL; /* pEnv is now garbage */ + dblayer_free_env(&priv->dblayer_env); /* pEnv is now garbage */ #if 0 /* DBDB do NOT remove the environment: bad, bad idea */ if (return_value == 0) { @@ -2607,6 +2634,14 @@ int dblayer_post_close(struct ldbminfo *li, int dbmode) && !priv->dblayer_bad_stuff_happened) { commit_good_database(priv); } + if (priv->dblayer_data_directories) { + /* dblayer_data_directories are set in dblayer_make_env via + * dblayer_start, which is paired with dblayer_close. */ + /* no need to release dblayer_home_directory, + * which is one of dblayer_data_directories */ + charray_free(priv->dblayer_data_directories); + priv->dblayer_data_directories = NULL; + } return return_value; } @@ -2767,10 +2802,12 @@ int dblayer_open_file(backend *be, char* indexname, int open_flag, struct attrin if (0 != return_value) goto out; - return_value = dbp->set_dup_compare( - dbp, - idl_new_compare_dups - ); + if (ai->ai_dup_cmp_fn) { + /* If set, use the special dup compare callback */ + return_value = dbp->set_dup_compare(dbp, ai->ai_dup_cmp_fn); + } else { + return_value = dbp->set_dup_compare(dbp, idl_new_compare_dups); + } if (0 != return_value) goto out; } @@ -4031,13 +4068,13 @@ static int commit_good_database(dblayer_private *priv) int return_value = 0; int num_bytes; - PR_snprintf(filename,sizeof(filename), "%s/guardian",priv->dblayer_home_directory); + PR_snprintf(filename,sizeof(filename), "%s/guardian", priv->dblayer_home_directory); prfd = PR_Open(filename, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, priv->dblayer_file_mode ); if (NULL == prfd) { - LDAPDebug( LDAP_DEBUG_ANY,"Fatal Error---Failed to write guardian file, database corruption possible" SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n", + LDAPDebug( LDAP_DEBUG_ANY,"Fatal Error---Failed to write guardian file %s, database corruption possible" SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n", filename, PR_GetError(), slapd_pr_strerror(PR_GetError()) ); return -1; } @@ -5441,7 +5478,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; PRFileInfo info; - ldbm_instance *inst; + ldbm_instance *inst = NULL; int seen_logfiles = 0; /* Tells us if we restored any logfiles */ int is_a_logfile = 0; int dbmode; @@ -5694,7 +5731,25 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char * { dbmode = DBLAYER_RESTORE_MODE; } - else + else if (action & DBVERSION_NEED_DN2RDN) + { + LDAPDebug2Args(LDAP_DEBUG_ANY, + "%s is on, while the instance %s is in the DN format. " + "Please run dn2rdn to convert the database format.\n", + CONFIG_ENTRYRDN_SWITCH, inst->inst_name); + return_value = -1; + goto error_out; + } + else if (action & DBVERSION_NEED_RDN2DN) + { + LDAPDebug2Args(LDAP_DEBUG_ANY, + "%s is off, while the instance %s is in the RDN format. " + "Please change the value to on in dse.ldif.\n", + CONFIG_ENTRYRDN_SWITCH, inst->inst_name); + return_value = -1; + goto error_out; + } + else { dbmode = DBLAYER_RESTORE_NO_RECOVERY_MODE; } |