ldap/servers/slapd/back-ldbm/dbhelp.c | 53 +++++++++++++++++++++++++++++++--
ldap/servers/slapd/back-ldbm/dblayer.c | 25 +++++++--------
ldap/servers/slapd/back-ldbm/dblayer.h | 2 -
ldap/servers/slapd/control.c | 2 -
4 files changed, 64 insertions(+), 18 deletions(-)
New commits:
commit 0e7f59d6c22e02a0604e028b878003ac0baf5a1c
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 28 14:20:23 2014 -0800
Ticket #47463 - IDL-style can become mismatched during partial restoration
The commit to 389-ds-base-1.3.2 and newer is back ported to 389-ds-
1.2.11 trough 1.3.1 by Thomas E Lackey.
commit b43145218dccc8c9c16ecadad80f94bf58c73d57
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Sep 27 17:58:03 2013 -0700
Description by telackey:
When doing a partial/FRI restoration the database files are copied
key-by-key. This is necessary to reset the LSNs so the restored
files can merge into the existing DB environment (cf. dblayer_copy_
file_resetlsns()) in a recoverable way.
However, dblayer_copy_file_keybykey() does not set the comparison
function before calling DB->put(), which means that the restored
files will not necessarily be using the proper function.
While all the keys are technically present, indexed searches can
still fail to return relevant results because the key order is
significant when intersecting the results with the other indices.
Note: The bug was reported and the patch was provided by telackey.
(Thank you, Thomas!)
Additional fix by nhosoi:
The entryrdn index uses its special dup compare function. The dup
compare function is set when the restoring index file is entryrdn.
https://fedorahosted.org/389/ticket/47463
Reviewed by rmeggins (Thank you, Rich!)
(cherry picked from commit abe5c894686f46b60f069f8cbd8aa909b34d81a1)
(cherry picked from commit 9ebe2e80d090537e8f905ef54990bfdec088e267)
diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
index 1165831..b0d17d3 100644
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
@@ -49,7 +49,13 @@
#include "back-ldbm.h"
#include "dblayer.h"
-static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+static int
+dblayer_copy_file_keybykey(DB_ENV *env,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
int retval_cleanup = 0;
@@ -62,6 +68,7 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
int cursor_flag = 0;
int finished = 0;
int mode = 0;
+ char *p = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> dblayer_copy_file_keybykey\n", 0, 0, 0 );
@@ -119,6 +126,40 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, set_pagesize error %d: %s\n", retval, db_strerror(retval), 0);
goto error;
}
+
+ /* TEL 20130412: Make sure to set the dup comparison function if needed.
+ * We key our decision off of the presence of new IDL and dup flags on
+ * the source database. This is similar dblayer_open_file, except that
+ * we don't have the attribute info index mask for VLV. That should be OK
+ * since the DB_DUP and DB_DUPSORT flags wouldn't have been toggled on
+ * unless they passed the check on the source.
+ */
+ /* Entryrdn index has its own dup compare function */
+ if ((p = PL_strcasestr(source_file_name, LDBM_ENTRYRDN_STR)) &&
+ (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
+ /* entryrdn.db */
+ struct attrinfo *ai = NULL;
+ ainfo_get(inst->inst_be, LDBM_ENTRYRDN_STR, &ai);
+ if (ai->ai_dup_cmp_fn) {
+ /* If set, use the special dup compare callback */
+ retval = destination_file->set_dup_compare(destination_file, ai->ai_dup_cmp_fn);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey(entryrdn), set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+ } else if (idl_get_idl_new() && (dbflags & DB_DUP) && (dbflags & DB_DUPSORT)) {
+ retval = destination_file->set_dup_compare(destination_file, idl_new_compare_dups);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey, set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+
retval = (destination_file->open)(destination_file, NULL, destination_file_name, NULL, dbtype, DB_CREATE | DB_EXCL, mode);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, Open error %d: %s\n", retval, db_strerror(retval), 0);
@@ -190,7 +231,13 @@ error:
return retval;
}
-int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+int
+dblayer_copy_file_resetlsns(char *home_dir,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
DB_ENV *env = NULL;
@@ -205,7 +252,7 @@ int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *de
goto out;
}
/* Do the copy */
- retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv);
+ retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv, inst);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_resetlsns: Copy not completed successfully.", 0, 0, 0);
}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 46334bd..844b3b7 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5653,6 +5653,7 @@ dblayer_copy_directory(struct ldbminfo *li,
char inst_dir[MAXPATHLEN];
char sep;
int suffix_len = 0;
+ ldbm_instance *inst = NULL;
if (!src_dir || '\0' == *src_dir)
{
@@ -5676,6 +5677,14 @@ 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;
@@ -5683,15 +5692,6 @@ 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);
@@ -5811,13 +5811,12 @@ dblayer_copy_directory(struct ldbminfo *li,
/* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
/* PL_strcmp takes NULL arg */
if (resetlsns &&
- (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.'))
- == 0)) {
+ (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.')) == 0)) {
return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
- 0, priv);
+ 0, priv, inst);
} else {
return_value = dblayer_copyfile(filename1, filename2,
- 0, priv->dblayer_file_mode);
+ 0, priv->dblayer_file_mode);
}
slapi_ch_free((void**)&filename1);
slapi_ch_free((void**)&filename2);
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
index 7f3200c..4ff9d53 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
@@ -201,7 +201,7 @@ int dblayer_make_private_simple_env(char *db_home_dir, DB_ENV **env);
/* Copy a database file, preserving all its contents (used to reset the LSNs in the file in order to move
* it from one transacted environment to another.
*/
-int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv);
+int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv, ldbm_instance *inst);
/* Turn on the various logging and debug options for DB */
void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c
index e614d50..e7b7562 100644
--- a/ldap/servers/slapd/control.c
+++ b/ldap/servers/slapd/control.c
@@ -361,7 +361,7 @@ get_ldapmessage_controls_ext(
slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &ctrl_not_found);
slapi_pblock_set(pb, SLAPI_PWPOLICY, &ctrl_not_found);
slapi_log_error(SLAPI_LOG_CONNS, "connection", "Warning: conn=%d op=%d contains an empty list of controls\n",
- pb->pb_conn->c_connid, pb->pb_op->o_opid);
+ (int)pb->pb_conn->c_connid, pb->pb_op->o_opid);
} else {
if ((tag != LBER_END_OF_SEQORSET) && (len != -1)) {
goto free_and_return;
ldap/servers/slapd/back-ldbm/dbhelp.c | 53 +++++++++++++++++++++++++++++++--
ldap/servers/slapd/back-ldbm/dblayer.c | 29 ++++++++----------
ldap/servers/slapd/back-ldbm/dblayer.h | 2 -
3 files changed, 65 insertions(+), 19 deletions(-)
New commits:
commit 9ebe2e80d090537e8f905ef54990bfdec088e267
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 28 11:25:34 2014 -0800
Ticket #47463 - IDL-style can become mismatched during partial restoration
The commit to 389-ds-base-1.3.2 and newer is back ported to 389-ds-
1.2.11 trough 1.3.1 by Thomas E Lackey.
commit b43145218dccc8c9c16ecadad80f94bf58c73d57
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Sep 27 17:58:03 2013 -0700
Description by telackey:
When doing a partial/FRI restoration the database files are copied
key-by-key. This is necessary to reset the LSNs so the restored
files can merge into the existing DB environment (cf. dblayer_copy_
file_resetlsns()) in a recoverable way.
However, dblayer_copy_file_keybykey() does not set the comparison
function before calling DB->put(), which means that the restored
files will not necessarily be using the proper function.
While all the keys are technically present, indexed searches can
still fail to return relevant results because the key order is
significant when intersecting the results with the other indices.
Note: The bug was reported and the patch was provided by telackey.
(Thank you, Thomas!)
Additional fix by nhosoi:
The entryrdn index uses its special dup compare function. The dup
compare function is set when the restoring index file is entryrdn.
https://fedorahosted.org/389/ticket/47463
Reviewed by rmeggins (Thank you, Rich!)
(cherry picked from commit abe5c894686f46b60f069f8cbd8aa909b34d81a1)
diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
index 1165831..b0d17d3 100644
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
@@ -49,7 +49,13 @@
#include "back-ldbm.h"
#include "dblayer.h"
-static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+static int
+dblayer_copy_file_keybykey(DB_ENV *env,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
int retval_cleanup = 0;
@@ -62,6 +68,7 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
int cursor_flag = 0;
int finished = 0;
int mode = 0;
+ char *p = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> dblayer_copy_file_keybykey\n", 0, 0, 0 );
@@ -119,6 +126,40 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, set_pagesize error %d: %s\n", retval, db_strerror(retval), 0);
goto error;
}
+
+ /* TEL 20130412: Make sure to set the dup comparison function if needed.
+ * We key our decision off of the presence of new IDL and dup flags on
+ * the source database. This is similar dblayer_open_file, except that
+ * we don't have the attribute info index mask for VLV. That should be OK
+ * since the DB_DUP and DB_DUPSORT flags wouldn't have been toggled on
+ * unless they passed the check on the source.
+ */
+ /* Entryrdn index has its own dup compare function */
+ if ((p = PL_strcasestr(source_file_name, LDBM_ENTRYRDN_STR)) &&
+ (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
+ /* entryrdn.db */
+ struct attrinfo *ai = NULL;
+ ainfo_get(inst->inst_be, LDBM_ENTRYRDN_STR, &ai);
+ if (ai->ai_dup_cmp_fn) {
+ /* If set, use the special dup compare callback */
+ retval = destination_file->set_dup_compare(destination_file, ai->ai_dup_cmp_fn);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey(entryrdn), set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+ } else if (idl_get_idl_new() && (dbflags & DB_DUP) && (dbflags & DB_DUPSORT)) {
+ retval = destination_file->set_dup_compare(destination_file, idl_new_compare_dups);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey, set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+
retval = (destination_file->open)(destination_file, NULL, destination_file_name, NULL, dbtype, DB_CREATE | DB_EXCL, mode);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, Open error %d: %s\n", retval, db_strerror(retval), 0);
@@ -190,7 +231,13 @@ error:
return retval;
}
-int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+int
+dblayer_copy_file_resetlsns(char *home_dir,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
DB_ENV *env = NULL;
@@ -205,7 +252,7 @@ int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *de
goto out;
}
/* Do the copy */
- retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv);
+ retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv, inst);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_resetlsns: Copy not completed successfully.", 0, 0, 0);
}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 5bbc34d..0de7bd9 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5630,6 +5630,7 @@ dblayer_copy_directory(struct ldbminfo *li,
char inst_dir[MAXPATHLEN];
char sep;
int suffix_len = 0;
+ ldbm_instance *inst = NULL;
if (!src_dir || '\0' == *src_dir)
{
@@ -5653,6 +5654,14 @@ 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;
@@ -5660,15 +5669,6 @@ 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);
@@ -5726,7 +5726,7 @@ dblayer_copy_directory(struct ldbminfo *li,
if (NULL == new_dest_dir) {
/* Need to create the new directory where the files will be
* copied to. */
- PRFileInfo info;
+ PRFileInfo64 info;
char *prefix = "";
char mysep = 0;
@@ -5747,7 +5747,7 @@ dblayer_copy_directory(struct ldbminfo *li,
new_dest_dir = slapi_ch_smprintf("%s/%s",
dest_dir, relative_instance_name);
/* } */
- if (PR_SUCCESS == PR_GetFileInfo(new_dest_dir, &info))
+ if (PR_SUCCESS == PR_GetFileInfo64(new_dest_dir, &info))
{
ldbm_delete_dirs(new_dest_dir);
}
@@ -5788,13 +5788,12 @@ dblayer_copy_directory(struct ldbminfo *li,
/* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
/* PL_strcmp takes NULL arg */
if (resetlsns &&
- (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.'))
- == 0)) {
+ (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.')) == 0)) {
return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
- 0, priv);
+ 0, priv, inst);
} else {
return_value = dblayer_copyfile(filename1, filename2,
- 0, priv->dblayer_file_mode);
+ 0, priv->dblayer_file_mode);
}
slapi_ch_free((void**)&filename1);
slapi_ch_free((void**)&filename2);
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
index 7f3200c..4ff9d53 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
@@ -201,7 +201,7 @@ int dblayer_make_private_simple_env(char *db_home_dir, DB_ENV **env);
/* Copy a database file, preserving all its contents (used to reset the LSNs in the file in order to move
* it from one transacted environment to another.
*/
-int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv);
+int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv, ldbm_instance *inst);
/* Turn on the various logging and debug options for DB */
void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
ldap/servers/slapd/back-ldbm/dbhelp.c | 53 +++++++++++++++++++++++++++++++--
ldap/servers/slapd/back-ldbm/dblayer.c | 29 ++++++++----------
ldap/servers/slapd/back-ldbm/dblayer.h | 2 -
3 files changed, 65 insertions(+), 19 deletions(-)
New commits:
commit abe5c894686f46b60f069f8cbd8aa909b34d81a1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 28 11:25:34 2014 -0800
Ticket #47463 - IDL-style can become mismatched during partial restoration
The commit to 389-ds-base-1.3.2 and newer is back ported to 389-ds-
1.2.11 trough 1.3.1 by Thomas E Lackey.
commit b43145218dccc8c9c16ecadad80f94bf58c73d57
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Sep 27 17:58:03 2013 -0700
Description by telackey:
When doing a partial/FRI restoration the database files are copied
key-by-key. This is necessary to reset the LSNs so the restored
files can merge into the existing DB environment (cf. dblayer_copy_
file_resetlsns()) in a recoverable way.
However, dblayer_copy_file_keybykey() does not set the comparison
function before calling DB->put(), which means that the restored
files will not necessarily be using the proper function.
While all the keys are technically present, indexed searches can
still fail to return relevant results because the key order is
significant when intersecting the results with the other indices.
Note: The bug was reported and the patch was provided by telackey.
(Thank you, Thomas!)
Additional fix by nhosoi:
The entryrdn index uses its special dup compare function. The dup
compare function is set when the restoring index file is entryrdn.
https://fedorahosted.org/389/ticket/47463
Reviewed by rmeggins (Thank you, Rich!)
diff --git a/ldap/servers/slapd/back-ldbm/dbhelp.c b/ldap/servers/slapd/back-ldbm/dbhelp.c
index 1165831..b0d17d3 100644
--- a/ldap/servers/slapd/back-ldbm/dbhelp.c
+++ b/ldap/servers/slapd/back-ldbm/dbhelp.c
@@ -49,7 +49,13 @@
#include "back-ldbm.h"
#include "dblayer.h"
-static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+static int
+dblayer_copy_file_keybykey(DB_ENV *env,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
int retval_cleanup = 0;
@@ -62,6 +68,7 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
int cursor_flag = 0;
int finished = 0;
int mode = 0;
+ char *p = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> dblayer_copy_file_keybykey\n", 0, 0, 0 );
@@ -119,6 +126,40 @@ static int dblayer_copy_file_keybykey(DB_ENV *env, char *source_file_name, char
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, set_pagesize error %d: %s\n", retval, db_strerror(retval), 0);
goto error;
}
+
+ /* TEL 20130412: Make sure to set the dup comparison function if needed.
+ * We key our decision off of the presence of new IDL and dup flags on
+ * the source database. This is similar dblayer_open_file, except that
+ * we don't have the attribute info index mask for VLV. That should be OK
+ * since the DB_DUP and DB_DUPSORT flags wouldn't have been toggled on
+ * unless they passed the check on the source.
+ */
+ /* Entryrdn index has its own dup compare function */
+ if ((p = PL_strcasestr(source_file_name, LDBM_ENTRYRDN_STR)) &&
+ (*(p + sizeof(LDBM_ENTRYRDN_STR) - 1) == '.')) {
+ /* entryrdn.db */
+ struct attrinfo *ai = NULL;
+ ainfo_get(inst->inst_be, LDBM_ENTRYRDN_STR, &ai);
+ if (ai->ai_dup_cmp_fn) {
+ /* If set, use the special dup compare callback */
+ retval = destination_file->set_dup_compare(destination_file, ai->ai_dup_cmp_fn);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey(entryrdn), set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+ } else if (idl_get_idl_new() && (dbflags & DB_DUP) && (dbflags & DB_DUPSORT)) {
+ retval = destination_file->set_dup_compare(destination_file, idl_new_compare_dups);
+ if (retval) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "dblayer_copy_file_keybykey, set_dup_compare error %d: %s\n",
+ retval, db_strerror(retval));
+ goto error;
+ }
+ }
+
retval = (destination_file->open)(destination_file, NULL, destination_file_name, NULL, dbtype, DB_CREATE | DB_EXCL, mode);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_keybykey, Open error %d: %s\n", retval, db_strerror(retval), 0);
@@ -190,7 +231,13 @@ error:
return retval;
}
-int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv)
+int
+dblayer_copy_file_resetlsns(char *home_dir,
+ char *source_file_name,
+ char *destination_file_name,
+ int overwrite,
+ dblayer_private *priv,
+ ldbm_instance *inst)
{
int retval = 0;
DB_ENV *env = NULL;
@@ -205,7 +252,7 @@ int dblayer_copy_file_resetlsns(char *home_dir ,char *source_file_name, char *de
goto out;
}
/* Do the copy */
- retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv);
+ retval = dblayer_copy_file_keybykey(env, source_file_name, destination_file_name, overwrite, priv, inst);
if (retval) {
LDAPDebug(LDAP_DEBUG_ANY, "dblayer_copy_file_resetlsns: Copy not completed successfully.", 0, 0, 0);
}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 6b29890..a26c2f0 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -5546,6 +5546,7 @@ dblayer_copy_directory(struct ldbminfo *li,
char inst_dir[MAXPATHLEN];
char sep;
int suffix_len = 0;
+ ldbm_instance *inst = NULL;
if (!src_dir || '\0' == *src_dir)
{
@@ -5569,6 +5570,14 @@ 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;
@@ -5576,15 +5585,6 @@ 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);
@@ -5642,7 +5642,7 @@ dblayer_copy_directory(struct ldbminfo *li,
if (NULL == new_dest_dir) {
/* Need to create the new directory where the files will be
* copied to. */
- PRFileInfo info;
+ PRFileInfo64 info;
char *prefix = "";
char mysep = 0;
@@ -5663,7 +5663,7 @@ dblayer_copy_directory(struct ldbminfo *li,
new_dest_dir = slapi_ch_smprintf("%s/%s",
dest_dir, relative_instance_name);
/* } */
- if (PR_SUCCESS == PR_GetFileInfo(new_dest_dir, &info))
+ if (PR_SUCCESS == PR_GetFileInfo64(new_dest_dir, &info))
{
ldbm_delete_dirs(new_dest_dir);
}
@@ -5704,13 +5704,12 @@ dblayer_copy_directory(struct ldbminfo *li,
/* If the file is a database file, and resetlsns is set, then we need to do a key by key copy */
/* PL_strcmp takes NULL arg */
if (resetlsns &&
- (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.'))
- == 0)) {
+ (PL_strcmp(LDBM_FILENAME_SUFFIX, strrchr(filename1, '.')) == 0)) {
return_value = dblayer_copy_file_resetlsns(src_dir, filename1, filename2,
- 0, priv);
+ 0, priv, inst);
} else {
return_value = dblayer_copyfile(filename1, filename2,
- 0, priv->dblayer_file_mode);
+ 0, priv->dblayer_file_mode);
}
slapi_ch_free((void**)&filename1);
slapi_ch_free((void**)&filename2);
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
index 7f3200c..4ff9d53 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
@@ -201,7 +201,7 @@ int dblayer_make_private_simple_env(char *db_home_dir, DB_ENV **env);
/* Copy a database file, preserving all its contents (used to reset the LSNs in the file in order to move
* it from one transacted environment to another.
*/
-int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv);
+int dblayer_copy_file_resetlsns(char *home_dir, char *source_file_name, char *destination_file_name, int overwrite, dblayer_private *priv, ldbm_instance *inst);
/* Turn on the various logging and debug options for DB */
void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
ldap/servers/slapd/back-ldbm/ldbm_usn.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
New commits:
commit a6f66e7fcbd5d17d975cc2ac65806d7c64571254
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Jan 27 15:15:01 2014 -0800
Ticket #47659 - ldbm_usn_init: Valgrind reports Invalid read / SIGSEGV
Bug description: A suffix mapping tree could exist without the corresponding
backend. The existing code did not properly check the backend returned from
slapi_mapping_tree_find_backend_for_sdn. When NULL backend is returned, it
triggers the NULL pointer dereference.
Fix description: This patch added a NULL backend check to usn_get_last_usn,
and moved a logging to the if clause where the backend is not NULL.
https://fedorahosted.org/389/ticket/47659
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_usn.c b/ldap/servers/slapd/back-ldbm/ldbm_usn.c
index 7c11a68..1ca16b1 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_usn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_usn.c
@@ -80,10 +80,11 @@ ldbm_usn_init(struct ldbminfo *li)
for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
sdn = slapi_get_next_suffix_ext( &node, 0 )) {
be = slapi_mapping_tree_find_backend_for_sdn(sdn);
- slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_usn_init",
- "backend: %s%s\n", be->be_name, isglobal?" (global mode)":"");
rc = usn_get_last_usn(be, &last_usn);
if (0 == rc) { /* only when the last usn is available */
+ slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_usn_init",
+ "backend: %s%s\n", be->be_name,
+ isglobal?" (global mode)":"");
if (isglobal) {
if (isfirst) {
li->li_global_usn_counter = slapi_counter_new();
@@ -126,7 +127,7 @@ usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn)
DBT value;
PRInt64 signed_last_usn;
- if (NULL == last_usn) {
+ if ((NULL == be) || (NULL == last_usn)) {
return rc;
}
ldap/servers/plugins/cos/cos_cache.c | 82 ++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 34 deletions(-)
New commits:
commit 1ebad4bd50fb1483998a32b5d3e232e89aeda0f7
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Jan 24 18:12:32 2014 -0800
Ticket #47649 - Server hangs in cos_cache when adding a user entry
Bug description: cos_dn_defs_cb reads cosDefinition and sets up the cos
Definition part of cos cache. In the function, when processing
cosAttribute, cosTargetTree and cosTemlpateDn are missing, it sets the
parent dn of the cos definition dn. This parent setting is needed only
when the 2 attributes are completely missing from the cos definition.
But if the attributes are located below cosAttribute (see the Example
cos definition), in addition to "cn=cosTemplates,ou=people,dc=example,
dc=com", the parent of "cn=generatePostalCode,ou=People,dc=example,dc=com"
is added to the cos cache as cosTemplateDn.
Example cos definition:
dn: cn=generatePostalCode,ou=People,dc=example,dc=com
description: generate postalCode attr based on location
objectClass: top
objectClass: ldapsubentry
objectClass: cossuperdefinition
objectClass: cosClassicDefinition
cosAttribute: postalCode
costemplatedn: cn=cosTemplates,ou=people,dc=example,dc=com
cosSpecifier: l
cn: generatePostalCode
The mistakenly added cosTemplatedDn makes adding an entry under ou=People
notify recreating the cos cache. The notification needs to be outside of
backend transaction since it causes a deadlock with the cos_cache_wait_
on_change thread which cannot read the DB due to the transaction but holds
the lock that the notifier thread is waiting for.
Fix description: The parent of the cos definition dn is set to the
cosTargetTree and the cosTemlpateDn, only when the attributes are
completely missing.
https://fedorahosted.org/389/ticket/47649
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!!)
(cherry picked from commit 1e52401d3abd0377f55676f4a1508a02aaa7f955)
(cherry picked from commit 01c0794cde7eb91a1a4e477a0286533df4a4ae38)
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index fed2aa9..a68e59f 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -727,7 +727,8 @@ struct dn_defs_info {
* if a particular attempt to add a definition fails: info.ret gets set to
* zero only if we succed to add a def.
*/
-static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
+static int
+cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
{
struct dn_defs_info *info;
cosAttrValue **pSneakyVal = 0;
@@ -877,31 +878,10 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dnVals[valIndex]->bv_val);
}
- if(!pCosTargetTree)
- {
- /* get the parent of the definition */
- char *orig = slapi_dn_parent(pDn->val);
- Slapi_DN *psdn = slapi_sdn_new_dn_byval(orig);
- char *parent = (char *)slapi_sdn_get_dn(psdn);
- if (!parent) {
- parent = (char *)slapi_sdn_get_udn(psdn);
- LDAPDebug(LDAP_DEBUG_ANY,
- "cos_cache_build_definition_list: "
- "failed to normalize parent dn %s. "
- "Adding the pre normalized dn.\n",
- parent, 0, 0);
- }
- cos_cache_add_attrval(&pCosTargetTree, parent);
- if (!pCosTemplateDn) {
- cos_cache_add_attrval(&pCosTemplateDn, parent);
- }
- slapi_sdn_free(&psdn);
- }
-
slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle,
dnVals[valIndex]->bv_val, NULL, NULL);
} /* if(attrType is cosAttribute) */
-
+
/*
* Add the attributetype to the appropriate
* list.
@@ -913,6 +893,47 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
ber_bvecfree( dnVals );
dnVals = NULL;
} while(!slapi_entry_next_attr(e, dnAttr, &dnAttr));
+
+ if (pCosAttribute && (!pCosTargetTree || !pCosTemplateDn)) {
+ /* get the parent of the definition */
+ char *orig = slapi_dn_parent(pDn->val);
+ char *parent = NULL;
+ if (orig) {
+ parent = slapi_create_dn_string("%s", orig);
+ if (!parent) {
+ parent = orig;
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "cos_dn_defs_cb: "
+ "failed to normalize parent dn %s. "
+ "Adding the pre normalized dn.\n",
+ parent);
+ }
+ if (!pCosTargetTree) {
+ cos_cache_add_attrval(&pCosTargetTree, parent);
+ }
+ if (!pCosTemplateDn) {
+ cos_cache_add_attrval(&pCosTemplateDn, parent);
+ }
+ if (parent != orig) {
+ slapi_ch_free_string(&parent);
+ }
+ slapi_ch_free_string(&orig);
+ } else {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "cos_dn_defs_cb: "
+ "failed to get parent dn of cos definition %s.\n",
+ pDn->val);
+ if (!pCosTemplateDn) {
+ if (!pCosTargetTree) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTargetTree and cosTemplateDn are not set.\n");
+ } else {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTemplateDn is not set.\n");
+ }
+ } else if (!pCosTargetTree) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTargetTree is not set.\n");
+ }
+ }
+ }
/*
determine the type of class of service scheme
@@ -951,9 +972,7 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
*/
/* these must exist */
- if( pDn &&
- pObjectclass &&
-
+ if(pDn && pObjectclass &&
(
(cosType == COSTYPE_CLASSIC &&
pCosTemplateDn &&
@@ -3582,14 +3601,9 @@ static int cos_cache_entry_is_cos_related( Slapi_Entry *e) {
{
pObj = (char*)slapi_value_get_string(val);
- /*
- * objectclasses are ascii--maybe strcasecmp() is faster than
- * slapi_utf8casecmp()
- */
- if( !strcasecmp(pObj, "cosdefinition") ||
- !strcasecmp(pObj, "cossuperdefinition") ||
- !strcasecmp(pObj, "costemplate")
- )
+ if(!strcasecmp(pObj, "cosdefinition") ||
+ !strcasecmp(pObj, "cossuperdefinition") ||
+ !strcasecmp(pObj, "costemplate"))
{
rc = 1;
}