|
|
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 |
|