From 7a0e4c959bbd768475ed3711f51edf23462ab8f6 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Thu, 18 Oct 2012 10:30:54 -0400
Subject: [PATCH] Ticket 403 - CLEANALLRUV - minor fixes and add support for replica-force-cleaning

Description:  Improved maxcsn checking of remote replicas.  Added check for running
              duplicate clean/abort tasks, added check to prevent multiple threads
              from being created, and added a new option:

                  replica-force-cleaning: yes

                  - This skips the maxcsn checks
---
 ldap/servers/plugins/replication/repl5.h           |    3 +
 ldap/servers/plugins/replication/repl5_replica.c   |    2 +
 .../plugins/replication/repl5_replica_config.c     |  135 ++++++++++++++++++--
 ldap/servers/plugins/replication/repl_extop.c      |   33 +++--
 4 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 1637057..31231ac 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -616,8 +616,10 @@ CSN *replica_get_cleanruv_maxcsn(Replica *r, ReplicaId rid);
 void ruv_get_cleaned_rids(RUV *ruv, ReplicaId *rids);
 void add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root);
 int is_task_aborted(ReplicaId rid);
+int is_pre_cleaned_rid(ReplicaId rid);
 void delete_aborted_rid(Replica *replica, ReplicaId rid, char *repl_root);
 void set_cleaned_rid(ReplicaId rid);
+void set_aborted_rid(ReplicaId rid);
 void cleanruv_log(Slapi_Task *task, char *task_type, char *fmt, ...);
 
 #define CLEANRIDSIZ 4 /* maximum number for concurrent CLEANALLRUV tasks */
@@ -633,6 +635,7 @@ typedef struct _cleanruv_data
 	char *repl_root;
 	Slapi_DN *sdn;
 	char *certify;
+	char *force;
 } cleanruv_data;
 
 /* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index c956647..ec0b113 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1863,6 +1863,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
             csn_init_by_string(maxcsn, csnpart);
             csn_as_string(maxcsn, PR_FALSE, csnstr);
             add_cleaned_rid(rid, r, csnstr);
+            set_cleaned_rid(rid);
 
             slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: cleanAllRUV task found, "
                 "resuming the cleaning of rid(%d)...\n", rid);
@@ -1951,6 +1952,7 @@ done:
             stop_ruv_cleaning();
             maxcsn = replica_get_cleanruv_maxcsn(r, rid);
             delete_cleaned_rid(r, rid, maxcsn);
+            set_aborted_rid(rid);
             csn_free(&maxcsn);
 
             slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: abort task found, "
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 752b09b..fe34f4b 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -64,6 +64,7 @@
 
 int slapi_log_urp = SLAPI_LOG_REPL;
 static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0};
+static ReplicaId pre_cleaned_rids[CLEANRIDSIZ + 1] = {0};
 static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0};
 static Slapi_RWLock *rid_lock = NULL;
 static Slapi_RWLock *abort_rid_lock = NULL;
@@ -84,7 +85,7 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
 static int replica_execute_cl2ldif_task (Object *r, char *returntext);
 static int replica_execute_ldif2cl_task (Object *r, char *returntext);
 static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext);
+static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, char *returntext);
 static void replica_cleanallruv_thread(void *arg);
 static void replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task);
 static int check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task);
@@ -96,6 +97,7 @@ static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt);
 static int replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task);
 static int get_cleanruv_task_count();
 static int get_abort_cleanruv_task_count();
+static void preset_cleaned_rid(ReplicaId rid);
 static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
 static int replica_task_done(Replica *replica);
 static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
@@ -893,7 +895,7 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
 		if (apply_mods)
 		{
 			Slapi_Task *empty_task = NULL;
-			return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, empty_task, returntext);
+			return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, empty_task, "no", returntext);
 		}
 		else
 			return LDAP_SUCCESS;
@@ -1231,11 +1233,13 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
     Object *r;
     const char *base_dn;
     const char *rid_str;
+    const char *force_cleaning;
     ReplicaId rid;
     int rc = SLAPI_DSE_CALLBACK_OK;
 
     /* allocate new task now */
     task = slapi_new_task(slapi_entry_get_ndn(e));
