|
 |
dc8c34 |
From caa4c40e88032c97d8c928debd5d1b34078d60a3 Mon Sep 17 00:00:00 2001
|
|
 |
dc8c34 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
 |
dc8c34 |
Date: Tue, 19 Mar 2013 15:17:51 -0400
|
|
 |
dc8c34 |
Subject: [PATCH 37/42] Ticket 623 - cleanAllRUV task fails to cleanup config
|
|
 |
dc8c34 |
upon completion
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
Bug Description: Since multiple tasks can be run at once. When a task
|
|
 |
dc8c34 |
completes we need to remove a attribute from the replication
|
|
 |
dc8c34 |
configuration. We were manually building the attribute
|
|
 |
dc8c34 |
value, and under certain circumstances this would not work
|
|
 |
dc8c34 |
correctly. This would leave the attribute in the replication
|
|
 |
dc8c34 |
config, and after a restart the task would fire off again.
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
Fix Description: Do not manually build the attribute value, but instead search
|
|
 |
dc8c34 |
cn=config and grab the exact value we need to delete.
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
https://fedorahosted.org/389/ticket/623
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
Reviewed by: nhosoi(Thanks!)
|
|
 |
dc8c34 |
(cherry picked from commit fa7972a5f01be7cedcd65c4c19af9602d2f7848f)
|
|
 |
dc8c34 |
---
|
|
 |
dc8c34 |
.../plugins/replication/repl5_replica_config.c | 106 +++++++++++++++------
|
|
 |
dc8c34 |
1 file changed, 75 insertions(+), 31 deletions(-)
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
 |
dc8c34 |
index e234c15..8710c04 100644
|
|
 |
dc8c34 |
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
 |
dc8c34 |
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
 |
