andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone

Blame SOURCES/0058-Ticket-48964-cleanallruv-changelog-purging-removes-w.patch

4aa5b2
From abd1c1d0e098dfd071ab12dad075870d88495783 Mon Sep 17 00:00:00 2001
4aa5b2
From: Mark Reynolds <mreynolds@redhat.com>
4aa5b2
Date: Thu, 22 Dec 2016 14:38:27 -0500
4aa5b2
Subject: [PATCH] Ticket 48964 - cleanallruv changelog purging removes wrong
4aa5b2
 rid
4aa5b2
4aa5b2
Bug Description:  A regression from the previous patch uses the local replica
4aa5b2
                  object to locate the correct changelog file, but the rid to
4aa5b2
                  be clean is not the same rid from the replica object.  So the
4aa5b2
                  local replica object's rid is used accidentally to purge the
4aa5b2
                  change log.
4aa5b2
4aa5b2
Fix Description:  Instead if passing the replica object to the changelog purging
4aa5b2
                  code, create a new purge_data struct to hold all the neccessary
4aa5b2
                  data to purge the correct changelog file and the cleaned rid.
4aa5b2
4aa5b2
https://fedorahosted.org/389/ticket/48964
4aa5b2
4aa5b2
Reviewed by: nhosoi(Thanks!)
4aa5b2
4aa5b2
(cherry picked from commit a38d76d27970b5b6facf2ffbd1bce9d6979e6297)
4aa5b2
(cherry picked from commit 4053587d5dfb9c4b4e5cd966cabb1adc624511d6)
4aa5b2
---
4aa5b2
 ldap/servers/plugins/replication/cl5_api.c         | 54 +++++++++++++---------
4aa5b2
 ldap/servers/plugins/replication/cl5_api.h         |  2 +-
4aa5b2
 ldap/servers/plugins/replication/repl5.h           |  8 ++++
4aa5b2
 .../plugins/replication/repl5_replica_config.c     | 12 ++++-
4aa5b2
 4 files changed, 50 insertions(+), 26 deletions(-)
4aa5b2
4aa5b2
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
4aa5b2
index f8b2cea..66c2677 100644
4aa5b2
--- a/ldap/servers/plugins/replication/cl5_api.c
4aa5b2
+++ b/ldap/servers/plugins/replication/cl5_api.c
4aa5b2
@@ -3500,12 +3500,12 @@ static void _cl5DoTrimming ()
4aa5b2
  * changelog for the backend that is being cleaned, and purge all the records
4aa5b2
  * with the cleaned rid.
4aa5b2
  */
4aa5b2
-static void _cl5DoPurging (Replica *replica)
4aa5b2
+static void _cl5DoPurging (cleanruv_purge_data *purge_data)
4aa5b2
 {
4aa5b2
-	ReplicaId rid = replica_get_rid(replica);
4aa5b2
-	const Slapi_DN *sdn = replica_get_root(replica);
4aa5b2
-	const char *replName = replica_get_name(replica);
4aa5b2
-	char *replGen = replica_get_generation(replica);
4aa5b2
+	ReplicaId rid = purge_data->cleaned_rid;
4aa5b2
+	const Slapi_DN *suffix_sdn = purge_data->suffix_sdn;
4aa5b2
+	const char *replName = purge_data->replName;
4aa5b2
+	char *replGen = purge_data->replGen;
4aa5b2
 	char *fileName;
4aa5b2
 	Object *obj;
4aa5b2
 
4aa5b2
@@ -3517,18 +3517,15 @@ static void _cl5DoPurging (Replica *replica)
4aa5b2
 		_cl5PurgeRID (obj, rid);
4aa5b2
 		object_release (obj);
4aa5b2
 		slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
4aa5b2
-			"Purged rid (%d) from suffix (%s)\n",
4aa5b2
-			rid, slapi_sdn_get_dn(sdn));
4aa5b2
+			"_cl5DoPurging - Purged rid (%d) from suffix (%s)\n",
4aa5b2
+			rid, slapi_sdn_get_dn(suffix_sdn));
4aa5b2
 	} else {
4aa5b2
 		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
4aa5b2
-			"Purge rid (%d) failed to find changelog file (%s) for suffix (%s)\n",
4aa5b2
-			rid, fileName, slapi_sdn_get_dn(sdn));
4aa5b2
+			"_cl5DoPurging - Purge rid (%d) failed to find changelog file (%s) for suffix (%s)\n",
4aa5b2
+			rid, fileName, slapi_sdn_get_dn(suffix_sdn));
4aa5b2
 	}