+    task_dn = slapi_entry_get_sdn(e);
     if(task == NULL){
         slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to create new task\n");
         rc = SLAPI_DSE_CALLBACK_ERROR;
@@ -1255,8 +1259,21 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
         rc = SLAPI_DSE_CALLBACK_ERROR;
         goto out;
     }
+    if ((force_cleaning = fetch_attr(e, "replica-force-cleaning", 0)) != NULL){
+        if(strcasecmp(force_cleaning,"yes") != 0 && strcasecmp(force_cleaning,"no") != 0){
+            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for replica-force-cleaning "
+                "(%s).  Value must be \"yes\" or \"no\" for task - (%s)",
+                force_cleaning, slapi_sdn_get_dn(task_dn));
+            cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+            *returncode = LDAP_OPERATIONS_ERROR;
+            rc = SLAPI_DSE_CALLBACK_ERROR;
+            goto out;
+        }
+    } else {
+        force_cleaning = "no";
+    }
+
 
-    task_dn = slapi_entry_get_sdn(e);
     /*
      *  Check the rid
      */
@@ -1269,6 +1286,14 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
         rc = SLAPI_DSE_CALLBACK_ERROR;
         goto out;
     }
+    if(is_cleaned_rid(rid)){
+        /* we are already cleaning this rid */
+    	PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica id (%d) is already being cleaned", rid);
+        cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+        *returncode = LDAP_UNWILLING_TO_PERFORM;
+        rc = SLAPI_DSE_CALLBACK_ERROR;
+        goto out;
+    }
     /*
      *  Get the replica object
      */
@@ -1282,7 +1307,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
     }
 
     /* clean the RUV's */
