andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 0b48e0728af1fb7c59468cb93f9805cb8fbcac03 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Tue, 28 Jan 2014 11:25:34 -0800
dc8c34
Subject: [PATCH 159/225] Ticket #47463 - IDL-style can become mismatched
dc8c34
 during partial restoration
dc8c34
dc8c34
The commit to 389-ds-base-1.3.2 and newer is back ported to 389-ds-
dc8c34
1.2.11 trough 1.3.1 by Thomas E Lackey.
dc8c34
dc8c34
commit b43145218dccc8c9c16ecadad80f94bf58c73d57
dc8c34
Author: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date:   Fri Sep 27 17:58:03 2013 -0700
dc8c34
dc8c34
Description by telackey:
dc8c34
When doing a partial/FRI restoration the database files are copied
dc8c34
key-by-key. This is necessary to reset the LSNs so the restored
dc8c34
files can merge into the existing DB environment (cf. dblayer_copy_
dc8c34
file_resetlsns()) in a recoverable way.
dc8c34
dc8c34
However, dblayer_copy_file_keybykey() does not set the comparison
dc8c34
function before calling DB->put(), which means that the restored
dc8c34
files will not necessarily be using the proper function.
dc8c34
dc8c34
While all the keys are technically present, indexed searches can
dc8c34
still fail to return relevant results because the key order is
dc8c34
significant when intersecting the results with the other indices.
dc8c34
dc8c34
Note: The bug was reported and the patch was provided by telackey.
dc8c34
(Thank you, Thomas!)
dc8c34
dc8c34
Additional fix by nhosoi:
dc8c34
The entryrdn index uses its special dup compare function.  The dup
dc8c34
compare function is set when the restoring index file is entryrdn.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47463
dc8c34
dc8c34
Reviewed by rmeggins (Thank you, Rich!)
dc8c34
(cherry picked from commit abe5c894686f46b60f069f8cbd8aa909b34d81a1)
dc8c34
---
dc8c34
 ldap/servers/slapd/back-ldbm/dbhelp.c  | 53 ++++++++++++++++++++++++++++++++--
dc8c34
 ldap/servers/slapd/back-ldbm/dblayer.c | 29 +++++++++----------
dc8c34
 ldap/servers/slapd/back-ldbm/dblayer.h |  2 +-
dc8c34
 3 files changed, 65 insertions(+), 19 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
index 1165831..b0d17d3 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
dc8c34
@@ -49,7 +49,13 @@
dc8c34
 #include "back-ldbm.h"
dc8c34
 #include "dblayer.h"
dc8c34
 
dc8c34
-static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
dc8c34
+static int
dc8c34
+dblayer_copy_file_keybykey(DB_ENV *env,
dc8c34
+                           char *source_file_name,
dc8c34
+                           char *destination_file_name,
dc8c34
+                           int overwrite,
dc8c34
+                           dblayer_private *priv,
dc8c34
+                           ldbm_instance *inst)
dc8c34
 {
dc8c34
 	int retval = 0;
dc8c34
 	int retval_cleanup = 0;
dc8c34
@@ -62,6 +68,7 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
dc8c34
 	int cursor_flag = 0;
dc8c34
 	int finished = 0;
dc8c34
 	int mode = 0;
dc8c34
+        char *p = NULL;
dc8c34
 
dc8c34
 	LDAPDebug( LDAP_DEBUG_TRACE, "=> dblayer_copy_file_keybykey\n", 0, 0, 0 );
dc8c34
 
dc8c34
@@ -119,6 +126,40 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
dc8c34
 		LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, set_pagesize error %d: %s\n", retval, db_strerror(retval), 0);
dc8c34
 		goto error;
dc8c34
 	}
dc8c34
+
dc8c34
+        /* TEL 20130412: Make sure to set the dup comparison function if needed.  
dc8c34
+         * We key our decision off of the presence of new IDL and dup flags on
dc8c34
+         * the source database.  This is similar dblayer_open_file, except that
dc8c34
+         * we don't have the attribute info index mask for VLV.  That should be OK
dc8c34
+         * since the DB_DUP and DB_DUPSORT flags wouldn't have been toggled on
dc8c34
+         * unless they passed the check on the source.
dc8c34
+         */
dc8c34
+        /* Entryrdn index has its own dup compare function */
dc8c34
+        if ((p = PL_strcasestr(source_file_name, LDBM_ENTRYRDN_STR)) &&
dc8c34
+                (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
dc8c34
+                /* entryrdn.db */
dc8c34
+                struct attrinfo *ai = NULL;
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
+                        retval = destination_file->set_dup_compare(destination_file, ai->ai_dup_cmp_fn);
dc8c34
+                        if (retval) {
dc8c34
+                                LDAPDebug2Args(LDAP_DEBUG_ANY,
dc8c34
+                                               "dblayer_copy_file_keybykey(entryrdn), set_dup_compare error %d: %s\n",
dc8c34
+                                               retval, db_strerror(retval));
dc8c34
+                                goto error;
dc8c34
+                        }
dc8c34
+                }
dc8c34
+        } else if (idl_get_idl_new() && (dbflags & DB_DUP) && (dbflags & DB_DUPSORT)) {
dc8c34
+                retval = destination_file->set_dup_compare(destination_file, idl_new_compare_dups); 
dc8c34
+                if (retval) {
dc8c34
+                        LDAPDebug2Args(LDAP_DEBUG_ANY,
dc8c34
+                                       "dblayer_copy_file_keybykey, set_dup_compare error %d: %s\n",
dc8c34
+                                       retval, db_strerror(retval));
dc8c34
+                        goto error;
dc8c34
+                }
dc8c34
+        }
dc8c34
+
dc8c34
 	retval = (destination_file->open)(destination_file, NULL, destination_file_name, NULL, dbtype, DB_CREATE | DB_EXCL, mode);
