andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 4 months ago
Clone
Blob Blame History Raw
From f734217280efe98528d4be1544972cae1c12c8d6 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Fri, 16 May 2014 10:05:43 -0700
Subject: [PATCH 213/225] Ticket #47804 - db2bak.pl error with changelogdb

Bug description: Backup utility db2bak[.pl] copies not just backend
db files but also changelog db files, which is not associated with
the backend instance, but the backend code blindly expected it.

Fix description: If the copying directory is a changelog db dir,
skip retrieving the backend instance info and just copy the files
underneath

https://fedorahosted.org/389/ticket/47804

Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
(cherry picked from commit a6c24c5bf1216e6dceaf014a25ce60a5a714635c)
---
 ldap/servers/slapd/back-ldbm/dbhelp.c          |  6 +++
 ldap/servers/slapd/back-ldbm/dblayer.c         | 60 +++++++++++++-------------
 ldap/servers/slapd/back-ldbm/proto-back-ldbm.h |  4 +-
 3 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
index b0d17d3..797e2ae 100644
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
@@ -139,6 +139,12 @@ dblayer_copy_file_keybykey(DB_ENV *env,
                 (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
                 /* entryrdn.db */
                 struct attrinfo *ai = NULL;
+                if (NULL == inst) {
+                    LDAPDebug0Args(LDAP_DEBUG_ANY,
+                                   "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 */
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 5fdca28..6f66a75 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5526,17 +5526,15 @@ dblayer_copy_directory(struct ldbminfo *li,
                        char *dest_dir,
                        int restore,
                        int *cnt,
-                       int instance_dir_flag,
                        int indexonly,
-                       int resetlsns)
+                       int resetlsns,
+                       int is_changelog)
 {
     dblayer_private *priv = NULL;
     char            *new_src_dir = NULL;
     char            *new_dest_dir = NULL;
     PRDir           *dirhandle = NULL;
     PRDirEntry      *direntry = NULL;
-    size_t          filename_length = 0;
-    size_t          offset = 0;
     char            *compare_piece = NULL;
     char            *filename1;
     char            *filename2;
@@ -5545,8 +5543,8 @@ dblayer_copy_directory(struct ldbminfo *li,
     char            *inst_dirp = NULL;
     char            inst_dir[MAXPATHLEN];
     char            sep;
-    int             suffix_len = 0;
-    ldbm_instance *inst = NULL;
+    int             src_is_fullpath = 0;
+    ldbm_instance   *inst = NULL;
 
     if (!src_dir || '\0' == *src_dir)
     {
@@ -5570,20 +5568,28 @@ 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)) {
+        src_is_fullpath = 1;
+    }
+    if (is_changelog) {
+        if (!src_is_fullpath) {
+            LDAPDebug1Arg(LDAP_DEBUG_ANY, "Changelogdir \"%s\" is not full path; "
+                          "Skipping it.\n", src_dir);
+            return 0;
+        }
+    } else {
+        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))
-    {
+    if (src_is_fullpath) {
         new_src_dir = src_dir;
-    }
-    else
-    {
+    } else {
         int len;
 
         inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
@@ -5610,7 +5616,6 @@ dblayer_copy_directory(struct ldbminfo *li,
         return return_value;
     }
 
-    suffix_len = sizeof(LDBM_SUFFIX) - 1;
     while (NULL != (direntry =
                     PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
     {
@@ -5624,15 +5629,10 @@ dblayer_copy_directory(struct ldbminfo *li,
             continue;
         }
 
-        /* Look at the last three characters in the filename */
-        filename_length = strlen(direntry->name);
-        if (filename_length > suffix_len) {
-            offset = filename_length - suffix_len;
-        } else {
-            offset = 0;
+        compare_piece = PL_strrchr((char *)direntry->name, '.');
+        if (NULL == compare_piece) {
+            compare_piece = (char *)direntry->name;
         }
-        compare_piece = (char *)direntry->name + offset;
-
         /* rename .db3 -> .db4 or .db4 -> .db */
         if (0 == strcmp(compare_piece, LDBM_FILENAME_SUFFIX) ||
             0 == strcmp(compare_piece, LDBM_SUFFIX_OLD) ||
@@ -5732,6 +5732,7 @@ out:
 /*
  * Get changelogdir from cn=changelog5,cn=config
  * The value does not have trailing spaces nor slashes.
+ * The changelogdir value must be a fullpath.
  */
 static int
 _dblayer_get_changelogdir(struct ldbminfo *li, char **changelogdir)
@@ -5947,7 +5948,7 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
             return_value = dblayer_copy_directory(li, task, changelogdir,
                                                   changelog_destdir,
                                                   0 /* backup */,
-                                                  &cnt, 0, 0, 0);
+                                                  &cnt, 0, 0, 1);
             if (return_value) {
                 LDAPDebug(LDAP_DEBUG_ANY,
                           "Backup: error in copying directory "
@@ -6619,7 +6620,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
                     /* Get the parent dir of changelogdir */
                     *cldirname = '\0';
                     return_value = dblayer_copy_directory(li, task, filename1,
-                                  changelogdir, 1 /* restore */, &cnt, 0, 0, 0);
+                                                          changelogdir, 1 /* restore */,
+                                                          &cnt, 0, 0, 1);
                     *cldirname = '/';
                     if (return_value) {
                         LDAPDebug1Arg(LDAP_DEBUG_ANY,
@@ -6651,7 +6653,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
             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)
+                restore_dir, 1 /* restore */, &cnt, 0, (bename) ? 1 : 0, 0) == 0)
                 continue;
             else
             {
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 499c92b..65cafea 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -137,8 +137,8 @@ int dblayer_backup(struct ldbminfo *li, char *destination_directory,
 int dblayer_restore(struct ldbminfo *li, char* source_directory, Slapi_Task *task, char *bename);
 int dblayer_copy_directory(struct ldbminfo *li, Slapi_Task *task,
                            char *instance_dir, char *destination_dir,
-                           int restore, int *cnt, int instance_dir_flag,
-                           int indexonly, int resetlsns);
+                           int restore, int *cnt, int indexonly,
+                           int resetlsns, int is_changelog);
 int dblayer_copyfile(char* source, char * destination, int overwrite, int mode);
 int dblayer_delete_instance_dir(backend *be);
 int dblayer_delete_database(struct ldbminfo *li);
-- 
1.8.1.4