-    rc = replica_execute_cleanall_ruv_task (r, rid, task, returntext);
+    rc = replica_execute_cleanall_ruv_task (r, rid, task, force_cleaning, returntext);
 
 out:
     if(rc){
@@ -1305,7 +1330,7 @@ out:
  *
  */
 static int
-replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext)
+replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, const char* force_cleaning, char *returntext)
 {
     PRThread *thread = NULL;
     Slapi_Task *pre_task = NULL; /* this is supposed to be null for logging */
@@ -1374,7 +1399,7 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
     /*
      *  Create payload
      */
-    ridstr = slapi_ch_smprintf("%d:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)), csnstr);
+    ridstr = slapi_ch_smprintf("%d:%s:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)), csnstr, force_cleaning);
     payload = create_ruv_payload(ridstr);
     slapi_ch_free_string(&ridstr);
 
@@ -1400,12 +1425,14 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
     data->maxcsn = maxcsn;
     data->payload = payload;
     data->sdn = NULL;
+    data->force = slapi_ch_strdup(force_cleaning);
 
     thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread,
         (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
         PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
     if (thread == NULL) {
         rc = -1;
+        slapi_ch_free_string(&data->force);
         goto fail;
     } else {
         goto done;
@@ -1501,6 +1528,7 @@ replica_cleanallruv_thread(void *arg)
     }
     rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
     csn_as_string(data->maxcsn, PR_FALSE, csnstr);
+    preset_cleaned_rid(data->rid); /* this prevents duplicate thread creation */
 
     /*
      *  Add the cleanallruv task to the repl config - so we can handle restarts
@@ -1514,7 +1542,7 @@ replica_cleanallruv_thread(void *arg)
     ruv_obj = replica_get_ruv(data->replica);
     ruv = object_get_data (ruv_obj);
     while(data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){
-        if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_cleanallruv(ruv,data->maxcsn)){
+        if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_cleanallruv(ruv,data->maxcsn) || strcasecmp(data->force,"yes") == 0){
             /* We are caught up, now we can clean the ruv's */
             break;
         }
@@ -1525,6 +1553,8 @@ replica_cleanallruv_thread(void *arg)
     object_release(ruv_obj);
     /*
      *  Next, make sure all the replicas are up and running before sending off the clean ruv tasks
+     *
+     *  Even if we are forcing the cleaning, the replicas still need to be up
      */
     cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to be online...");
     if(check_agmts_are_alive(data->replica, data->rid, data->task)){
@@ -1536,7 +1566,7 @@ replica_cleanallruv_thread(void *arg)
      *  Make sure all the replicas have seen the max csn
      */
     cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to receive all the deleted replica updates...");
-    if(check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
+    if(strcasecmp(data->force,"no") == 0 && check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
         /* error, aborted or shutdown */
         aborted = 1;
         goto done;
@@ -1567,6 +1597,7 @@ replica_cleanallruv_thread(void *arg)
                 agmt_not_notified = 0;
             } else {
                 agmt_not_notified = 1;
+                cleanruv_log(data->task, CLEANALLRUV_ID, "Failed to send task to replica (%s)",agmt_get_long_name(agmt));
                 break;
             }
             agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
@@ -1620,6 +1651,7 @@ replica_cleanallruv_thread(void *arg)
             if(replica_cleanallruv_check_ruv(agmt, rid_text, data->task) == 0){
                 found_dirty_rid = 0;
             } else {
+                cleanruv_log(data->task, CLEANALLRUV_ID,"Replica is not cleaned yet (%s)",agmt_get_long_name(agmt));
                 found_dirty_rid = 1;
                 break;
             }
@@ -1679,6 +1711,7 @@ done:
         object_release(data->repl_obj);
     }
     slapi_sdn_free(&data->sdn);
+    slapi_ch_free_string(&data->force);
     slapi_ch_free_string(&rid_text);
     csn_free(&data->maxcsn);
     slapi_ch_free((void **)&data);
@@ -1715,6 +1748,7 @@ check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_T
                 not_all_caughtup = 0;
             } else {
                 not_all_caughtup = 1;
+                cleanruv_log(task, CLEANALLRUV_ID, "Replica not caught up (%s)",agmt_get_long_name(agmt));
                 break;
             }
             agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
@@ -1771,6 +1805,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
                 not_all_alive = 0;
             } else {
                 not_all_alive = 1;
+                cleanruv_log(task, CLEANALLRUV_ID, "Replica not online (%s)",agmt_get_long_name(agmt));
                 break;
             }
             agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
@@ -1914,6 +1949,23 @@ is_cleaned_rid(ReplicaId rid)
 }
 
 int
+is_pre_cleaned_rid(ReplicaId rid)
+{
+    int i;
+
+    slapi_rwlock_rdlock(rid_lock);
+    for(i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != 0; i++){
+        if(rid == pre_cleaned_rids[i]){
+            slapi_rwlock_unlock(rid_lock);
+            return 1;
+        }
+    }
+    slapi_rwlock_unlock(rid_lock);
+
+    return 0;
+}
+
+int
 is_task_aborted(ReplicaId rid)
 {
 	int i;
@@ -1947,11 +1999,44 @@ set_cleaned_rid(ReplicaId rid)
         if(cleaned_rids[i] == 0){
             cleaned_rids[i] = rid;
             cleaned_rids[i + 1] = 0;
+            break;
         }
     }
     slapi_rwlock_unlock(rid_lock);
 }
 
+static void
+preset_cleaned_rid(ReplicaId rid)
+{
+    int i;
+
+    slapi_rwlock_wrlock(rid_lock);
+    for(i = 0; i < CLEANRIDSIZ; i++){
+        if(pre_cleaned_rids[i] == 0){
+            pre_cleaned_rids[i] = rid;
+            pre_cleaned_rids[i + 1] = 0;
+            break;
+        }
+    }
+    slapi_rwlock_unlock(rid_lock);
+}
+
+void
+set_aborted_rid(ReplicaId rid)
+{
+    int i;
+
+    slapi_rwlock_wrlock(abort_rid_lock);
+    for(i = 0; i < CLEANRIDSIZ; i++){
+        if(aborted_rids[i] == 0){
+            aborted_rids[i] = rid;
+            aborted_rids[i + 1] = 0;
+            break;
+        }
+    }
+    slapi_rwlock_unlock(abort_rid_lock);;
+}
+
 /*
  *  Add the rid and maxcsn to the repl config (so we can resume after a server restart)
  */
