|
|
dc8c34 |
From 84c69dee99ae60b9a571b41bb84514a15eec7b74 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
dc8c34 |
Date: Wed, 15 May 2013 19:39:24 -0600
|
|
|
dc8c34 |
Subject: [PATCH 60/99] Ticket #47362 - ipa upgrade selinuxusermap data not
|
|
|
dc8c34 |
replicating
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47362
|
|
|
dc8c34 |
Reviewed by: nhosoi (Thanks!)
|
|
|
dc8c34 |
Branch: 389-ds-base-1.2.11
|
|
|
dc8c34 |
Fix Description: When nsslapd-port is set to 0, this causes the
|
|
|
dc8c34 |
replica purl to be "ldap://hostname:0". At startup, the MMR code looks to
|
|
|
dc8c34 |
see if this replica purl is in the RUV, by doing a string comparison of this
|
|
|
dc8c34 |
purl with the ruv replica purl. If it is not there, the MMR code wipes out
|
|
|
dc8c34 |
this ruv element. Later the code in replica_check_for_data_reload() uses
|
|
|
dc8c34 |
this RUV to see if it needs to reinit the changelog. Since the RUV doesn't
|
|
|
dc8c34 |
match the changelog RUV any more, the changelog is erased, which erases
|
|
|
dc8c34 |
any changes that were made in the meantime. The missing RUV element causes
|
|
|
dc8c34 |
the supplier to attempt to send over changes which may already exist on the
|
|
|
dc8c34 |
consumer. If one of these is an ADD, the urp code will correctly flag this
|
|
|
dc8c34 |
as an attempt to add an entry that already exists, and will turn this into
|
|
|
dc8c34 |
a replConflict entry. A subsequent attempt to replicate the same ADD will
|
|
|
dc8c34 |
cause an error in the urp code which will cause it to return err=53.
|
|
|
dc8c34 |
Replication will then become stuck on this update - it will keep trying to
|
|
|
dc8c34 |
send it over and over again, and will not be able to proceed.
|
|
|
dc8c34 |
The only workaround is a replica reinit of the replica, to get the database
|
|
|
dc8c34 |
RUV and changelog in a consistent state.
|
|
|
dc8c34 |
I've also added some additional RUV debugging when using the REPL log level.
|
|
|
dc8c34 |
Platforms tested: RHEL6 x86_64
|
|
|
dc8c34 |
Flag Day: no
|
|
|
dc8c34 |
Doc impact: no
|
|
|
dc8c34 |
(cherry picked from commit 0c194eb79aa381bf4e4cd05082956218512115a4)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
.../plugins/replication/repl5_inc_protocol.c | 38 ++++++++++++++++++++++
|
|
|
dc8c34 |
ldap/servers/plugins/replication/repl5_ruv.c | 32 ++++++++++++++++++
|
|
|
dc8c34 |
2 files changed, 70 insertions(+)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
dc8c34 |
index 743be57..82b121c 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
dc8c34 |
@@ -1931,6 +1931,44 @@ repl5_inc_stop(Private_Repl_Protocol *prp)
|
|
|
dc8c34 |
agmt_get_long_name(prp->agmt),
|
|
|
dc8c34 |
PR_IntervalToSeconds(now-start));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
|
|
|
dc8c34 |
+ if (NULL == prp->replica_object) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "%s: repl5_inc_stop: protocol replica_object is NULL\n",
|
|
|
dc8c34 |
+ agmt_get_long_name(prp->agmt));
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ Replica *replica;
|
|
|
dc8c34 |
+ object_acquire(prp->replica_object);
|
|
|
dc8c34 |
+ replica = object_get_data(prp->replica_object);
|
|
|
dc8c34 |
+ if (NULL == replica) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "%s: repl5_inc_stop: replica is NULL\n",
|
|
|
dc8c34 |
+ agmt_get_long_name(prp->agmt));
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ Object *ruv_obj = replica_get_ruv(replica);
|
|
|
dc8c34 |
+ if (NULL == ruv_obj) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "%s: repl5_inc_stop: ruv_obj is NULL\n",
|
|
|
dc8c34 |
+ agmt_get_long_name(prp->agmt));
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ RUV *ruv;
|
|
|
dc8c34 |
+ object_acquire(ruv_obj);
|
|
|
dc8c34 |
+ ruv = (RUV*)object_get_data (ruv_obj);
|
|
|
dc8c34 |
+ if (NULL == ruv) {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "%s: repl5_inc_stop: ruv is NULL\n",
|
|
|
dc8c34 |
+ agmt_get_long_name(prp->agmt));
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ ruv_dump(ruv, "Database RUV", NULL);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ object_release(ruv_obj);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ object_release(prp->replica_object);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
return return_value;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
|
|
|
dc8c34 |
index b52dd49..8fbd89c 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_ruv.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
|
|
|
dc8c34 |
@@ -208,6 +208,9 @@ ruv_init_from_slapi_attr_and_check_purl(Slapi_Attr *attr, RUV **ruv, ReplicaId *
|
|
|
dc8c34 |
Slapi_Value *value;
|
|
|
dc8c34 |
const struct berval *bval;
|
|
|
dc8c34 |
const char *purl = NULL;
|
|
|
dc8c34 |
+ char *localhost = get_localhost_DNS();
|
|
|
dc8c34 |
+ size_t localhostlen = localhost ? strlen(localhost) : 0;
|
|
|
dc8c34 |
+ int port = config_get_port();
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return_value = RUV_SUCCESS;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -236,16 +239,30 @@ ruv_init_from_slapi_attr_and_check_purl(Slapi_Attr *attr, RUV **ruv, ReplicaId *
|
|
|
dc8c34 |
RUVElement *ruve = get_ruvelement_from_berval(bval);
|
|
|
dc8c34 |
if (NULL != ruve)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ char *ptr;
|
|
|
dc8c34 |
/* Is the local purl already in the ruv ? */
|
|
|
dc8c34 |
if ( (*contain_purl==0) && ruve->replica_purl && purl && (strncmp(ruve->replica_purl, purl, strlen(purl))==0) )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
*contain_purl = ruve->rid;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ /* ticket 47362 - nsslapd-port: 0 causes replication to break */
|
|
|
dc8c34 |
+ else if ((*contain_purl==0) && ruve->replica_purl && (port == 0) && localhost &&
|
|
|
dc8c34 |
+ (ptr = strstr(ruve->replica_purl, localhost)) && (ptr != ruve->replica_purl) &&
|
|
|
dc8c34 |
+ (*(ptr - 1) == '/') && (*(ptr+localhostlen) == ':'))
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ /* same hostname, but port number may have been temporarily set to 0
|
|
|
dc8c34 |
+ * just allow it with whatever port number is already in the replica_purl
|
|
|
dc8c34 |
+ * do not reset the port number, do not tell the configure_ruv code that there
|
|
|
dc8c34 |
+ * is anything wrong
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ *contain_purl = ruve->rid;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
dl_add ((*ruv)->elements, ruve);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ slapi_ch_free_string(&localhost);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
return return_value;
|
|
|
dc8c34 |
@@ -1279,6 +1296,11 @@ ruv_compare_ruv(const RUV *ruv1, const char *ruv1name, const RUV *ruv2, const ch
|
|
|
dc8c34 |
const char *ruvbnames[] = {ruv2name, ruv1name};
|
|
|
dc8c34 |
const int nitems = 2;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
|
|
|
dc8c34 |
+ ruv_dump(ruv1, (char *)ruv1name, NULL);
|
|
|
dc8c34 |
+ ruv_dump(ruv2, (char *)ruv2name, NULL);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
/* compare replica generations first */
|
|
|
dc8c34 |
if (ruv1->replGen == NULL || ruv2->replGen == NULL) {
|
|
|
dc8c34 |
slapi_log_error(loglevel, repl_plugin_name,
|
|
|
dc8c34 |
@@ -1335,7 +1357,17 @@ ruv_compare_ruv(const RUV *ruv1, const char *ruv1name, const RUV *ruv2, const ch
|
|
|
dc8c34 |
"than the max CSN [%s] from RUV [%s] for element [%s]\n",
|
|
|
dc8c34 |
csnstrb, ruvbname, csnstra, ruvaname, ruvelem);
|
|
|
dc8c34 |
rc = RUV_COMP_CSN_DIFFERS;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ csn_as_string(replicaa->csn, PR_FALSE, csnstra);
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "ruv_compare_ruv: the max CSN [%s] from RUV [%s] is less than "
|
|
|
dc8c34 |
+ "or equal to the max CSN [%s] from RUV [%s] for element [%s]\n",
|
|
|
dc8c34 |
+ csnstrb, ruvbname, csnstra, ruvaname, ruvelem);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
dc8c34 |
+ "ruv_compare_ruv: RUV [%s] has an empty CSN\n",
|
|
|
dc8c34 |
+ ruvbname);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|