4aa5b2
 	PR_Unlock (s_cl5Desc.dbTrim.lock);
4aa5b2
 
4aa5b2
-	slapi_ch_free_string(&replGen);
4aa5b2
-	slapi_ch_free_string(&fileName);
4aa5b2
-
4aa5b2
 	return;
4aa5b2
 }
4aa5b2
 
4aa5b2
@@ -6983,19 +6980,27 @@ cl5CleanRUV(ReplicaId rid){
4aa5b2
     slapi_rwlock_unlock (s_cl5Desc.stLock);
4aa5b2
 }
4aa5b2
 
4aa5b2
+static void free_purge_data(cleanruv_purge_data *purge_data)
4aa5b2
+{
4aa5b2
+    slapi_ch_free_string(&purge_data->replGen);
4aa5b2
+    slapi_ch_free_string(&purge_data->replName);
4aa5b2
+    slapi_ch_free((void **)&purge_data);
4aa5b2
+}
4aa5b2
+
4aa5b2
 /*
4aa5b2
  * Create a thread to purge a changelog of cleaned RIDs
4aa5b2
  */
4aa5b2
-void trigger_cl_purging(Replica *replica){
4aa5b2
+void trigger_cl_purging(cleanruv_purge_data *purge_data){
4aa5b2
     PRThread *trim_tid = NULL;
4aa5b2
 
4aa5b2
     trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_purging_thread,
4aa5b2
-                   (void *)replica, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
4aa5b2
+                   (void *)purge_data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
4aa5b2
                    PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE);
4aa5b2
     if (NULL == trim_tid){
4aa5b2
         slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
4aa5b2
-            "trigger_cl_purging: failed to create trimming "
4aa5b2
+            "trigger_cl_purging: failed to create cl trimming "
4aa5b2
             "thread; NSPR error - %d\n", PR_GetError ());
4aa5b2
+        free_purge_data(purge_data);
4aa5b2
     } else {
4aa5b2
         /* need a little time for the thread to get started */
4aa5b2
         DS_Sleep(PR_SecondsToInterval(1));
4aa5b2
@@ -7007,13 +7012,12 @@ void trigger_cl_purging(Replica *replica){
4aa5b2
  */
4aa5b2
 void
4aa5b2
 trigger_cl_purging_thread(void *arg){
4aa5b2
-    Replica *replica = (Replica *)arg;
4aa5b2
+    cleanruv_purge_data *purge_data = (cleanruv_purge_data *)arg;
4aa5b2
 
4aa5b2
     /* Make sure we have a change log, and we aren't closing it */
4aa5b2
-    if (replica == NULL ||
4aa5b2
-        s_cl5Desc.dbState == CL5_STATE_CLOSED ||
4aa5b2
+    if (s_cl5Desc.dbState == CL5_STATE_CLOSED ||
4aa5b2
         s_cl5Desc.dbState == CL5_STATE_CLOSING) {
4aa5b2
-        return;
4aa5b2
+        goto free_and_return;
4aa5b2
     }
4aa5b2
 
4aa5b2
     /* Bump the changelog thread count */
4aa5b2
@@ -7021,13 +7025,17 @@ trigger_cl_purging_thread(void *arg){
4aa5b2
         slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
4aa5b2
             "trigger_cl_purging: Abort - failed to increment thread count "
4aa5b2
             "NSPR error - %d\n", PR_GetError ());
4aa5b2
-        return;
4aa5b2
+        goto free_and_return;
4aa5b2
     }
4aa5b2
 
4aa5b2
     /* Purge the changelog */
4aa5b2
-    _cl5DoPurging(replica);
4aa5b2
+    _cl5DoPurging(purge_data);
4aa5b2
     _cl5RemoveThread();
4aa5b2
+
4aa5b2
     slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
4aa5b2
-        "trigger_cl_purging: purged changelog for (%s) rid (%d)\n",
4aa5b2
-        slapi_sdn_get_dn(replica_get_root(replica)), replica_get_rid(replica));
4aa5b2
+        "trigger_cl_purging_thread - purged changelog for (%s) rid (%d)\n",
4aa5b2
+        slapi_sdn_get_dn(purge_data->suffix_sdn), purge_data->cleaned_rid);
4aa5b2
+
4aa5b2
+free_and_return:
4aa5b2
+    free_purge_data(purge_data);
4aa5b2
 }