@@ -2134,11 +2219,18 @@ delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn)
      *  Remove this rid, and optimize the array
      */
     slapi_rwlock_wrlock(rid_lock);
+    /* do the cleaned rids */
     for(i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++); /* found rid, stop */
     for(; i < CLEANRIDSIZ; i++){
         /* rewrite entire array */
         cleaned_rids[i] = cleaned_rids[i + 1];
     }
+    /* do the preset cleaned rids */
+    for(i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != rid; i++); /* found rid, stop */
+    for(; i < CLEANRIDSIZ; i++){
+        /* rewrite entire array */
+        pre_cleaned_rids[i] = pre_cleaned_rids[i + 1];
+    }
     slapi_rwlock_unlock(rid_lock);
     /*
      *  Prepare the mods for the config entry
@@ -2244,6 +2336,14 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
         rc = SLAPI_DSE_CALLBACK_ERROR;
         goto out;
     }
+    if(is_aborted_rid(rid)){
+        /* we are already cleaning this rid */
+    	PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica id (%d) is already being aborted", rid);
+        cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
+        *returncode = LDAP_UNWILLING_TO_PERFORM;
+        rc = SLAPI_DSE_CALLBACK_ERROR;
+        goto out;
+    }
     /*
      *  Get the replica object
      */
