summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/back-ldbm
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-09-12 21:59:29 -0700
committerNoriko Hosoi <nhosoi@redhat.com>2010-09-13 10:06:51 -0700
commit80ce631a97977c273a56b5d4d7e99a7eaf109d57 (patch)
tree75207bb0b02a57485d87efedabfcc2fe243eeb06 /ldap/servers/slapd/back-ldbm
parent2a25e6518f6e2bd83dd4750bf023d332edef2063 (diff)
downloadds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.gz
ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.xz
ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.zip
Bug 633168 - Share backend dbEnv with the replication changelog
https://bugzilla.redhat.com/show_bug.cgi?id=633168 Description: * cl5_api.c, cl5_api.h - fetches dbEnv from backend using slapi_back_get_info. - unused macros and DB helper functions and APIs are removed. * cl5_config.c - local changelog DB related config parameters are removed. * Added SLAPI_PLUGIN_BE_PRE_CLOSE_FN and SLAPI_PLUGIN_BE_POST_OPEN_FN to close changelog DB before dbEnv is closed and to open changelog DB after dbEnv is opened, respectively. * Added slapi APIs slapi_back_get_info and slapi_back_set_info to get/set the backend info. * back-ldbm - db2bak[.pl] and bak2db[.pl] backs up and restores the database files including changelog db. - changelog dir is backed up in <backupdir>/.repl_changelog_backup. - underlying implementation ldbm_back_get_info for slapi_back_get_info is added. * Added an upgrade script 81changelog.pl See also: http://directory.fedoraproject.org/wiki/Move_changelog
Diffstat (limited to 'ldap/servers/slapd/back-ldbm')
-rw-r--r--ldap/servers/slapd/back-ldbm/archive.c45
-rw-r--r--ldap/servers/slapd/back-ldbm/back-ldbm.h4
-rw-r--r--ldap/servers/slapd/back-ldbm/dblayer.c705
-rw-r--r--ldap/servers/slapd/back-ldbm/dblayer.h4
-rw-r--r--ldap/servers/slapd/back-ldbm/import-threads.c37
-rw-r--r--ldap/servers/slapd/back-ldbm/init.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modify.c2
-rw-r--r--ldap/servers/slapd/back-ldbm/ldif2ldbm.c31
-rw-r--r--ldap/servers/slapd/back-ldbm/misc.c26
-rw-r--r--ldap/servers/slapd/back-ldbm/proto-back-ldbm.h5
10 files changed, 605 insertions, 258 deletions
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index edaa5edf..545a4b0c 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -151,7 +151,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
}
}
- /* now take down ALL BACKENDS */
+ /* now take down ALL BACKENDS and changelog */
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
inst = (ldbm_instance *)object_get_data(inst_obj);
@@ -167,6 +167,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
cache_clear(&inst->inst_dncache, CACHE_TYPE_DN);
}
}
+ plugin_call_plugins (pb, SLAPI_PLUGIN_BE_PRE_CLOSE_FN);
/* now we know nobody's using any of the backend instances, so we
* can shutdown the dblayer -- this closes all instances too.
* Use DBLAYER_RESTORE_MODE to prevent loss of perfctr memory.
@@ -246,7 +247,8 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
goto out;
}
}
- /* bring all backends back online */
+ /* bring all backends and changelog back online */
+ plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_OPEN_FN);
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
inst = (ldbm_instance *)object_get_data(inst_obj);
@@ -316,8 +318,6 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
directory = rel2abspath(rawdirectory);
if (stat(directory, &sbuf) == 0) {
- int baklen = 0;
-
if (slapd_comp_path(directory, li->li_directory) == 0) {
LDAPDebug(LDAP_DEBUG_ANY,
"db2archive: Cannot archive to the db directory.\n", 0, 0, 0);
@@ -329,9 +329,7 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
goto out;
}
- baklen = strlen(directory) + 5; /* ".bak\0" */
- dir_bak = slapi_ch_malloc(baklen);
- PR_snprintf(dir_bak, baklen, "%s.bak", directory);
+ dir_bak = slapi_ch_smprintf("%s.bak", directory);
LDAPDebug(LDAP_DEBUG_ANY, "db2archive: %s exists. Renaming to %s\n",
directory, dir_bak, 0);
if (task) {
@@ -442,22 +440,33 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
}
}
err:
- if (return_value != 0) {
- LDAPDebug(LDAP_DEBUG_ANY, "db2archive: Rename %s back to %s\n",
- dir_bak, directory, 0);
- if (task) {
- slapi_task_log_notice(task, "Rename %s back to %s",
- dir_bak, directory);
+ if (return_value) {
+ if (dir_bak) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "db2archive failed: renaming %s back to %s\n",
+ dir_bak, directory);
+ if (task) {
+ slapi_task_log_notice(task,
+ "db2archive failed: renaming %s back to %s",
+ dir_bak, directory);
+ }
+ } else {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "db2archive failed: removing %s\n", directory);
+ if (task) {
+ slapi_task_log_notice(task, "db2archive failed: removing %s",
+ directory);
+ }
}
ldbm_delete_dirs(directory);
- if (PR_SUCCESS != PR_Rename(dir_bak, directory)) {
+ if (dir_bak && (PR_SUCCESS != PR_Rename(dir_bak, directory))) {
PRErrorCode prerr = PR_GetError();
- LDAPDebug(LDAP_DEBUG_ANY,
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
"db2archive: Failed to rename \"%s\" to \"%s\".\n",
- dir_bak, directory, 0);
- LDAPDebug(LDAP_DEBUG_ANY,
+ dir_bak, directory);
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
- prerr, slapd_pr_strerror(prerr), 0);
+ prerr, slapd_pr_strerror(prerr));
if (task) {
slapi_task_log_notice(task,
"Failed to rename \"%s\" to \"%s\".",
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index f4a6f434..29d18458 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -844,4 +844,8 @@ typedef struct _back_search_result_set
/* Initial entryusn value */
#define INITIALUSN (PRUint64)(-1)
+/* changelog backup dir name
+ * starting with '.' to reduce the risk to match an ordinary backend name */
+#define CHANGELOG_BACKUPDIR ".repl_changelog_backup"
+
#endif /* _back_ldbm_h_ */
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index a17ba5ce..cd388c9b 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -4320,6 +4320,50 @@ static int dblayer_force_checkpoint(struct ldbminfo *li)
return ret;
}
+static int
+_dblayer_delete_aux_dir(struct ldbminfo *li, char *path)
+{
+ PRDir *dirhandle = NULL;
+ PRDirEntry *direntry = NULL;
+ char filename[MAXPATHLEN];
+ dblayer_private *priv = NULL;
+ struct dblayer_private_env *pEnv = NULL;
+ int rc = -1;
+
+ if (NULL == li || NULL == path) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "_dblayer_delete_aux_dir: Invalid LDBM info (0x%x) "
+ "or path (0x%x)\n", li, path);
+ return rc;
+ }
+ priv = (dblayer_private*)li->li_dblayer_private;
+ if (priv) {
+ pEnv = priv->dblayer_env;
+ }
+ dirhandle = PR_OpenDir(path);
+ if (!dirhandle) {
+ return 0; /* The dir does not exist. */
+ }
+ while (NULL != (direntry = PR_ReadDir(dirhandle,
+ PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+ if (! direntry->name)
+ break;
+ PR_snprintf(filename, sizeof(filename), "%s/%s", path, direntry->name);
+ if (pEnv &&
+ strcmp(LDBM_FILENAME_SUFFIX , last_four_chars(direntry->name)) == 0)
+ {
+ rc = dblayer_db_remove_ex(pEnv, filename, 0, PR_TRUE);
+ }
+ else
+ {
+ rc = ldbm_delete_dirs(filename);
+ }
+ }
+ PR_CloseDir(dirhandle);
+ PR_RmDir(path);
+ return rc;
+}
+
/* TEL: Added startdb flag. If set (1), the DB environment will be started so
* that dblayer_db_remove_ex will be used to remove the database files instead
* of simply deleting them. That is important when doing a selective restoration
@@ -4339,7 +4383,8 @@ static int _dblayer_delete_instance_dir(ldbm_instance *inst, int startdb)
if (NULL == li)
{
- LDAPDebug(LDAP_DEBUG_ANY, "_dblayer_delete_instance_dir: NULL LDBM info\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "_dblayer_delete_instance_dir: NULL LDBM info\n");
rval = -1;
goto done;
}
@@ -4461,7 +4506,8 @@ int dblayer_delete_instance_dir(backend *be)
* this is used mostly for restores.
* dblayer is assumed to be closed.
*/
-int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
+static int
+dblayer_delete_database_ex(struct ldbminfo *li, char *instance, char *cldir)
{
dblayer_private *priv = NULL;
Object *inst_obj;
@@ -4504,6 +4550,17 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
}
}
+ /* changelog path is given; delete it, too. */
+ if (cldir) {
+ ret = _dblayer_delete_aux_dir(li, cldir);
+ if (ret) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "dblayer_delete_database: failed to deelete \"%s\"\n",
+ chdir);
+ return ret;
+ }
+ }
+
/* now smash everything else in the db/ dir */
dirhandle = PR_OpenDir(priv->dblayer_home_directory);
if (! dirhandle)
@@ -4567,7 +4624,7 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
*/
int dblayer_delete_database(struct ldbminfo *li)
{
- return dblayer_delete_database_ex(li, NULL);
+ return dblayer_delete_database_ex(li, NULL, NULL);
}
@@ -4830,7 +4887,6 @@ dblayer_copy_directory(struct ldbminfo *li,
char *inst_dirp = NULL;
char inst_dir[MAXPATHLEN];
char sep;
- ldbm_instance *inst;
if (!src_dir || '\0' == *src_dir)
{
@@ -4854,15 +4910,6 @@ dblayer_copy_directory(struct ldbminfo *li,
else
relative_instance_name++;
- inst = ldbm_instance_find_by_name(li, relative_instance_name);
- if (NULL == inst)
- {
- LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
- "Instance path %s could be invalid.\n",
- relative_instance_name, src_dir, 0);
- return return_value;
- }
-
if (is_fullpath(src_dir))
{
new_src_dir = src_dir;
@@ -4870,6 +4917,16 @@ dblayer_copy_directory(struct ldbminfo *li,
else
{
int len;
+ ldbm_instance *inst =
+ ldbm_instance_find_by_name(li, relative_instance_name);
+ if (NULL == inst)
+ {
+ LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
+ "Instance path %s could be invalid.\n",
+ relative_instance_name, src_dir, 0);
+ return return_value;
+ }
+
inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
inst_dir, MAXPATHLEN);
if (!inst_dirp || !*inst_dirp)
@@ -5009,21 +5066,98 @@ out:
return return_value;
}
+/*
+ * Get changelogdir from cn=changelog5,cn=config
+ * The value does not have trailing spaces nor slashes.
+ */
+static int
+_dblayer_get_changelogdir(struct ldbminfo *li, char **changelogdir)
+{
+ Slapi_PBlock *pb = NULL;
+ Slapi_Entry **entries = NULL;
+ Slapi_Attr *attr = NULL;
+ Slapi_Value *v = NULL;
+ const char *s = NULL;
+ char *attrs[2];
+ int rc = -1;
+
+ if (NULL == li || NULL == changelogdir) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ERROR: _dblayer_get_changelogdir: Invalid arg: "
+ "li: 0x%x, changelogdir: 0x%x\n", li, changelogdir);
+ return rc;
+ }
+ *changelogdir = NULL;
+ pb = slapi_pblock_new();
+ attrs[0] = CHANGELOGDIRATTR;
+ attrs[1] = NULL;
+ slapi_search_internal_set_pb(pb, CHANGELOGENTRY,
+ LDAP_SCOPE_BASE, "cn=*", attrs, 0, NULL, NULL,
+ li->li_identity, 0);
+ slapi_search_internal_pb(pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+
+ if (LDAP_NO_SUCH_OBJECT == rc) {
+ /* No changelog; Most likely standalone or not a master. */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ if (LDAP_SUCCESS != rc) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ERROR: Failed to search \"%s\"\n", CHANGELOGENTRY);
+ goto bail;
+ }
+ /* rc == LDAP_SUCCESS */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ if (NULL == entries) {
+ /* No changelog */
+ goto bail;
+ }
+ /* There should be only one entry. */
+ rc = slapi_entry_attr_find(entries[0], CHANGELOGDIRATTR, &attr);
+ if (rc || NULL == attr) {
+ /* No changelog dir */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ rc = slapi_attr_first_value(attr, &v);
+ if (rc || NULL == v) {
+ /* No changelog dir */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ rc = LDAP_SUCCESS;
+ s = slapi_value_get_string(v);
+ if (NULL == s) {
+ /* No changelog dir */
+ goto bail;
+ }
+ *changelogdir = slapi_ch_strdup(s);
+ /* Remove trailing spaces and '/' if any */
+ normalize_dir(*changelogdir);
+bail:
+ slapi_free_search_results_internal(pb);
+ slapi_pblock_destroy(pb);
+ return rc;
+}
/* Destination Directory is an absolute pathname */
-int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
+int
+dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
{
dblayer_private *priv = NULL;
char **listA = NULL, **listB = NULL, **listi, **listj, *prefix;
char *home_dir = NULL;
- int return_value = 0;
+ int return_value = -1;
char *pathname1;
char *pathname2;
back_txn txn;
int cnt = 1, ok = 0;
- ldbm_instance *inst;
Object *inst_obj;
+ char inst_dir[MAXPATHLEN];
+ char *inst_dirp = NULL;
+ char *changelogdir = NULL;
PR_ASSERT(NULL != li);
priv = (dblayer_private*)li->li_dblayer_private;
@@ -5031,9 +5165,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
home_dir = dblayer_get_home_dir(li, NULL);
if (NULL == home_dir || '\0' == *home_dir)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "Backup failed due to missing db home directory info\n", 0, 0, 0);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: missing db home directory info\n");
+ return return_value;
}
/*
@@ -5068,15 +5202,16 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
dblayer_force_checkpoint(li);
dblayer_txn_init(li,&txn);
return_value=dblayer_txn_begin(li,NULL,&txn);
- if (0 != return_value) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "Backup failed due to transaction failure\n", 0, 0, 0);
- return -1;
+ if (return_value) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: transaction error\n");
+ return return_value;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
/* repeat this until the logfile sets match... */
@@ -5085,73 +5220,104 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
if (priv->dblayer_enable_transactions) {
return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV,
&listA, DB_ARCH_LOG, (void *)slapi_ch_malloc);
- if ((return_value != 0) || (listA == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "BAD: can't get list of logs\n",
- 0, 0, 0);
- dblayer_txn_abort(li,&txn);
- return return_value;
+ if (return_value || (listA == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: log archive error\n");
+ if (task) {
+ slapi_task_log_notice(task, "Backup: log archive error\n");
+ }
+ return_value = -1;
+ goto bail;
}
} else {
ok=1;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj))
{
- char inst_dir[MAXPATHLEN];
- char *inst_dirp = NULL;
- inst = (ldbm_instance *)object_get_data(inst_obj);
+ ldbm_instance *inst = (ldbm_instance *)object_get_data(inst_obj);
inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
- inst_dir, MAXPATHLEN);
- if (inst_dirp && *inst_dirp)
- {
- return_value = dblayer_copy_directory(li, task, inst_dirp,
- dest_dir, 0 /* backup */, &cnt, 0, 0, 0);
- }
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: Instance dir is empty\n", 0, 0, 0);
+ inst_dir, MAXPATHLEN);
+ if ((NULL == inst_dirp) || ('\0' == *inst_dirp)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: Instance dir is empty\n");
if (task) {
slapi_task_log_notice(task,
- "ERROR: Instance dir is empty\n");
+ "Backup: Instance dir is empty\n");
}
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
- return -1;
+ return_value = -1;
+ goto bail;
}
- if (return_value != 0) {
+ return_value = dblayer_copy_directory(li, task, inst_dirp,
+ dest_dir, 0 /* backup */,
+ &cnt, 0, 0, 0);
+ if (return_value) {
LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: error copying directory (%s -> %s): err=%d\n",
- inst_dirp, dest_dir, return_value);
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ inst_dirp, dest_dir, return_value);
if (task) {
slapi_task_log_notice(task,
- "ERROR: error copying directory (%s -> %s): err=%d",
- inst_dirp, dest_dir, return_value);
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ inst_dirp, dest_dir, return_value);
}
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
if (inst_dirp != inst_dir)
slapi_ch_free_string(&inst_dirp);
- return return_value;
+ goto bail;
}
if (inst_dirp != inst_dir)
slapi_ch_free_string(&inst_dirp);
}
+ /* Get changelogdir, if any */
+ _dblayer_get_changelogdir(li, &changelogdir);
+ if (changelogdir) {
+ /* dest dir for changelog: dest_dir/repl_changelog_backup */
+ char *changelog_destdir = slapi_ch_smprintf("%s/%s",
+ dest_dir, CHANGELOG_BACKUPDIR);
+ return_value = dblayer_copy_directory(li, task, changelogdir,
+ changelog_destdir,
+ 0 /* backup */,
+ &cnt, 0, 0, 0);
+ if (return_value) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ changelogdir, changelog_destdir, return_value);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ changelogdir, changelog_destdir, return_value);
+ }
+ slapi_ch_free_string(&changelog_destdir);
+ goto bail;
+ }
+ /* Copy DBVERSION */
+ pathname1 = slapi_ch_smprintf("%s/%s",
+ changelogdir, DBVERSION_FILENAME);
+ pathname2 = slapi_ch_smprintf("%s/%s",
+ changelog_destdir, DBVERSION_FILENAME);
+ return_value = dblayer_copyfile(pathname1, pathname2,
+ 0, priv->dblayer_file_mode);
+ slapi_ch_free_string(&pathname1);
+ slapi_ch_free_string(&pathname1);
+ slapi_ch_free_string(&changelog_destdir);
+ }
if (priv->dblayer_enable_transactions) {
/* now, get the list of logfiles that still exist */
return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV,
&listB, DB_ARCH_LOG, (void *)slapi_ch_malloc);
- if ((return_value != 0) || (listB == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "ERROR: can't get list of logs\n",
- 0, 0, 0);
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
- return return_value;
+ if (return_value || (listB == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: can't get list of logs\n");
+ goto bail;
}
/* compare: make sure everything in list A is still in list B */
@@ -5166,8 +5332,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
if (! found) {
ok = 0; /* missing log: start over */
- LDAPDebug(LDAP_DEBUG_ANY, "WARNING: Log %s has been swiped "
- "out from under me! (retrying)\n", *listi, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "WARNING: Log %s has been swiped "
+ "out from under me! (retrying)\n", *listi);
if (task) {
slapi_task_log_notice(task,
"WARNING: Log %s has been swiped out from under me! "
@@ -5177,8 +5344,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
if (ok) {
@@ -5201,8 +5369,8 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
for (listptr = listB; listptr && *listptr && ok; ++listptr) {
PR_snprintf(pathname1, p1len, "%s/%s", prefix, *listptr);
PR_snprintf(pathname2, p2len, "%s/%s", dest_dir, *listptr);
- LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
- cnt, pathname2, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
+ cnt, pathname2);
if (task)
{
slapi_task_log_notice(task,
@@ -5213,9 +5381,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
return_value = dblayer_copyfile(pathname1, pathname2,
0, priv->dblayer_file_mode);
if (0 > return_value) {
- LDAPDebug(LDAP_DEBUG_ANY, "Error copying file '%s' "
- "(err=%d) -- Starting over...\n",
- pathname1, return_value, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backup: error in "
+ "copying file '%s' (err=%d) -- Starting over...\n",
+ pathname1, return_value);
if (task) {
slapi_task_log_notice(task,
"Error copying file '%s' (err=%d) -- Starting "
@@ -5224,8 +5392,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
ok = 0;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ slapi_ch_free((void **)&pathname1);
+ slapi_ch_free((void **)&pathname2);
+ goto bail;
}
cnt++;
}
@@ -5238,22 +5409,28 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
} while (!ok);
-
- if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
- }
-
/* now copy the version file */
pathname1 = slapi_ch_smprintf("%s/%s", home_dir, DBVERSION_FILENAME);
pathname2 = slapi_ch_smprintf("%s/%s", dest_dir, DBVERSION_FILENAME);
- LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
- cnt, pathname2, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", cnt, pathname2);
if (task) {
slapi_task_log_notice(task, "Backing up file %d (%s)", cnt, pathname2);
slapi_task_log_status(task, "Backing up file %d (%s)", cnt, pathname2);
}
- return_value = dblayer_copyfile(pathname1,pathname2,0,priv->dblayer_file_mode);
+ return_value =
+ dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode);
+ if (return_value) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "Backup: error in copying version file "
+ "(%s -> %s): err=%d\n",
+ pathname1, pathname2, return_value);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup: error in copying version file "
+ "(%s -> %s): err=%d\n",
+ pathname1, pathname2, return_value);
+ }
+ }
slapi_ch_free((void **)&pathname1);
slapi_ch_free((void **)&pathname2);
@@ -5261,8 +5438,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
if (0 == return_value) /* if everything went well, backup the index conf */
return_value = dse_conf_backup(li, dest_dir);
-
- return_value = dblayer_txn_abort(li,&txn);
+bail:
+ slapi_ch_free((void **)&listA);
+ slapi_ch_free((void **)&listB);
+ dblayer_txn_abort(li,&txn);
+ slapi_ch_free_string(&changelogdir);
return return_value;
}
@@ -5560,7 +5740,7 @@ static int dblayer_fri_restore(char *home_dir, char *src_dir, dblayer_private *p
int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *bename)
{
dblayer_private *priv = NULL;
- int return_value = 0;
+ int return_value = 0;
int tmp_rval;
char filename1[MAXPATHLEN];
char filename2[MAXPATHLEN];
@@ -5576,6 +5756,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
char *real_src_dir = NULL;
int frirestore = 0; /* Is a an FRI/single instance restore. 0 for no, 1 for yes */
struct stat sbuf;
+ char *changelogdir = NULL;
+ char *restore_dir = NULL;
+ char *prefix = NULL;
+ int cnt = 1;
PR_ASSERT(NULL != li);
priv = (dblayer_private*)li->li_dblayer_private;
@@ -5595,8 +5779,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
if (NULL == home_dir || '\0' == *home_dir)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "Restore failed due to missing db home directory info\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: missing db home directory info\n");
return -1;
}
@@ -5605,27 +5789,27 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* We check on the source staging area, no point in going further if it
* isn't there */
if (stat(src_dir, &sbuf) < 0) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
- "exist.\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not "
+ "exist.\n", src_dir);
if (task) {
- slapi_task_log_notice(task,
- "Backup directory %s does not exist.\n", src_dir);
+ slapi_task_log_notice(task, "Restore: backup directory %s does not "
+ "exist.\n", src_dir);
}
return LDAP_UNWILLING_TO_PERFORM;
} else if (!S_ISDIR(sbuf.st_mode)) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s is not "
- "a directory.\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s is not "
+ "a directory.\n", src_dir);
if (task) {
- slapi_task_log_notice(task,
- "Backup directory %s is not a directory.\n", src_dir);
+ slapi_task_log_notice(task, "Restore: backup directory %s is not "
+ "a directory.\n", src_dir);
}
return LDAP_UNWILLING_TO_PERFORM;
}
if (!dbversion_exists(li, src_dir)) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
- "contain a complete backup\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not "
+ "contain a complete backup\n", src_dir);
if (task) {
- slapi_task_log_notice(task, "Backup directory %s does not "
+ slapi_task_log_notice(task, "Restore: backup directory %s does not "
"contain a complete backup", src_dir );
}
return LDAP_UNWILLING_TO_PERFORM;
@@ -5646,34 +5830,50 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))
&& direntry->name)
{
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", src_dir, direntry->name);
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ src_dir, direntry->name);
if(!frirestore || strcmp(direntry->name,bename)==0)
{
tmp_rval = PR_GetFileInfo(filename1, &info);
if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
+ /* Is it CHANGELOG_BACKUPDIR? */
+ if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) {
+ /* Yes, this is a changelog backup. */
+ /* Get the changelog path */
+ _dblayer_get_changelogdir(li, &changelogdir);
+ continue;
+ }
inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
if ( inst == NULL)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: target server has no %s configured\n", direntry->name, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: target server has no %s configured\n",
+ direntry->name);
if (task) {
slapi_task_log_notice(task,
- "ERROR: target server has no %s configured\n", direntry->name);
+ "Restore: target server has no %s configured\n",
+ direntry->name);
}
PR_CloseDir(dirhandle);
- return LDAP_UNWILLING_TO_PERFORM;
+ return_value = LDAP_UNWILLING_TO_PERFORM;
+ goto error_out;
}
if (slapd_comp_path(src_dir, inst->inst_parent_dir_name)
== 0) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "Restore: backup dir %s and target dir %s "
+ "are identical\n",
+ src_dir, inst->inst_parent_dir_name);
if (task) {
slapi_task_log_notice(task,
- "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name);
+ "Restore: backup dir %s and target dir %s "
+ "are identical\n",
+ src_dir, inst->inst_parent_dir_name);
}
PR_CloseDir(dirhandle);
- return LDAP_UNWILLING_TO_PERFORM;
+ return_value = LDAP_UNWILLING_TO_PERFORM;
+ goto error_out;
}
}
}
@@ -5682,10 +5882,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
}
/* We delete the existing database */
-
- return_value = dblayer_delete_database_ex(li, bename);
+ /* changelogdir is taken care only when it's not NULL. */
+ return_value = dblayer_delete_database_ex(li, bename, changelogdir);
if (return_value) {
- return return_value;
+ goto error_out;
}
if (frirestore) /*if we are restoring a single backend*/
@@ -5693,7 +5893,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
char *new_src_dir = NULL;
return_value = dblayer_fri_restore(home_dir,src_dir,priv,task,&new_src_dir,bename);
if (return_value) {
- return return_value;
+ goto error_out;
}
/* Now modify the src_dir to point to our recovery area and carry on as if nothing had happened... */
real_src_dir = new_src_dir;
@@ -5707,91 +5907,141 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* We want to treat the logfiles specially: if there's
* a log file directory configured, copy the logfiles there
* rather than to the db dirctory */
- if (0 == return_value) {
- dirhandle = PR_OpenDir(real_src_dir);
- if (NULL != dirhandle) {
- char *restore_dir;
- char *prefix = NULL;
- int cnt = 1;
-
-
- while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
- if (NULL == direntry->name) {
- /* NSPR doesn't behave like the docs say it should */
- break;
- }
-
-
- /* Is this entry a directory? */
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name);
- tmp_rval = PR_GetFileInfo(filename1, &info);
- if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
- /* This is an instance directory. It contains the *.db#
- * files for the backend instance.
- * restore directory is supposed to be where the backend
- * directory is located.
- */
-
- inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
- if (inst == NULL)
- continue;
+ dirhandle = PR_OpenDir(real_src_dir);
+ if (NULL == dirhandle) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to open the directory \"%s\"\n", real_src_dir);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Restore: failed to open the directory \"%s\"\n", real_src_dir);
+ }
+ return_value = -1;
+ goto error_out;
+ }
+
+ while (NULL !=
+ (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+ if (NULL == direntry->name) {
+ /* NSPR doesn't behave like the docs say it should */
+ break;
+ }
- restore_dir = inst->inst_parent_dir_name;
- /* If we're doing a partial restore, we need to reset the LSNs on the data files */
- if (dblayer_copy_directory(li, task, filename1,
- restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
- continue;
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "restore: failed to copy directory %s\n",
- filename1, 0, 0);
+ /* Is this entry a directory? */
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ real_src_dir, direntry->name);
+ tmp_rval = PR_GetFileInfo(filename1, &info);
+ if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
+ /* This is an instance directory. It contains the *.db#
+ * files for the backend instance.
+ * restore directory is supposed to be where the backend
+ * directory is located.
+ */
+ if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) {
+ if (changelogdir) {
+ char *cldirname = PL_strrchr(changelogdir, '/');
+ char *p = filename1 + strlen(filename1);
+ if (NULL == cldirname) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: broken changelog dir path %s\n",
+ changelogdir);
if (task) {
slapi_task_log_notice(task,
- "Failed to copy directory %s", filename1);
+ "Restore: broken changelog dir path %s\n",
+ changelogdir);
}
- break;
+ goto error_out;
+ }
+ PR_snprintf(p, sizeof(filename1) - (p - filename1),
+ "/%s", cldirname+1);
+ /* Get the parent dir of changelogdir */
+ *cldirname = '\0';
+ return_value = dblayer_copy_directory(li, task, filename1,
+ changelogdir, 1 /* restore */, &cnt, 0, 0, 0);
+ *cldirname = '/';
+ if (return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to copy directory %s\n",
+ filename1);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Restore: failed to copy directory %s",
+ filename1);
+ }
+ goto error_out;
}
+ /* Copy DBVERSION */
+ p = filename1 + strlen(filename1);
+ PR_snprintf(p, sizeof(filename1) - (p - filename1),
+ "/%s", DBVERSION_FILENAME);
+ PR_snprintf(filename2, sizeof(filename2), "%s/%s",
+ changelogdir, DBVERSION_FILENAME);
+ return_value = dblayer_copyfile(filename1, filename2,
+ 0, priv->dblayer_file_mode);
}
+ continue;
+ }
- if (doskip(direntry->name))
- continue;
+ inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
+ if (inst == NULL)
+ continue;
- /* Is this a log file ? */
- /* Log files have names of the form "log.xxxxx" */
- /* We detect these by looking for the prefix "log." and
- * the lack of the ".db#" suffix */
- is_a_logfile = dblayer_is_logfilename(direntry->name);
- if (is_a_logfile) {
- seen_logfiles = 1;
- }
- if (is_a_logfile && (NULL != priv->dblayer_log_directory) &&
- (0 != strlen(priv->dblayer_log_directory)) ) {
- prefix = priv->dblayer_log_directory;
- } else {
- prefix = home_dir;
- }
- mkdir_p(prefix, 0700);
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name);
- PR_snprintf(filename2, MAXPATHLEN, "%s/%s", prefix, direntry->name);
- LDAPDebug(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n",
- cnt, filename2, 0);
+ restore_dir = inst->inst_parent_dir_name;
+ /* If we're doing a partial restore, we need to reset the LSNs on the data files */
+ if (dblayer_copy_directory(li, task, filename1,
+ restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
+ continue;
+ else
+ {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to copy directory %s\n",
+ filename1);
if (task) {
- slapi_task_log_notice(task, "Restoring file %d (%s)",
- cnt, filename2);
- slapi_task_log_status(task, "Restoring file %d (%s)",
- cnt, filename2);
+ slapi_task_log_notice(task,
+ "Restore: failed to copy directory %s", filename1);
}
- return_value = dblayer_copyfile(filename1, filename2, 0,
- priv->dblayer_file_mode);
- if (0 > return_value)
- break;
-
- cnt++;
+ goto error_out;
}
- PR_CloseDir(dirhandle);
}
+
+ if (doskip(direntry->name))
+ continue;
+
+ /* Is this a log file ? */
+ /* Log files have names of the form "log.xxxxx" */
+ /* We detect these by looking for the prefix "log." and
+ * the lack of the ".db#" suffix */
+ is_a_logfile = dblayer_is_logfilename(direntry->name);
+ if (is_a_logfile) {
+ seen_logfiles = 1;
+ }
+ if (is_a_logfile && (NULL != priv->dblayer_log_directory) &&
+ (0 != strlen(priv->dblayer_log_directory)) ) {
+ prefix = priv->dblayer_log_directory;
+ } else {
+ prefix = home_dir;
+ }
+ mkdir_p(prefix, 0700);
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ real_src_dir, direntry->name);
+ PR_snprintf(filename2, sizeof(filename2), "%s/%s",
+ prefix, direntry->name);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n",
+ cnt, filename2);
+ if (task) {
+ slapi_task_log_notice(task, "Restoring file %d (%s)",
+ cnt, filename2);
+ slapi_task_log_status(task, "Restoring file %d (%s)",
+ cnt, filename2);
+ }
+ return_value = dblayer_copyfile(filename1, filename2, 0,
+ priv->dblayer_file_mode);
+ if (0 > return_value) {
+ goto error_out;
+ }
+ cnt++;
}
+ PR_CloseDir(dirhandle);
+
/* We're done ! */
/* [605024] check the DBVERSION and reset idl-switch if needed */
@@ -5802,8 +6052,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
if (dbversion_read(li, home_dir, &ldbmversion, &dataversion) != 0)
{
- LDAPDebug(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion "
- "file in %s\n", home_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion "
+ "file in %s\n", home_dir);
}
else
{
@@ -5862,10 +6112,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
tmp_rval = dblayer_start(li, dbmode);
if (0 != tmp_rval) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "dblayer_restore: Failed to init database\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: failed to init database\n");
if (task) {
- slapi_task_log_notice(task, "Failed to init database");
+ slapi_task_log_notice(task, "Restore: failed to init database");
}
return_value = tmp_rval;
goto error_out;
@@ -5875,16 +6125,16 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* check the DSE_* files, if any */
tmp_rval = dse_conf_verify(li, real_src_dir, bename);
if (0 != tmp_rval)
- LDAPDebug(LDAP_DEBUG_ANY,
- "Warning: Unable to verify the index configuration\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Warning: Unable to verify the index configuration\n");
}
if (li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
/* command line: close the database down again */
tmp_rval = dblayer_close(li, dbmode);
if (0 != tmp_rval) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "dblayer_restore: Failed to close database\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: Failed to close database\n");
}
} else {
allinstance_set_busy(li); /* on-line mode */
@@ -5894,20 +6144,24 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
error_out:
/* Free the restore src dir, but only if we allocated it above */
- if (real_src_dir != src_dir) {
+ if (real_src_dir && (real_src_dir != src_dir)) {
/* If this was an FRI restore and the staging area exists, go ahead and remove it */
if (frirestore && PR_Access(real_src_dir, PR_ACCESS_EXISTS) == PR_SUCCESS)
{
int ret1 = 0;
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removing staging area %s.\n",real_src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: Removing staging area %s.\n", real_src_dir);
ret1 = ldbm_delete_dirs(real_src_dir);
if (ret1)
{
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removal of staging area %s failed!\n", real_src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: Removal of staging area %s failed!\n",
+ real_src_dir);
}
}
- slapi_ch_free((void**)&real_src_dir);
+ slapi_ch_free_string(&real_src_dir);
}
+ slapi_ch_free_string(&changelogdir);
return return_value;
}
@@ -6136,3 +6390,60 @@ void dblayer_set_recovery_required(struct ldbminfo *li)
li->li_dblayer_private->dblayer_recovery_required = 1;
}
+int
+ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info)
+{
+ int rc = -1;
+ if (!be || !info) {
+ return rc;
+ }
+
+ switch (cmd) {
+ case BACK_INFO_DBENV:
+ {
+ struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+ if (li) {
+ dblayer_private *prv = (dblayer_private*)li->li_dblayer_private;
+ if (prv && prv->dblayer_env && prv->dblayer_env->dblayer_DB_ENV) {
+ *(DB_ENV **)info = prv->dblayer_env->dblayer_DB_ENV;
+ rc = 0;
+ }
+ }
+ break;
+ }
+ case BACK_INFO_INDEXPAGESIZE:
+ {
+ struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+ if (li) {
+ dblayer_private *prv = (dblayer_private*)li->li_dblayer_private;
+ if (prv && prv->dblayer_index_page_size) {
+ *(size_t *)info = prv->dblayer_index_page_size;
+ } else {
+ *(size_t *)info = DBLAYER_INDEX_PAGESIZE;
+ }
+ rc = 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+int
+ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info)
+{
+ int rc = -1;
+ if (!be || !info) {
+ return rc;
+ }
+
+ switch (cmd) {
+ default:
+ break;
+ }
+
+ return rc;
+}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
index d0d05b4a..419b263b 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
@@ -207,4 +207,8 @@ void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
/* Return the last four characters of a string; used for comparing extensions. */
char* last_four_chars(const char* s);
+/* To support backingup/restoring changelog dir */
+#define CHANGELOGENTRY "cn=changelog5,cn=config"
+#define CHANGELOGDIRATTR "nsslapd-changelogdir"
+
#endif /* _DBLAYER_H_ */
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index 1fc269b9..1d490546 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -549,6 +549,7 @@ import_producer(void *param)
}
continue;
}
+ /* From here, e != NULL */
if (0 == my_version) {
/* after the first entry version string won't be given */
my_version = -1;
@@ -556,10 +557,7 @@ import_producer(void *param)
if (! import_entry_belongs_here(e, inst->inst_be)) {
/* silently skip */
- if (e) {
- slapi_entry_free(e);
- }
-
+ slapi_entry_free(e);
continue;
}
@@ -569,9 +567,7 @@ import_producer(void *param)
"violates schema, ending line %d of file "
"\"%s\"", escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- if (e) {
- slapi_entry_free(e);
- }
+ slapi_entry_free(e);
job->skipped++;
continue;
@@ -625,9 +621,7 @@ import_producer(void *param)
"violates attribute syntax, ending line %d of "
"file \"%s\"", escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- if (e) {
- slapi_entry_free(e);
- }
+ slapi_entry_free(e);
job->skipped++;
continue;
@@ -640,8 +634,10 @@ import_producer(void *param)
}
ep = import_make_backentry(e, id);
- if (!ep || !ep->ep_entry)
+ if (!ep) {
+ slapi_entry_free(e);
goto error;
+ }
/* check for include/exclude subtree lists */
if (! ldbm_back_ok_to_dump(backentry_get_ndn(ep),
@@ -729,8 +725,8 @@ import_producer(void *param)
"ending line %d of file \"%s\"",
escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- import_log_notice(job, "REASON: entry too large (%ld bytes) for "
- "the buffer size (%lu bytes)", newesize, job->fifo.bsize);
+ import_log_notice(job, "REASON: entry too large (%u bytes) for "
+ "the buffer size (%u bytes)", newesize, job->fifo.bsize);
backentry_free(&ep);
job->skipped++;
continue;
@@ -1422,6 +1418,7 @@ upgradedn_producer(void *param)
continue;
}
+ /* From here, e != NULL */
/* Check DN syntax attr values if it contains '\\' or not */
/* Start from the rdn */
if (entryrdn_get_switch()) { /* subtree-rename: on */
@@ -1615,7 +1612,7 @@ upgradedn_producer(void *param)
upgradedn_free_list(&ud_list);
ep = import_make_backentry(e, temp_id);
- if (!ep || !ep->ep_entry) {
+ if (!ep) {
slapi_entry_free(e); e = NULL;
goto error;
}
@@ -2130,7 +2127,7 @@ import_foreman(void *param)
* Note: FLAG_UPGRADEDNFORMAT only.
*/
Slapi_Attr *orig_entrydn = NULL;
- Slapi_Attr *new_entrydn = slapi_attr_new();
+ Slapi_Attr *new_entrydn = NULL;
Slapi_Attr *nsuniqueid = NULL;
const char *uuidstr = NULL;
char *new_dn = NULL;
@@ -2150,6 +2147,7 @@ import_foreman(void *param)
orig_dn, fi->entry->ep_id);
goto cont;
}
+ new_entrydn = slapi_attr_new();
new_dn = slapi_create_dn_string("nsuniqueid=%s+%s",
uuidstr, orig_dn);
/* releasing original dn */
@@ -2724,6 +2722,10 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
Slapi_Attr *attr = NULL;
size_t newesize = 0;
+ if (!entry) {
+ return -1;
+ }
+
PR_Lock(job->wire_lock);
/* Let's do this inside the lock !*/
id = job->lead_ID + 1;
@@ -2732,7 +2734,7 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
/* make into backentry */
ep = import_make_backentry(entry, id);
- if (!ep || !ep->ep_entry) {
+ if (!ep) {
import_abort_all(job, 1);
PR_Unlock(job->wire_lock);
return -1;
@@ -3157,9 +3159,10 @@ dse_conf_verify_core(struct ldbminfo *li, char *src_dir, char *file_name, char *
if (entry_filter != NULL) /* Single instance restoration */
{
- if (NULL == strstr(estr, entry_filter))
+ if (NULL == strstr(estr, entry_filter)) {
slapi_ch_free_string(&estr);
continue;
+ }
}
e = slapi_str2entry(estr, 0);
diff --git a/ldap/servers/slapd/back-ldbm/init.c b/ldap/servers/slapd/back-ldbm/init.c
index f1f71840..83951aea 100644
--- a/ldap/servers/slapd/back-ldbm/init.c
+++ b/ldap/servers/slapd/back-ldbm/init.c
@@ -248,6 +248,10 @@ ldbm_back_init( Slapi_PBlock *pb )
(void *) ldbm_back_wire_import );
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_SCHEMA_FN,
(void *) ldbm_back_add_schema );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_GET_INFO_FN,
+ (void *) ldbm_back_get_info );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SET_INFO_FN,
+ (void *) ldbm_back_set_info );
if ( rc != 0 ) {
LDAPDebug( LDAP_DEBUG_ANY, "ldbm_back_init failed\n", 0, 0, 0 );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 529f55e0..5e3b9b53 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -190,7 +190,7 @@ int
ldbm_back_modify( Slapi_PBlock *pb )
{
backend *be;
- ldbm_instance *inst;
+ ldbm_instance *inst = NULL;
struct ldbminfo *li;
struct backentry *e = NULL, *ec = NULL;
Slapi_Entry *postentry = NULL;
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 25cc265c..e0b09fb4 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1389,6 +1389,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
&eargs, DB2LDIF_ENTRYRDN, &psrdn);
if (rc) {
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1424,6 +1425,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
"%d\n", pid);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1436,6 +1438,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
rdn, temp_id);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1932,6 +1935,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
rdn, temp_id, pid, run_from_cmdline,
NULL, index_ext, &psrdn);
if (rc) {
+ backentry_free(&ep);
continue;
}
}
@@ -1966,6 +1970,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
"%d\n", pid);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1978,6 +1983,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
rdn, temp_id);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -2448,7 +2454,6 @@ ldbm_exclude_attr_from_export( struct ldbminfo *li , const char *attr,
int upgradedb_core(Slapi_PBlock *pb, ldbm_instance *inst);
int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir, int restore);
int upgradedb_delete_indices_4cmd(ldbm_instance *inst, int flags);
-static void normalize_dir(char *dir);
/*
* ldbm_back_upgradedb -
@@ -2797,26 +2802,6 @@ fail0:
return rval + upgrade_rval;
}
-static void
-normalize_dir(char *dir)
-{
- char *p = NULL;
- int l = 0;
-
- if (NULL == dir) {
- return;
- }
- l = strlen(dir);
-
- for (p = dir + l - 1; p && *p; p--) {
- if (' ' != *p && '\t' != *p && '/' != *p && '\\' != *p) {
- break;
- }
- }
- *(p+1) = '\0';
-}
-
-
#define LOG "log."
#define LOGLEN 4
int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir,
@@ -3070,7 +3055,7 @@ _get_and_add_parent_rdns(backend *be,
slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm",
"_get_and_add_parent_rdns: "
"Failed to convert DN %s to RDN\n",
- slapi_sdn_get_dn(bdn->dn_sdn));
+ slapi_rdn_get_rdn(&mysrdn));
slapi_rdn_done(&mysrdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
goto bail;
@@ -3162,7 +3147,7 @@ _get_and_add_parent_rdns(backend *be,
slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm",
"_get_and_add_parent_rdns: "
"Failed to merge Slapi_RDN %s to RDN\n",
- slapi_sdn_get_dn(bdn->dn_sdn));
+ slapi_rdn_get_rdn(&mysrdn));
goto bail;
}
}
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 4b4a7200..13b87fd7 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -483,12 +483,14 @@ get_value_from_string(const char *string, char *type, char **value)
ldif_getline_fixline(startptr, tmpptr);
startptr = tmpptr;
rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval);
- if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
+ if (0 > rc || NULL == tmptype.bv_val ||
+ NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse "
"failed: %d\n", rc);
if (freeval) {
slapi_ch_free_string(&bvvalue.bv_val);
}
+ rc = -1; /* set non-0 to rc */
goto bail;
}
if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) {
@@ -498,8 +500,10 @@ get_value_from_string(const char *string, char *type, char **value)
if (freeval) {
slapi_ch_free_string(&bvvalue.bv_val);
}
+ rc = -1; /* set non-0 to rc */
goto bail;
}
+ rc = 0; /* set 0 to rc */
if (freeval) {
*value = bvvalue.bv_val; /* just hand off the memory */
bvvalue.bv_val = NULL;
@@ -609,3 +613,23 @@ bail:
slapi_ch_free_string(&copy);
return rc;
}
+
+void
+normalize_dir(char *dir)
+{
+ char *p = NULL;
+ int l = 0;
+
+ if (NULL == dir) {
+ return;
+ }
+ l = strlen(dir);
+
+ for (p = dir + l - 1; p && *p && (p > dir); p--) {
+ if ((' ' != *p) && ('\t' != *p) && ('/' != *p) && ('\\' != *p)) {
+ break;
+ }
+ }
+ *(p+1) = '\0';
+}
+
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 615d9373..363bec27 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -173,6 +173,9 @@ int dblayer_db_uses_logging(DB_ENV *db_env);
int dblayer_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2);
int dblayer_remove_env(struct ldbminfo *li);
+int ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info);
+int ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info);
+
/*
* dn2entry.c
*/
@@ -364,7 +367,7 @@ int is_fullpath(char *path);
char get_sep(char *path);
int get_value_from_string(const char *string, char *type, char **value);
int get_values_from_string(const char *string, char *type, char ***valuearray);
-
+void normalize_dir(char *dir);
/*
* nextid.c