From e48616639e254b698edaa778d41597094243ced5 Mon Sep 17 00:00:00 2001 From: Mark Reynolds 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