andykimpe / rpms / 389-ds-base

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