dc8c34 |
@@ -2351,57 +2351,100 @@ delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root, int skip){
|
|
 |
dc8c34 |
static void
|
|
 |
dc8c34 |
delete_cleaned_rid_config(cleanruv_data *clean_data)
|
|
 |
dc8c34 |
{
|
|
 |
dc8c34 |
- Slapi_PBlock *pb;
|
|
 |
dc8c34 |
+ Slapi_PBlock *pb = slapi_pblock_new();
|
|
 |
dc8c34 |
+ Slapi_Entry **entries = NULL;
|
|
 |
dc8c34 |
LDAPMod *mods[2];
|
|
 |
dc8c34 |
LDAPMod mod;
|
|
 |
dc8c34 |
struct berval *vals[2];
|
|
 |
dc8c34 |
struct berval val;
|
|
 |
dc8c34 |
char data[CSN_STRSIZE + 15];
|
|
 |
dc8c34 |
char *csnstr = NULL;
|
|
 |
dc8c34 |
+ char *iter = NULL;
|
|
 |
dc8c34 |
char *dn;
|
|
 |
dc8c34 |
- int rc;
|
|
 |
dc8c34 |
+ int found = 0, i;
|
|
 |
dc8c34 |
+ int rc, ret, rid;
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
/*
|
|
 |
dc8c34 |
- * Prepare the mods for the config entry
|
|
 |
dc8c34 |
+ * If there is no maxcsn, set the proper csnstr
|
|
 |
dc8c34 |
*/
|
|
 |
dc8c34 |
csn_as_string(clean_data->maxcsn, PR_FALSE, csnstr);
|
|
 |
dc8c34 |
- val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s", (int)clean_data->rid, csnstr, clean_data->force);
|
|
 |
dc8c34 |
+ if(csnstr == NULL || csn_get_replicaid(clean_data->maxcsn) == 0){
|
|
 |
dc8c34 |
+ csnstr = slapi_ch_strdup("00000000000000000000");
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ /*
|
|
 |
dc8c34 |
+ * Search the config for the exact attribute value to delete
|
|
 |
dc8c34 |
+ */
|
|
 |
dc8c34 |
dn = replica_get_dn(clean_data->replica);
|
|
 |
dc8c34 |
- pb = slapi_pblock_new();
|
|
 |
dc8c34 |
+ slapi_search_internal_set_pb(pb, dn, LDAP_SCOPE_SUBTREE, "nsds5ReplicaCleanRUV=*", NULL, 0, NULL, NULL,
|
|
 |
dc8c34 |
+ (void *)plugin_get_default_component_id(), 0);
|
|
 |
dc8c34 |
+ slapi_search_internal_pb(pb);
|
|
 |
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret;;
|
|
 |
dc8c34 |
+ if (ret != LDAP_SUCCESS){
|
|
 |
dc8c34 |
+ /*
|
|
 |
dc8c34 |
+ * Search failed, manually build the attr value
|
|
 |
dc8c34 |
+ */
|
|
 |
dc8c34 |
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s",
|
|
 |
dc8c34 |
+ (int)clean_data->rid, csnstr, clean_data->force);
|
|
 |
dc8c34 |
+ slapi_pblock_destroy(pb);
|
|
 |
dc8c34 |
+ } else {
|
|
 |
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
|
|
 |
dc8c34 |
+ if (entries == NULL || entries[0] == NULL){
|
|
 |
dc8c34 |
+ /*
|
|
 |
dc8c34 |
+ * Entry not found, manually build the attr value
|
|
 |
dc8c34 |
+ */
|
|
 |
dc8c34 |
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s",
|
|
 |
dc8c34 |
+ (int)clean_data->rid, csnstr, clean_data->force);
|
|
 |
dc8c34 |
+ } else {
|
|
 |
dc8c34 |
+ char **attr_val = slapi_entry_attr_get_charray(entries[0], "nsds5ReplicaCleanRUV");
|
|
 |
dc8c34 |
+
|
|
 |
dc8c34 |
+ for (i = 0; attr_val && attr_val[i] && !found; i++){
|
|
 |
dc8c34 |
+ /* make a copy to retain the full value after toking */
|
|
 |
dc8c34 |
+ char *aval = slapi_ch_strdup(attr_val[i]);
|
|
 |
dc8c34 |
+
|
|
 |
dc8c34 |
+ rid = atoi(ldap_utf8strtok_r(attr_val[i], ":", &iter));
|
|
 |
dc8c34 |
+ if(rid == clean_data->rid){
|
|
 |
dc8c34 |
+ /* found it */
|
|
 |
dc8c34 |
+ found = 1;
|
|
 |
dc8c34 |
+ val.bv_len = PR_snprintf(data, sizeof(data), "%s", aval);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ slapi_ch_free_string(&aval);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ if(!found){
|
|
 |
dc8c34 |
+ /*
|
|
 |
dc8c34 |
+ * No match, manually build the attr value
|
|
 |
dc8c34 |
+ */
|
|
 |
dc8c34 |
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:%s",
|
|
 |
dc8c34 |
+ (int)clean_data->rid, csnstr, clean_data->force);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ slapi_ch_array_free(attr_val);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ slapi_free_search_results_internal(pb);
|
|
 |
dc8c34 |
+ slapi_pblock_destroy(pb);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+
|
|
 |
dc8c34 |
+ /*
|
|
 |
dc8c34 |
+ * Now delete the attribute
|
|
 |
dc8c34 |
+ */
|
|
 |
dc8c34 |
mod.mod_op = LDAP_MOD_DELETE|LDAP_MOD_BVALUES;
|
|
 |
dc8c34 |
- mod.mod_type = (char *)type_replicaAbortCleanRUV;
|
|
 |
dc8c34 |
mod.mod_type = (char *)type_replicaCleanRUV;
|
|
 |
dc8c34 |
mod.mod_bvalues = vals;
|
|
 |
dc8c34 |
vals [0] = &val;
|
|
 |
dc8c34 |
vals [1] = NULL;
|
|
 |
dc8c34 |
val.bv_val = data;
|
|
 |
dc8c34 |
-
|
|
 |
dc8c34 |
mods[0] = &mod;
|
|
 |
dc8c34 |
mods[1] = NULL;
|
|
 |
dc8c34 |
+ pb = slapi_pblock_new();
|
|
 |
dc8c34 |
slapi_modify_internal_set_pb(pb, dn, mods, NULL, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
|
|
 |
dc8c34 |
slapi_modify_internal_pb (pb);
|
|
 |
dc8c34 |
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
|
 |
dc8c34 |
- if (rc != LDAP_SUCCESS){
|
|
 |
dc8c34 |
- /*
|
|
 |
dc8c34 |
- * When aborting a task, we don't know if the "force" option was used.
|
|
 |
dc8c34 |
- * So we assume it is set to "no", but if this op fails, we'll try "yes"
|
|
 |
dc8c34 |
- */
|
|
 |
dc8c34 |
- slapi_pblock_destroy (pb);
|
|
 |
dc8c34 |
- pb = slapi_pblock_new();
|
|
 |
dc8c34 |
- memset(data,'0',sizeof(data));
|
|
 |
dc8c34 |
- val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s:yes", (int)clean_data->rid, csnstr);
|
|
 |
dc8c34 |
- slapi_modify_internal_set_pb(pb, dn, mods, NULL, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
|
|
 |
dc8c34 |
- slapi_modify_internal_pb (pb);
|
|
 |
dc8c34 |
- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
|
 |
dc8c34 |
- if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT){
|
|
 |
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to remove replica config "
|
|
 |
dc8c34 |
- "(%d), rid (%d)\n", rc, clean_data->rid);
|
|
 |
dc8c34 |
- }
|
|
 |
dc8c34 |
- }
|
|
 |
dc8c34 |
- slapi_pblock_destroy (pb);
|
|
 |
dc8c34 |
- slapi_ch_free_string(&dn;;
|
|
 |
dc8c34 |
- slapi_ch_free_string(&csnstr);
|
|
 |
dc8c34 |
- }
|
|
 |
dc8c34 |
+ if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT){
|
|
 |
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to remove replica config "
|
|
 |
dc8c34 |
+ "(%d), rid (%d)\n", rc, clean_data->rid);
|
|
 |
dc8c34 |
+ }
|
|
 |
dc8c34 |
+ slapi_pblock_destroy(pb);
|
|
 |
dc8c34 |
+ slapi_ch_free_string(&dn;;
|
|
 |
dc8c34 |
+ slapi_ch_free_string(&csnstr);
|
|
 |
dc8c34 |
+}
|
|
 |
dc8c34 |
|
|
 |
dc8c34 |
/*
|
|
 |
dc8c34 |
* Remove the rid from our list, and the config
|
|
 |
dc8c34 |
@@ -2762,8 +2805,8 @@ replica_cleanallruv_send_extop(Repl_Agmt *ra, cleanruv_data *clean_data, int che
|
|
 |
dc8c34 |
/* extop was accepted */
|
|
 |
dc8c34 |
rc = 0;
|
|
 |
dc8c34 |
} else {
|
|
 |
dc8c34 |
- cleanruv_log(clean_data->task, CLEANALLRUV_ID,"Replica %s does not support the CLEANALLRUV task. Sending replica CLEANRUV task...",
|
|
 |
dc8c34 |
- slapi_sdn_get_dn(agmt_get_dn_byref(ra)));
|
|
 |
dc8c34 |
+ cleanruv_log(clean_data->task, CLEANALLRUV_ID,"Replica %s does not support the CLEANALLRUV task. "
|
|
 |
dc8c34 |
+ "Sending replica CLEANRUV task...", slapi_sdn_get_dn(agmt_get_dn_byref(ra)));
|
|
 |
dc8c34 |
/*
|
|
 |
dc8c34 |
* Ok, this replica doesn't know about CLEANALLRUV, so just manually
|
|
 |
dc8c34 |
* add the CLEANRUV task to the replica.
|
|
 |
dc8c34 |
@@ -2841,7 +2884,8 @@ replica_cleanallruv_find_maxcsn(Replica *replica, ReplicaId rid, char *basedn)
|
|
 |
dc8c34 |
/* we could not find any maxcsn's - already cleaned? */
|
|
 |
dc8c34 |
return NULL;
|
|
 |
dc8c34 |
}
|
|
 |
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: replica_cleanallruv_find_maxcsn: Not all replicas online, retrying in %d seconds\n",interval);
|
|
 |
dc8c34 |
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: replica_cleanallruv_find_maxcsn: "
|
|
 |
dc8c34 |
+ "Not all replicas online, retrying in %d seconds\n", interval);
|
|
 |
dc8c34 |
PR_Lock( notify_lock );
|
|
 |
dc8c34 |
PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
|
|
 |
dc8c34 |
PR_Unlock( notify_lock );
|
|
 |
dc8c34 |
--
|
|
 |
dc8c34 |
1.8.1.4
|
|
 |
dc8c34 |
|