andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
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