4aa5b2
diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h
4aa5b2
index 1a1c2f5..e33601d 100644
4aa5b2
--- a/ldap/servers/plugins/replication/cl5_api.h
4aa5b2
+++ b/ldap/servers/plugins/replication/cl5_api.h
4aa5b2
@@ -467,6 +467,6 @@ int cl5WriteRUV();
4aa5b2
 int cl5DeleteRUV();
4aa5b2
 void cl5CleanRUV(ReplicaId rid);
4aa5b2
 void cl5NotifyCleanup(int rid);
4aa5b2
-void trigger_cl_purging(Replica *replica);
4aa5b2
+void trigger_cl_purging(cleanruv_purge_data *purge_data);
4aa5b2
 
4aa5b2
 #endif
4aa5b2
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
4aa5b2
index 6582876..4ab2355 100644
4aa5b2
--- a/ldap/servers/plugins/replication/repl5.h
4aa5b2
+++ b/ldap/servers/plugins/replication/repl5.h
4aa5b2
@@ -704,6 +704,14 @@ typedef struct _cleanruv_data
4aa5b2
 	char *force;
4aa5b2
 } cleanruv_data;
4aa5b2
 
4aa5b2
+typedef struct _cleanruv_purge_data
4aa5b2
+{
4aa5b2
+	int cleaned_rid;
4aa5b2
+	const Slapi_DN *suffix_sdn;
4aa5b2
+	char *replName;
4aa5b2
+	char *replGen;
4aa5b2
+} cleanruv_purge_data;
4aa5b2
+
4aa5b2
 /* replutil.c */
4aa5b2
 LDAPControl* create_managedsait_control ();
4aa5b2
 LDAPControl* create_backend_control(Slapi_DN *sdn);
4aa5b2
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
4aa5b2
index 59e5298..d78d982 100644
4aa5b2
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
4aa5b2
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
4aa5b2
@@ -1434,6 +1434,7 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
4aa5b2
 	Object *RUVObj;
4aa5b2
 	RUV *local_ruv = NULL;
4aa5b2
 	Replica *replica = (Replica*)object_get_data (r);
4aa5b2
+	cleanruv_purge_data *purge_data;
4aa5b2
 	int rc = 0;
4aa5b2
 	PR_ASSERT (replica);
4aa5b2
 
4aa5b2
@@ -1465,9 +1466,16 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
4aa5b2
 	cl5CleanRUV(rid);
4aa5b2
 
4aa5b2
 	/*
4aa5b2
-	 * Now purge the changelog
4aa5b2
+	 * Now purge the changelog.  The purging thread will free the purge_data
4aa5b2
 	 */
4aa5b2
-	trigger_cl_purging(replica);
4aa5b2
+	if (replica){
4aa5b2
+		purge_data = (cleanruv_purge_data*)slapi_ch_calloc(1, sizeof(cleanruv_purge_data));
4aa5b2
+		purge_data->cleaned_rid = rid;
4aa5b2
+		purge_data->suffix_sdn = replica_get_root(replica);
4aa5b2
+		purge_data->replName = (char *)replica_get_name(replica);
4aa5b2
+		purge_data->replGen = replica_get_generation(replica);
4aa5b2
+		trigger_cl_purging(purge_data);
4aa5b2
+	}
4aa5b2
 
4aa5b2
 	if (rc != RUV_SUCCESS){
4aa5b2
 		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_task: task failed(%d)\n",rc);
4aa5b2
-- 
4aa5b2
2.7.4
4aa5b2