From e48616639e254b698edaa778d41597094243ced5 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Fri, 26 Aug 2016 15:04:02 -0400
Subject: [PATCH 44/45] Ticket 48957 - set proper update status to replication
agreement in case of failure
Bug Description: If a replication agreement fails to send updates it always returns
a generic error message even though there are many ways it could be
failing.
Fix Description: Set a proper error message when we fail to update a replica. Also made
all the messages consistent in format, and added new response strings
for known errors.
Also fixed some minor compiler warnings.
https://fedorahosted.org/389/ticket/48957
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit cdf4fb4ea6f26b4198d2d6b146ca51dcd51a31ef)
---
ldap/servers/plugins/replication/repl5.h | 15 +++--
ldap/servers/plugins/replication/repl5_agmt.c | 26 ++++----
.../plugins/replication/repl5_inc_protocol.c | 70 ++++++++++++++--------
.../plugins/replication/repl5_protocol_util.c | 65 ++++++++++++++++++--
.../plugins/replication/repl5_replica_config.c | 4 +-
ldap/servers/plugins/replication/repl5_total.c | 5 +-
6 files changed, 132 insertions(+), 53 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 6f6c81a..13a38fd 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -91,11 +91,16 @@
#define NSDS50_REPL_BELOW_PURGEPOINT 0x07 /* Supplier provided a CSN below the consumer's purge point */
#define NSDS50_REPL_INTERNAL_ERROR 0x08 /* Something bad happened on consumer */
#define NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED 0x09 /* Replica released successfully */
-#define NSDS50_REPL_LEGACY_CONSUMER 0x0A /* replica is a legacy consumer */
-#define NSDS50_REPL_REPLICAID_ERROR 0x0B /* replicaID doesn't seem to be unique */
-#define NSDS50_REPL_DISABLED 0x0C /* replica suffix is disabled */
-#define NSDS50_REPL_UPTODATE 0x0D /* replica is uptodate */
-#define NSDS50_REPL_BACKOFF 0x0E /* replica wants master to go into backoff mode */
+#define NSDS50_REPL_LEGACY_CONSUMER 0x0A /* replica is a legacy consumer */
+#define NSDS50_REPL_REPLICAID_ERROR 0x0B /* replicaID doesn't seem to be unique */
+#define NSDS50_REPL_DISABLED 0x0C /* replica suffix is disabled */
+#define NSDS50_REPL_UPTODATE 0x0D /* replica is uptodate */
+#define NSDS50_REPL_BACKOFF 0x0E /* replica wants master to go into backoff mode */
+#define NSDS50_REPL_CL_ERROR 0x0F /* Problem reading changelog */
+#define NSDS50_REPL_CONN_ERROR 0x10 /* Problem with replication connection*/
+#define NSDS50_REPL_CONN_TIMEOUT 0x11 /* Connection timeout */
+#define NSDS50_REPL_TRANSIENT_ERROR 0x12 /* Transient error */
+#define NSDS50_REPL_RUV_ERROR 0x13 /* Problem with the RUV */
#define NSDS50_REPL_REPLICA_NO_RESPONSE 0xff /* No response received */
/* Protocol status */
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 76d26a1..52cc8b6 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2460,9 +2460,9 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
replmsg = NULL;
}
}
- PR_snprintf(ra->last_update_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+ PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) %s%s - LDAP error: %s%s%s%s",
ldaprc, message?message:"",message?"":" - ",
- slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
+ slapi_err2string(ldaprc), replmsg ? " (" : "", replmsg ? replmsg : "", replmsg ? ")" : "");
}
/* ldaprc == LDAP_SUCCESS */
else if (replrc != 0)
@@ -2470,16 +2470,15 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
if (replrc == NSDS50_REPL_REPLICA_BUSY)
{
PR_snprintf(ra->last_update_status, STATUS_LEN,
- "%d Can't acquire busy replica", replrc );
+ "Error (%d) Can't acquire busy replica", replrc );
}
else if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED)
{
- PR_snprintf(ra->last_update_status, STATUS_LEN, "%d %s",
- ldaprc, "Replication session successful");
+ PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (0) Replication session successful");
}
else if (replrc == NSDS50_REPL_DISABLED)
{
- PR_snprintf(ra->last_update_status, STATUS_LEN, "%d Incremental update aborted: "
+ PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) Incremental update aborted: "
"Replication agreement for %s\n can not be updated while the replica is disabled.\n"
"(If the suffix is disabled you must enable it then restart the server for replication to take place).",
replrc, ra->long_name ? ra->long_name : "a replica");
@@ -2493,20 +2492,18 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
else
{
PR_snprintf(ra->last_update_status, STATUS_LEN,
- "%d Replication error acquiring replica: %s%s%s",
- replrc, protocol_response2string(replrc),
- message?" - ":"",message?message:"");
+ "Error (%d) Replication error acquiring replica: %s%s(%s)",
+ replrc, message?message:"", message?" ":"", protocol_response2string(replrc));
}
}
else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
{
- PR_snprintf(ra->last_update_status, STATUS_LEN,
- "%d Replica acquired successfully: %s",
- ldaprc, message);
+ PR_snprintf(ra->last_update_status, STATUS_LEN,
+ "Error (0) Replica acquired successfully: %s", message);
}
else
{ /* agmt_set_last_update_status(0,0,NULL) to reset agmt */
- PR_snprintf(ra->last_update_status, STATUS_LEN, "%d", ldaprc);
+ ra->last_update_status[0] = '\0';
}
}
}
@@ -2737,7 +2734,8 @@ get_agmt_status(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
slapi_entry_add_string(e, "nsds5replicaChangesSentSinceStartup", changecount_string);
if (ra->last_update_status[0] == '\0')
{
- slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus", "0 No replication sessions started since server startup");
+ slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus",
+ "Error (0) No replication sessions started since server startup");
}
else
{
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 27bac5d..d1de6c5 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -671,7 +671,6 @@ repl5_inc_run(Private_Repl_Protocol *prp)
int wait_change_timer_set = 0;
int current_state = STATE_START;
int next_state = STATE_START;
- int optype, ldaprc;
int done;
int e1;
@@ -838,14 +837,6 @@ repl5_inc_run(Private_Repl_Protocol *prp)
} else if (rc == ACQUIRE_FATAL_ERROR){
next_state = STATE_STOP_FATAL_ERROR;
}
-
- if (rc != ACQUIRE_SUCCESS){
- int optype, ldaprc;
- conn_get_error(prp->conn, &optype, &ldaprc);
- agmt_set_last_update_status(prp->agmt, ldaprc,
- prp->last_acquire_response_code, "Unable to acquire replica");
- }
-
object_release(prp->replica_object);
break;
@@ -934,10 +925,6 @@ repl5_inc_run(Private_Repl_Protocol *prp)
} else if (rc == ACQUIRE_FATAL_ERROR){
next_state = STATE_STOP_FATAL_ERROR;
}
- if (rc != ACQUIRE_SUCCESS){
- conn_get_error(prp->conn, &optype, &ldaprc);
- agmt_set_last_update_status(prp->agmt, ldaprc, prp->last_acquire_response_code, "Unable to acquire replica");
- }
/*
* We either need to step the backoff timer, or
* destroy it if we don't need it anymore
@@ -1037,7 +1024,8 @@ repl5_inc_run(Private_Repl_Protocol *prp)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Replica has no update vector. It has never been initialized.\n",
agmt_get_long_name(prp->agmt));
- agmt_set_last_update_status(prp->agmt, 0, rc, "Replica is not initialized");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_RUV_ERROR,
+ "Replica is not initialized");
next_state = STATE_BACKOFF_START;
break;
case EXAMINE_RUV_GENERATION_MISMATCH:
@@ -1045,8 +1033,9 @@ repl5_inc_run(Private_Repl_Protocol *prp)
"%s: The remote replica has a different database generation ID than "
"the local database. You may have to reinitialize the remote replica, "
"or the local replica.\n", agmt_get_long_name(prp->agmt));
- agmt_set_last_update_status(prp->agmt, 0, rc, "Replica has different database "
- "generation ID, remote replica may need to be initialized");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_RUV_ERROR,
+ "Replica has different database generation ID, remote "
+ "replica may need to be initialized");
next_state = STATE_BACKOFF_START;
break;
case EXAMINE_RUV_REPLICA_TOO_OLD:
@@ -1054,7 +1043,8 @@ repl5_inc_run(Private_Repl_Protocol *prp)
"%s: Replica update vector is too out of date to bring "
"into sync using the incremental protocol. The replica "
"must be reinitialized.\n", agmt_get_long_name(prp->agmt));
- agmt_set_last_update_status(prp->agmt, 0, rc, "Replica needs to be reinitialized");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_RUV_ERROR,
+ "Replica needs to be reinitialized");
next_state = STATE_BACKOFF_START;
break;
case EXAMINE_RUV_OK:
@@ -1069,11 +1059,15 @@ repl5_inc_run(Private_Repl_Protocol *prp)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Incremental protocol: fatal error - too much time skew between replicas!\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_EXCESSIVE_CLOCK_SKEW,
+ "fatal error - too much time skew between replicas");
next_state = STATE_STOP_FATAL_ERROR;
} else if (rc != 0) /* internal error */ {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Incremental protocol: fatal internal error updating the CSN generator!\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_INTERNAL_ERROR,
+ "fatal internal error updating the CSN generator");
next_state = STATE_STOP_FATAL_ERROR;
} else {
/*
@@ -1097,7 +1091,8 @@ repl5_inc_run(Private_Repl_Protocol *prp)
next_state = STATE_BACKOFF_START;
} else if (rc == UPDATE_TRANSIENT_ERROR){
dev_debug("repl5_inc_run(STATE_SENDING_UPDATES) -> send_updates = UPDATE_TRANSIENT_ERROR -> STATE_BACKOFF_START");
- agmt_set_last_update_status(prp->agmt, 0, rc, "Incremental update transient error. Backing off, will retry update later.");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_TRANSIENT_ERROR,
+ "Incremental update transient error. Backing off, will retry update later.");
next_state = STATE_BACKOFF_START;
} else if (rc == UPDATE_FATAL_ERROR){
dev_debug("repl5_inc_run(STATE_SENDING_UPDATES) -> send_updates = UPDATE_FATAL_ERROR -> STATE_STOP_FATAL_ERROR");
@@ -1114,11 +1109,13 @@ repl5_inc_run(Private_Repl_Protocol *prp)
conn_disconnect (prp->conn);
} else if (rc == UPDATE_CONNECTION_LOST){
dev_debug("repl5_inc_run(STATE_SENDING_UPDATES) -> send_updates = UPDATE_CONNECTION_LOST -> STATE_BACKOFF_START");
- agmt_set_last_update_status(prp->agmt, 0, rc, "Incremental update connection error. Backing off, will retry update later.");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CONN_ERROR,
+ "Incremental update connection error. Backing off, will retry update later.");
next_state = STATE_BACKOFF_START;
} else if (rc == UPDATE_TIMEOUT){
dev_debug("repl5_inc_run(STATE_SENDING_UPDATES) -> send_updates = UPDATE_TIMEOUT -> STATE_BACKOFF_START");
- agmt_set_last_update_status(prp->agmt, 0, rc, "Incremental update timeout error. Backing off, will retry update later.");
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CONN_TIMEOUT,
+ "Incremental update timeout error. Backing off, will retry update later.");
next_state = STATE_BACKOFF_START;
}
/* Set the updates times based off the result of send_updates() */
@@ -1173,8 +1170,6 @@ repl5_inc_run(Private_Repl_Protocol *prp)
/*
* We encountered some sort of a fatal error. Suspend.
*/
- /* XXXggood update state in replica */
- agmt_set_last_update_status(prp->agmt, -1, 0, "Incremental update has failed and requires administrator action");
dev_debug("repl5_inc_run(STATE_STOP_FATAL_ERROR)");
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Incremental update failed and requires administrator action\n",
@@ -1630,30 +1625,40 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Invalid parameter passed to cl5CreateReplayIterator\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Invalid parameter passed to cl5CreateReplayIterator");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_BAD_FORMAT: /* db data has unexpected format */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Unexpected format encountered in changelog database\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Unexpected format encountered in changelog database");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_BAD_STATE: /* changelog is in an incorrect state for attempted operation */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Changelog database was in an incorrect state\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Changelog database was in an incorrect state");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_BAD_DBVERSION: /* changelog has invalid dbversion */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Incorrect dbversion found in changelog database\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Incorrect dbversion found in changelog database");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_DB_ERROR: /* database error */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: A changelog database error was encountered\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Changelog database error was encountered");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_NOTFOUND: /* we have no changes to send */
@@ -1666,6 +1671,8 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Memory allocation error occurred\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "changelog memory allocation error occurred");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_SYSTEM_ERROR: /* NSPR error occurred: use PR_GetError for further info */
@@ -1694,15 +1701,20 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
break;
case CL5_PURGED_DATA: /* requested data has been purged */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "%s: Data required to update replica has been purged. "
+ "%s: Data required to update replica has been purged from the changelog. "
"The replica must be reinitialized.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Data required to update replica has been purged from the changelog. "
+ "The replica must be reinitialized.");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_MISSING_DATA: /* data should be in the changelog, but is missing */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Missing data encountered\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Changelog data is missing");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_UNKNOWN_ERROR: /* unclassified error */
@@ -1738,8 +1750,9 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
rc = repl5_inc_create_async_result_thread(rd);
if (rc) {
slapi_log_error (SLAPI_LOG_FATAL, repl_plugin_name, "%s: repl5_inc_run: "
- "repl5_tot_create_async_result_thread failed; error - %d\n",
+ "repl5_inc_create_async_result_thread failed; error - %d\n",
agmt_get_long_name(prp->agmt), rc);
+ agmt_set_last_update_status(prp->agmt, 0, rc, "Failed to create result thread");
return_value = UPDATE_FATAL_ERROR;
}
}
@@ -1898,6 +1911,8 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Invalid parameter passed to cl5GetNextOperationToReplay\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Invalid parameter passed to cl5GetNextOperationToReplay");
return_value = UPDATE_FATAL_ERROR;
finished = 1;
break;
@@ -1912,6 +1927,8 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: A database error occurred (cl5GetNextOperationToReplay)\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Database error occurred while getting the next operation to replay");
return_value = UPDATE_FATAL_ERROR;
finished = 1;
break;
@@ -1922,8 +1939,10 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
break;
case CL5_MEMORY_ERROR:
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "%s: A memory allocation error occurred (cl5GetNextOperationToRepla)\n",
+ "%s: A memory allocation error occurred (cl5GetNextOperationToReplay)\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_CL_ERROR,
+ "Memory allocation error occurred (cl5GetNextOperationToReplay)");
return_value = UPDATE_FATAL_ERROR;
break;
case CL5_IGNORE_OP:
@@ -1985,6 +2004,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
if (!replarea_sdn) {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"send_updates: Unknown replication area due to agreement not found.");
+ agmt_set_last_update_status(prp->agmt, 0, -1, "Agreement is corrupted: missing suffix");
return_value = UPDATE_FATAL_ERROR;
} else {
replica_subentry_update(replarea_sdn, rid);
diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c b/ldap/servers/plugins/replication/repl5_protocol_util.c
index ce27a8a..ce6281a 100644
--- a/ldap/servers/plugins/replication/repl5_protocol_util.c
+++ b/ldap/servers/plugins/replication/repl5_protocol_util.c
@@ -140,10 +140,18 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
crc = conn_connect(conn);
if (CONN_OPERATION_FAILED == crc)
{
+ int operation, error;
+ conn_get_error(conn, &operation, &error);
+ agmt_set_last_update_status(prp->agmt, error, NSDS50_REPL_CONN_ERROR,
+ "Problem connecting to replica");
return_value = ACQUIRE_TRANSIENT_ERROR;
}
else if (CONN_SSL_NOT_ENABLED == crc)
{
+ int operation, error;
+ conn_get_error(conn, &operation, &error);
+ agmt_set_last_update_status(prp->agmt, error, NSDS50_REPL_CONN_ERROR,
+ "Problem connecting to replica (SSL not enabled)");
return_value = ACQUIRE_FATAL_ERROR;
}
else
@@ -295,6 +303,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"an internal error occurred on the remote replica. "
"Replication is aborting.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Failed to acquire replica: "
+ "Internal error occurred on the remote replica");
return_value = ACQUIRE_FATAL_ERROR;
break;
case NSDS50_REPL_PERMISSION_DENIED:
@@ -307,6 +318,11 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"supply replication updates to the replica. "
"Will retry later.\n",
agmt_get_long_name(prp->agmt), repl_binddn);
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: permission denied. "
+ "The bind dn does not have permission to "
+ "supply replication updates to the replica. "
+ "Will retry later.");
slapi_ch_free((void **)&repl_binddn);
return_value = ACQUIRE_TRANSIENT_ERROR;
break;
@@ -321,6 +337,10 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"Replication is aborting.\n",
agmt_get_long_name(prp->agmt),
slapi_sdn_get_dn(repl_root));
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: there is no "
+ "replicated area on the consumer server. "
+ "Replication is aborting.");
slapi_sdn_free(&repl_root);
return_value = ACQUIRE_FATAL_ERROR;
break;
@@ -342,6 +362,11 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"startReplicationRequest extended operation sent by the "
"supplier. Replication is aborting.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: "
+ "the consumer was unable to decode the "
+ "startReplicationRequest extended operation sent "
+ "by the supplier. Replication is aborting.");
return_value = ACQUIRE_FATAL_ERROR;
break;
case NSDS50_REPL_REPLICA_BUSY:
@@ -365,6 +390,10 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"by another supplier. Will try later\n",
agmt_get_long_name(prp->agmt));
}
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: "
+ "the replica is currently being updated by another "
+ "supplier.");
return_value = ACQUIRE_REPLICA_BUSY;
break;
case NSDS50_REPL_LEGACY_CONSUMER:
@@ -373,6 +402,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"%s: Unable to acquire replica: the replica "
"is supplied by a legacy supplier. "
"Replication is aborting.\n", agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: the replica is supplied "
+ "by a legacy supplier. Replication is aborting.");
return_value = ACQUIRE_FATAL_ERROR;
break;
case NSDS50_REPL_REPLICAID_ERROR:
@@ -382,6 +414,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"has the same Replica ID as this one. "
"Replication is aborting.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, 0,
+ "Unable to aquire replica: the replica has the same "
+ "Replica ID as this one. Replication is aborting.");
return_value = ACQUIRE_FATAL_ERROR;
break;
case NSDS50_REPL_BACKOFF:
@@ -392,6 +427,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"the replica instructed us to go into "
"backoff mode. Will retry later.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica: the replica instructed "
+ "us to go into backoff mode. Will retry later.");
return_value = ACQUIRE_TRANSIENT_ERROR;
break;
case NSDS50_REPL_REPLICA_READY:
@@ -450,6 +488,8 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
return_value = ACQUIRE_SUCCESS;
break;
default:
+ agmt_set_last_update_status(prp->agmt, 0, extop_result,
+ "Unable to acquire replica");
return_value = ACQUIRE_FATAL_ERROR;
}
}
@@ -461,6 +501,10 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"startReplication extended operation. "
"Replication is aborting.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_DECODING_ERROR,
+ "Unable to parse the response to the "
+ "startReplication extended operation. "
+ "Replication is aborting.");
prp->last_acquire_response_code = NSDS50_REPL_INTERNAL_ERROR;
return_value = ACQUIRE_FATAL_ERROR;
}
@@ -477,6 +521,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"extended operation to consumer (%s). Will retry later.\n",
agmt_get_long_name(prp->agmt),
error ? ldap_err2string(error) : "unknown error");
+ agmt_set_last_update_status(prp->agmt, error, NSDS50_REPL_CONN_ERROR,
+ "Unable to receive the response for a startReplication "
+ "extended operation to consumer. Will retry later.");
}
}
else
@@ -486,6 +533,9 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
"%s: Unable to obtain current CSN. "
"Replication is aborting.\n",
agmt_get_long_name(prp->agmt));
+ agmt_set_last_update_status(prp->agmt, 0, 0,
+ "Unable to obtain current CSN. "
+ "Replication is aborting.");
return_value = ACQUIRE_FATAL_ERROR;
}
}
@@ -535,8 +585,8 @@ release_replica(Private_Repl_Protocol *prp)
PR_ASSERT(NULL != prp);
PR_ASSERT(NULL != prp->conn);
- if (!prp->replica_acquired)
- return;
+ if (!prp->replica_acquired)
+ return;
replarea_sdn = agmt_get_replarea(prp->agmt);
payload = NSDS50EndReplicationRequest_new((char *)slapi_sdn_get_dn(replarea_sdn)); /* XXXggood had to cast away const */
@@ -650,9 +700,14 @@ protocol_response2string (int response)
case NSDS50_REPL_BELOW_PURGEPOINT: return "csn below purge point";
case NSDS50_REPL_INTERNAL_ERROR: return "internal error";
case NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED: return "replica released";
- case NSDS50_REPL_LEGACY_CONSUMER: return "replica is a legacy consumer";
- case NSDS50_REPL_REPLICAID_ERROR: return "duplicate replica ID detected";
- case NSDS50_REPL_UPTODATE: return "no change to send";
+ case NSDS50_REPL_LEGACY_CONSUMER: return "replica is a legacy consumer";
+ case NSDS50_REPL_REPLICAID_ERROR: return "duplicate replica ID detected";
+ case NSDS50_REPL_UPTODATE: return "no change to send";
+ case NSDS50_REPL_CL_ERROR: return "changelog error";
+ case NSDS50_REPL_CONN_ERROR: return "connection error";
+ case NSDS50_REPL_CONN_TIMEOUT: return "connection timeout";
+ case NSDS50_REPL_TRANSIENT_ERROR: return "transient error";
+ case NSDS50_REPL_RUV_ERROR: return "RUV error";
default: return "unknown error";
}
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 011e4ca..59e5298 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -639,8 +639,8 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
}
done:
- if (mtnode_ext->replica)
- object_release (mtnode_ext->replica);
+ if (mtnode_ext->replica)
+ object_release (mtnode_ext->replica);
/* slapi_ch_free accepts NULL pointer */
slapi_ch_free_string(&replica_root);
diff --git a/ldap/servers/plugins/replication/repl5_total.c b/ldap/servers/plugins/replication/repl5_total.c
index 0512dfa..dcb7af5 100644
--- a/ldap/servers/plugins/replication/repl5_total.c
+++ b/ldap/servers/plugins/replication/repl5_total.c
@@ -533,8 +533,9 @@ my_ber_scanf_value(BerElement *ber, Slapi_Value **value, PRBool *deleted)
goto loser;
}
- if (attrval)
- ber_bvfree(attrval);
+ if (attrval)
+ ber_bvfree(attrval);
+
return 0;
loser:
--
2.4.11