andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From f734217280efe98528d4be1544972cae1c12c8d6 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Fri, 16 May 2014 10:05:43 -0700
dc8c34
Subject: [PATCH 213/225] Ticket #47804 - db2bak.pl error with changelogdb
dc8c34
dc8c34
Bug description: Backup utility db2bak[.pl] copies not just backend
dc8c34
db files but also changelog db files, which is not associated with
dc8c34
the backend instance, but the backend code blindly expected it.
dc8c34
dc8c34
Fix description: If the copying directory is a changelog db dir,
dc8c34
skip retrieving the backend instance info and just copy the files
dc8c34
underneath
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47804
dc8c34
dc8c34
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
dc8c34
(cherry picked from commit a6c24c5bf1216e6dceaf014a25ce60a5a714635c)
dc8c34
---
dc8c34
 ldap/servers/slapd/back-ldbm/dbhelp.c          |  6 +++
dc8c34
 ldap/servers/slapd/back-ldbm/dblayer.c         | 60 +++++++++++++-------------
dc8c34
 ldap/servers/slapd/back-ldbm/proto-back-ldbm.h |  4 +-
dc8c34
 3 files changed, 39 insertions(+), 31 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
index b0d17d3..797e2ae 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
@@ -139,6 +139,12 @@ dblayer_copy_file_keybykey(DB_ENV *env,
dc8c34
                 (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
dc8c34
                 /* entryrdn.db */
dc8c34
                 struct attrinfo *ai = NULL;
dc8c34
+                if (NULL == inst) {
dc8c34
+                    LDAPDebug0Args(LDAP_DEBUG_ANY,
dc8c34
+                                   "dblayer_copy_file_keybykey(entryrdn), "
dc8c34
+                                   "dup_cmp_fn cannot be retrieved since inst is NULL.\n");
dc8c34
+                    goto error;
dc8c34
+                }
dc8c34
                 ainfo_get(inst->inst_be, LDBM_ENTRYRDN_STR, &ai;;
dc8c34
                 if (ai->ai_dup_cmp_fn) {
dc8c34
                         /* If set, use the special dup compare callback */
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
index 5fdca28..6f66a75 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
@@ -5526,17 +5526,15 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
                        char *dest_dir,
dc8c34
                        int restore,
dc8c34
                        int *cnt,
dc8c34
-                       int instance_dir_flag,
dc8c34
                        int indexonly,
dc8c34
-                       int resetlsns)
dc8c34
+                       int resetlsns,
dc8c34
+                       int is_changelog)
dc8c34
 {
dc8c34
     dblayer_private *priv = NULL;
dc8c34
     char            *new_src_dir = NULL;
dc8c34
     char            *new_dest_dir = NULL;
dc8c34
     PRDir           *dirhandle = NULL;
dc8c34
     PRDirEntry      *direntry = NULL;
dc8c34
-    size_t          filename_length = 0;
dc8c34
-    size_t          offset = 0;
dc8c34
     char            *compare_piece = NULL;
dc8c34
     char            *filename1;
dc8c34
     char            *filename2;
dc8c34
@@ -5545,8 +5543,8 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
     char            *inst_dirp = NULL;
dc8c34
     char            inst_dir[MAXPATHLEN];
dc8c34
     char            sep;
dc8c34
-    int             suffix_len = 0;
dc8c34
-    ldbm_instance *inst = NULL;
dc8c34
+    int             src_is_fullpath = 0;
dc8c34
+    ldbm_instance   *inst = NULL;
dc8c34
 
dc8c34
     if (!src_dir || '\0' == *src_dir)
dc8c34
     {
dc8c34
@@ -5570,20 +5568,28 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
     else
dc8c34
         relative_instance_name++;
dc8c34
 
dc8c34
-    inst = ldbm_instance_find_by_name(li, relative_instance_name);
dc8c34
-    if (NULL == inst) {
dc8c34
-        LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
dc8c34
-                  "Instance path %s could be invalid.\n",
dc8c34
-                  relative_instance_name, src_dir, 0);
dc8c34
-        return return_value;
dc8c34
+    if (is_fullpath(src_dir)) {
dc8c34
+        src_is_fullpath = 1;
dc8c34
+    }
dc8c34
+    if (is_changelog) {
dc8c34
+        if (!src_is_fullpath) {
dc8c34
+            LDAPDebug1Arg(LDAP_DEBUG_ANY, "Changelogdir \"%s\" is not full path; "
dc8c34
+                          "Skipping it.\n", src_dir);
dc8c34
+            return 0;
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+        inst = ldbm_instance_find_by_name(li, relative_instance_name);
dc8c34
+        if (NULL == inst) {
dc8c34
+            LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
dc8c34
+                      "Instance path %s could be invalid.\n",
dc8c34
+                      relative_instance_name, src_dir, 0);
dc8c34
+            return return_value;
dc8c34
+        }
dc8c34
     }
dc8c34
 
dc8c34
-    if (is_fullpath(src_dir))
dc8c34
-    {
dc8c34
+    if (src_is_fullpath) {
dc8c34
         new_src_dir = src_dir;
dc8c34
-    }
dc8c34
-    else
dc8c34
-    {
dc8c34
+    } else {
dc8c34
         int len;
dc8c34
 
dc8c34
         inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
dc8c34
@@ -5610,7 +5616,6 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
         return return_value;
dc8c34
     }
dc8c34
 
dc8c34
-    suffix_len = sizeof(LDBM_SUFFIX) - 1;
dc8c34
     while (NULL != (direntry =
dc8c34
                     PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
dc8c34
     {
dc8c34
@@ -5624,15 +5629,10 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
             continue;
dc8c34
         }
dc8c34
 
dc8c34
-        /* Look at the last three characters in the filename */
dc8c34
-        filename_length = strlen(direntry->name);
dc8c34
-        if (filename_length > suffix_len) {
dc8c34
-            offset = filename_length - suffix_len;
dc8c34
-        } else {
dc8c34
-            offset = 0;
dc8c34
+        compare_piece = PL_strrchr((char *)direntry->name, '.');
dc8c34
+        if (NULL == compare_piece) {
dc8c34
+            compare_piece = (char *)direntry->name;
dc8c34
         }
dc8c34
-        compare_piece = (char *)direntry->name + offset;
dc8c34
-
dc8c34
         /* rename .db3 -> .db4 or .db4 -> .db */
dc8c34
         if (0 == strcmp(compare_piece, LDBM_FILENAME_SUFFIX) ||
dc8c34
             0 == strcmp(compare_piece, LDBM_SUFFIX_OLD) ||
dc8c34
@@ -5732,6 +5732,7 @@ out:
dc8c34
 /*
dc8c34
  * Get changelogdir from cn=changelog5,cn=config
dc8c34
  * The value does not have trailing spaces nor slashes.
dc8c34
+ * The changelogdir value must be a fullpath.
dc8c34
  */
dc8c34
 static int
dc8c34
 _dblayer_get_changelogdir(struct ldbminfo *li, char **changelogdir)
dc8c34
@@ -5947,7 +5948,7 @@ dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
dc8c34
             return_value = dblayer_copy_directory(li, task, changelogdir,
dc8c34
                                                   changelog_destdir,
dc8c34
                                                   0 /* backup */,
dc8c34
-                                                  &cnt, 0, 0, 0);
dc8c34
+                                                  &cnt, 0, 0, 1);
dc8c34
             if (return_value) {
dc8c34
                 LDAPDebug(LDAP_DEBUG_ANY,
dc8c34
                           "Backup: error in copying directory "
dc8c34
@@ -6619,7 +6620,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
dc8c34
                     /* Get the parent dir of changelogdir */
dc8c34
                     *cldirname = '\0';
dc8c34
                     return_value = dblayer_copy_directory(li, task, filename1,
dc8c34
-                                  changelogdir, 1 /* restore */, &cnt, 0, 0, 0);
dc8c34
+                                                          changelogdir, 1 /* restore */,
dc8c34
+                                                          &cnt, 0, 0, 1);
dc8c34
                     *cldirname = '/';
dc8c34
                     if (return_value) {
dc8c34
                         LDAPDebug1Arg(LDAP_DEBUG_ANY,
dc8c34
@@ -6651,7 +6653,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
dc8c34
             restore_dir = inst->inst_parent_dir_name;
dc8c34
             /* If we're doing a partial restore, we need to reset the LSNs on the data files */
dc8c34
             if (dblayer_copy_directory(li, task, filename1,
dc8c34
-                restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
dc8c34
+                restore_dir, 1 /* restore */, &cnt, 0, (bename) ? 1 : 0, 0) == 0)
dc8c34
                 continue;
dc8c34
             else
dc8c34
             {
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
dc8c34
index 499c92b..65cafea 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
dc8c34
@@ -137,8 +137,8 @@ int dblayer_backup(struct ldbminfo *li, char *destination_directory,
dc8c34
 int dblayer_restore(struct ldbminfo *li, char* source_directory, Slapi_Task *task, char *bename);
dc8c34
 int dblayer_copy_directory(struct ldbminfo *li, Slapi_Task *task,
dc8c34
                            char *instance_dir, char *destination_dir,
dc8c34
-                           int restore, int *cnt, int instance_dir_flag,
dc8c34
-                           int indexonly, int resetlsns);
dc8c34
+                           int restore, int *cnt, int indexonly,
dc8c34
+                           int resetlsns, int is_changelog);
dc8c34
 int dblayer_copyfile(char* source, char * destination, int overwrite, int mode);
dc8c34
 int dblayer_delete_instance_dir(backend *be);
dc8c34
 int dblayer_delete_database(struct ldbminfo *li);
dc8c34
-- 
dc8c34
1.8.1.4
dc8c34