dc8c34
 	if (retval) {
dc8c34
 		LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, Open error %d: %s\n", retval, db_strerror(retval), 0);
dc8c34
@@ -190,7 +231,13 @@ error:
dc8c34
 	return retval;
dc8c34
 }
dc8c34
 
dc8c34
-int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
dc8c34
+int
dc8c34
+dblayer_copy_file_resetlsns(char *home_dir,
dc8c34
+                            char *source_file_name,
dc8c34
+                            char *destination_file_name,
dc8c34
+                            int overwrite,
dc8c34
+                            dblayer_private *priv,
dc8c34
+                            ldbm_instance *inst)
dc8c34
 {
dc8c34
 	int retval = 0;
dc8c34
 	DB_ENV *env = NULL;
dc8c34
@@ -205,7 +252,7 @@ int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *de
dc8c34
 		goto out;
dc8c34
 	}
dc8c34
 	/* Do the copy */
dc8c34
-	retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv);
dc8c34
+	retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv, inst);
dc8c34
 	if (retval) {
dc8c34
 		LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_resetlsns: Copy not completed successfully.", 0, 0, 0);
dc8c34
 	}
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
index fab61f3..5fdca28 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
@@ -5546,6 +5546,7 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
     char            inst_dir[MAXPATHLEN];
dc8c34
     char            sep;
dc8c34
     int             suffix_len = 0;
dc8c34
+    ldbm_instance *inst = NULL;
dc8c34
 
dc8c34
     if (!src_dir || '\0' == *src_dir)
dc8c34
     {
dc8c34
@@ -5569,6 +5570,14 @@ 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
+    }
dc8c34
+
dc8c34
     if (is_fullpath(src_dir))
dc8c34
     {
dc8c34
         new_src_dir = src_dir;
dc8c34
@@ -5576,15 +5585,6 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
     else
dc8c34
     {
dc8c34
         int len;
dc8c34
-        ldbm_instance *inst =
dc8c34
-                       ldbm_instance_find_by_name(li, relative_instance_name);
dc8c34
-        if (NULL == inst)
dc8c34
-        {
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
         inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
dc8c34
                                               inst_dir, MAXPATHLEN);
dc8c34
@@ -5642,7 +5642,7 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
             if (NULL == new_dest_dir) {
dc8c34
                 /* Need to create the new directory where the files will be
dc8c34
                  * copied to. */
dc8c34
-                PRFileInfo info;
dc8c34
+                PRFileInfo64 info;
dc8c34
                 char *prefix = "";
dc8c34
                 char mysep = 0;
dc8c34
 
dc8c34
@@ -5663,7 +5663,7 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
                     new_dest_dir = slapi_ch_smprintf("%s/%s",
dc8c34
                         dest_dir, relative_instance_name);
dc8c34
                 /* } */
dc8c34
-                if (PR_SUCCESS == PR_GetFileInfo(new_dest_dir, &info))
dc8c34
+                if (PR_SUCCESS == PR_GetFileInfo64(new_dest_dir, &info))
dc8c34
                 {
dc8c34
                     ldbm_delete_dirs(new_dest_dir);
dc8c34
                 }
dc8c34
@@ -5704,13 +5704,12 @@ dblayer_copy_directory(struct ldbminfo *li,
dc8c34
             /* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
dc8c34
             /* PL_strcmp takes NULL arg */
dc8c34
             if (resetlsns &&
dc8c34
-                (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.'))
dc8c34
-                 == 0)) {
dc8c34
+                (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.')) == 0)) {
dc8c34
                 return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
dc8c34
-                                            0, priv);
dc8c34
+                                                           0, priv, inst);
dc8c34
             } else {
dc8c34
                 return_value = dblayer_copyfile(filename1, filename2,
dc8c34
-                                            0, priv->dblayer_file_mode);
dc8c34
+                                                0, priv->dblayer_file_mode);
dc8c34
             }
dc8c34
             slapi_ch_free((void**)&filename1);
dc8c34
             slapi_ch_free((void**)&filename2);
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
dc8c34
index 7f3200c..4ff9d53 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
dc8c34
@@ -201,7 +201,7 @@ int dblayer_make_private_simple_env(char *db_home_dir, DB_ENV **env);
dc8c34
 /* Copy a database file, preserving all its contents (used to reset the LSNs in the file in order to move 
dc8c34
  * it from one transacted environment to another.
dc8c34
  */
dc8c34
-int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv);
dc8c34
+int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv, ldbm_instance *inst);
dc8c34
 /* Turn on the various logging and debug options for DB */
dc8c34
 void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
dc8c34
 
dc8c34
-- 
dc8c34
1.8.1.4
dc8c34