|
|
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 |
|