@@ -2256,7 +2356,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
         goto out;
     }
     /*
-     *  Check verify value
+     *  Check certify value
      */
     if(certify_all){
         if(strcasecmp(certify_all,"yes") && strcasecmp(certify_all,"no")){
@@ -2591,10 +2691,17 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
                             for(part_count = 1; ruv_part && part_count < 5; part_count++){
                                 ruv_part = ldap_utf8strtok_r(iter, " ", &iter);
                             }
-                            if(part_count == 5 && ruv_part){
-                                /* we have the maxcsn */
-                                if(strcmp(ruv_part, maxcsn)){
+                            if(part_count == 5 && ruv_part){/* we have the maxcsn */
+                                CSN *max, *repl_max;
+
+                                max = csn_new();
+                                repl_max = csn_new();
+                                csn_init_by_string(max, maxcsn);
+                                csn_init_by_string(repl_max, ruv_part);
+                                if(csn_compare (repl_max, max) < 0){
                                     /* we are not caught up yet, free, and return */
+                                    cleanruv_log(task, CLEANALLRUV_ID,"Replica maxcsn (%s) not caught up deleted replica's maxcsn(%s)",
+                                	    ruv_part, maxcsn);
                                     ldap_value_free_len(vals);
                                     ldap_memfree( attr );
                                     ldap_msgfree( result );
@@ -2602,9 +2709,13 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
                                         ber_free( ber, 0 );
                                     }
                                     conn_delete_internal_ext(conn);
+                                    csn_free(&max);
+                                    csn_free(&repl_max);
                                     return -1;
                                 } else {
                                     /* ok this replica has all the updates from the deleted replica */
+                                	csn_free(&max);
+                                	csn_free(&repl_max);
                                     rc = 0;
                                 }
                             } else {
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index b2381b8..8026ff4 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1519,6 +1519,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 	char *payload = NULL;
 	char *csnstr = NULL;
 	char *iter;
+	char *force = NULL;
 	int release_it = 0;
 	int rid = 0;
 	int rc = LDAP_OPERATIONS_ERROR;
@@ -1535,18 +1536,22 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 	 *  Decode the payload
 	 */
 	if(decode_cleanruv_payload(extop_payload, &payload)){
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to decode payload.  Aborting ext op\n");
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to decode payload.  Aborting ext op\n");
 		goto free_and_return;
 	}
 	rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
 	repl_root = ldap_utf8strtok_r(iter, ":", &iter);
 	csnstr = ldap_utf8strtok_r(iter, ":", &iter);
+	force = ldap_utf8strtok_r(iter, ":", &iter);
+	if(force == NULL){
+	    force = "no";
+	}
 	maxcsn = csn_new();
 	csn_init_by_string(maxcsn, csnstr);
 	/*
 	 *  If we already cleaned this server, just return success
 	 */
-	if(is_cleaned_rid(rid)){
+	if(is_cleaned_rid(rid) || is_pre_cleaned_rid(rid)){
 		csn_free(&maxcsn);
 		rc = LDAP_SUCCESS;
 		goto free_and_return;
@@ -1556,7 +1561,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 	 *  Get the node, so we can get the replica and its agreements
 	 */
 	if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to get replication node "
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to get replication node "
 			"from (%s), aborting operation\n", repl_root);
 		goto free_and_return;
 	}
@@ -1565,14 +1570,14 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 		object_acquire (mtnode_ext->replica);
 		release_it = 1;
 	} else {
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: replica is missing from (%s), "
 			"aborting operation\n",repl_root);
 		goto free_and_return;
 	}
 
 	r = (Replica*)object_get_data (mtnode_ext->replica);
 	if(r == NULL){
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: replica is NULL, aborting task\n");
 		goto free_and_return;
 	}
 
@@ -1582,10 +1587,10 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 		 *
 		 *  This will also release mtnode_ext->replica
 		 */
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: launching cleanAllRUV thread...\n");
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: launching cleanAllRUV thread...\n");
 		data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
 		if (data == NULL) {
-			slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
+			slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to allocate "
 				"cleanruv_Data\n");
 			goto free_and_return;
 		}
@@ -1595,15 +1600,17 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 		data->task = NULL;
 		data->maxcsn = maxcsn;
 		data->payload = slapi_ch_bvdup(extop_payload);
+		data->force = slapi_ch_strdup(force);
 
 		thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
 				(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
 				PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
 		if (thread == NULL) {
-			slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
+			slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: unable to create cleanAllRUV "
 				"monitoring thread.  Aborting task.\n");
 			ber_bvfree(data->payload);
 			data->payload = NULL;
+			slapi_ch_free_string(&data->force);
 			slapi_ch_free((void **)&data);
 		} else {
 			release_it = 0; /* thread will release data->repl_obj == mtnode_ext->replica */
@@ -1625,18 +1632,18 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 				/* we've already been cleaned */
 				break;
 			}
-			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
+			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: checking if we're caught up...\n");
 			if(ruv_covers_csn_cleanallruv(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
 				/* We are caught up */
 				break;
 			} else {
 				char csnstr[CSN_STRSIZE];
 				csn_as_string(maxcsn, PR_FALSE, csnstr);
-				slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: not ruv caught up maxcsn(%s)\n", csnstr);
+				slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: ruv not caught up to maxcsn(%s)\n", csnstr);
 			}
 			DS_Sleep(PR_SecondsToInterval(5));
 		}
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: we're caught up...\n");
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: we're caught up...\n");
 		/*
 		 *  Set cleaned rid in memory only - does not survive a server restart
 		 */
@@ -1652,8 +1659,8 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
 		 *  This read-only replica has no easy way to tell when it's safe to release the rid.
 		 *  So we won't release it, not until a server restart.
 		 */
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: You must restart the server if you want to reuse rid(%d).\n", rid);
-		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully cleaned rid(%d).\n", rid);
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: You must restart the server if you want to reuse rid(%d).\n", rid);
+		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: Successfully cleaned rid(%d).\n", rid);
 		rc = LDAP_SUCCESS;
 	}
 
-- 
1.7.1

