summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/back-ldbm/dblayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/servers/slapd/back-ldbm/dblayer.c')
-rw-r--r--ldap/servers/slapd/back-ldbm/dblayer.c155
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;
}