Blame SOURCES/0000-Issue-49602-Revise-replication-status-messages.patch

83bcdf
From 45f4abd6befa50b129fc49b331b42c280f37199a Mon Sep 17 00:00:00 2001
83bcdf
From: Mark Reynolds <mreynolds@redhat.com>
83bcdf
Date: Thu, 13 Jun 2019 13:01:35 -0400
83bcdf
Subject: [PATCH] Issue 49602 - Revise replication status messages
83bcdf
83bcdf
Bug Description: All agreement status messages start with "Error (##)" followed
83bcdf
                 by a text string.  Even success states start with "Error", and
83bcdf
                 this is confusing.
83bcdf
83bcdf
                 Added new attributes to display the status in a JSON format
83bcdf
                 for easier parsing for applications:
83bcdf
83bcdf
                     replicaLastUpdateStatusJSON
83bcdf
                     replicaLastInitStatusJSON
83bcdf
83bcdf
Design Doc:  https://www.port389.org/docs/389ds/design/repl-agmt-status-design.html
83bcdf
83bcdf
https://pagure.io/389-ds-base/issue/49602
83bcdf
83bcdf
Reviewed by: firstyear(Thanks!)
83bcdf
---
83bcdf
 .../suites/replication/single_master_test.py  | 19 +++--
83bcdf
 ldap/schema/01core389.ldif                    |  2 +
83bcdf
 ldap/servers/plugins/replication/repl5_agmt.c | 84 ++++++++++++++++---
83bcdf
 .../plugins/replication/repl5_protocol_util.c | 13 +--
83bcdf
 4 files changed, 96 insertions(+), 22 deletions(-)
83bcdf
83bcdf
diff --git a/dirsrvtests/tests/suites/replication/single_master_test.py b/dirsrvtests/tests/suites/replication/single_master_test.py
83bcdf
index 5b73e23ae..78f849da7 100644
83bcdf
--- a/dirsrvtests/tests/suites/replication/single_master_test.py
83bcdf
+++ b/dirsrvtests/tests/suites/replication/single_master_test.py
83bcdf
@@ -23,6 +23,7 @@ from lib389._constants import (ReplicaRole, DEFAULT_SUFFIX, REPLICAID_MASTER_1,
83bcdf
                                 REPLICATION_BIND_METHOD, REPLICATION_TRANSPORT, DEFAULT_BACKUPDIR,
83bcdf
                                 RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD, RA_TRANSPORT_PROT,
83bcdf
                                 defaultProperties)
83bcdf
+import json
83bcdf
 
83bcdf
 pytestmark = pytest.mark.tier1
83bcdf
 
83bcdf
@@ -95,7 +96,7 @@ def test_mail_attr_repl(topo_r):
83bcdf
     consumer.start()
83bcdf
 
83bcdf
     log.info("Make a search for mail attribute in attempt to crash server")
83bcdf
-    consumer.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(mail=testuser@redhat.com)", ["mail"])
83bcdf
+    c_user.get_attr_val("mail")
83bcdf
 
83bcdf
     log.info("Make sure that server hasn't crashed")
83bcdf
     repl.test_replication(master, consumer)
83bcdf
@@ -111,11 +112,13 @@ def test_lastupdate_attr_before_init(topo_nr):
83bcdf
         1. Check nsds5replicaLastUpdateStart value
83bcdf
         2. Check nsds5replicaLastUpdateEnd value
83bcdf
         3. Check nsds5replicaLastUpdateStatus value
83bcdf
+        4. Check nsds5replicaLastUpdateStatusJSON is parsable
83bcdf
     :expectedresults:
83bcdf
         1. nsds5replicaLastUpdateStart should be equal to 0
83bcdf
         2. nsds5replicaLastUpdateEnd should be equal to 0
83bcdf
         3. nsds5replicaLastUpdateStatus should not be equal
83bcdf
-           to "0 Replica acquired successfully: Incremental update started"
83bcdf
+           to "Replica acquired successfully: Incremental update started"
83bcdf
+        4. Success
83bcdf
     """
83bcdf
 
83bcdf
     master = topo_nr.ins["standalone1"]
83bcdf
@@ -139,11 +142,15 @@ def test_lastupdate_attr_before_init(topo_nr):
83bcdf
     with pytest.raises(Exception):
83bcdf
         repl.wait_for_replication(master, consumer, timeout=5)
83bcdf
 
83bcdf
-    assert agmt.get_attr_val_bytes('nsds5replicaLastUpdateStart') == b"19700101000000Z"
83bcdf
-    assert agmt.get_attr_val_bytes("nsds5replicaLastUpdateEnd") == b"19700101000000Z"
83bcdf
-    assert b"Replica acquired successfully" not in agmt.get_attr_val_bytes("nsds5replicaLastUpdateStatus")
83bcdf
-
83bcdf
+    assert agmt.get_attr_val_utf8('nsds5replicaLastUpdateStart') == "19700101000000Z"
83bcdf
+    assert agmt.get_attr_val_utf8("nsds5replicaLastUpdateEnd") == "19700101000000Z"
83bcdf
+    assert "replica acquired successfully" not in agmt.get_attr_val_utf8_l("nsds5replicaLastUpdateStatus")
83bcdf
 
83bcdf
+    # make sure the JSON attribute is parsable
83bcdf
+    json_status = agmt.get_attr_val_utf8("nsds5replicaLastUpdateStatusJSON")
83bcdf
+    if json_status is not None:
83bcdf
+        json_obj = json.loads(json_status)
83bcdf
+        log.debug("JSON status message: {}".format(json_obj))
83bcdf
 
83bcdf
 if __name__ == '__main__':
83bcdf
     # Run isolated
83bcdf
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
83bcdf
index 993fa4a6d..7bf4acc5b 100644
83bcdf
--- a/ldap/schema/01core389.ldif
83bcdf
+++ b/ldap/schema/01core389.ldif
83bcdf
@@ -312,6 +312,8 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2341 NAME 'nsslapd-changelogmaxentries'
83bcdf
 attributeTypes: ( 2.16.840.1.113730.3.1.2344 NAME 'nsslapd-tls-check-crl' DESC 'Check CRL when opening outbound TLS connections. Valid options are none, peer, all.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
83bcdf
 attributeTypes: ( 2.16.840.1.113730.3.1.2353 NAME 'nsslapd-encryptionalgorithm' DESC 'The encryption algorithm used to encrypt the changelog' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
83bcdf
 attributeTypes: ( 2.16.840.1.113730.3.1.2084 NAME 'nsSymmetricKey' DESC 'A symmetric key - currently used by attribute encryption' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'attribute encryption' )
83bcdf
+attributeTypes: ( 2.16.840.1.113730.3.1.2364 NAME 'nsds5replicaLastInitStatusJSON' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )
83bcdf
+attributeTypes: ( 2.16.840.1.113730.3.1.2365 NAME 'nsds5replicaLastUpdateStatusJSON' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' )
83bcdf
 #
83bcdf
 # objectclasses
83bcdf
 #
83bcdf
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
83bcdf
index 53e6708c8..8e4586d8b 100644
83bcdf
--- a/ldap/servers/plugins/replication/repl5_agmt.c
83bcdf
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
83bcdf
@@ -60,7 +60,11 @@
83bcdf
 #define DEFAULT_TIMEOUT 120             /* (seconds) default outbound LDAP connection */
83bcdf
 #define DEFAULT_FLOWCONTROL_WINDOW 1000 /* #entries sent without acknowledgment */
83bcdf
 #define DEFAULT_FLOWCONTROL_PAUSE 2000  /* msec of pause when #entries sent witout acknowledgment */
83bcdf
-#define STATUS_LEN 1024
83bcdf
+#define STATUS_LEN 2048
83bcdf
+#define STATUS_GOOD "green"
83bcdf
+#define STATUS_WARNING "amber"
83bcdf
+#define STATUS_BAD "red"
83bcdf
+
83bcdf
 
83bcdf
 struct changecounter
83bcdf
 {
83bcdf
@@ -93,11 +97,13 @@ typedef struct repl5agmt
83bcdf
     time_t last_update_start_time;       /* Local start time of last update session */
83bcdf
     time_t last_update_end_time;         /* Local end time of last update session */
83bcdf
     char last_update_status[STATUS_LEN]; /* Status of last update. Format = numeric code <space> textual description */
83bcdf
+    char last_update_status_json[STATUS_LEN];
83bcdf
     PRBool update_in_progress;
83bcdf
     PRBool is_enabled;
83bcdf
     time_t last_init_start_time;       /* Local start time of last total init */
83bcdf
     time_t last_init_end_time;         /* Local end time of last total init */
83bcdf
     char last_init_status[STATUS_LEN]; /* Status of last total init. Format = numeric code <space> textual description */
83bcdf
+    char last_init_status_json[STATUS_LEN];
83bcdf
     PRLock *lock;
83bcdf
     Object *consumerRUV;     /* last RUV received from the consumer - used for changelog purging */
83bcdf
     CSN *consumerSchemaCSN;  /* last schema CSN received from the consumer */
83bcdf
@@ -2443,6 +2449,21 @@ agmt_set_last_init_end(Repl_Agmt *ra, time_t end_time)
83bcdf
     }
83bcdf
 }
83bcdf
 
83bcdf
+static void
83bcdf
+agmt_set_last_update_status_json(Repl_Agmt *ra, char *state, int ldaprc, int replrc)
83bcdf
+{
83bcdf
+    char ts[SLAPI_TIMESTAMP_BUFSIZE];
83bcdf
+    time_t now;
83bcdf
+
83bcdf
+    time(&now;;
83bcdf
+    strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now));
83bcdf
+    PR_snprintf(ra->last_update_status_json, STATUS_LEN,
83bcdf
+            "{\"state\": \"%s\", \"ldap_rc\": \"%d\", \"ldap_rc_text\": \"%s\", "
83bcdf
+            "\"repl_rc\": \"%d\", \"repl_rc_text\": \"%s\", \"date\": \"%s\", \"message\": \"%s\"}",
83bcdf
+            state, ldaprc, ldap_err2string(ldaprc), replrc, protocol_response2string(replrc),
83bcdf
+            ts, ra->last_update_status);
83bcdf
+}
83bcdf
+
83bcdf
 void
83bcdf
 agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *message)
83bcdf
 {
83bcdf
@@ -2463,19 +2484,29 @@ agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *m
83bcdf
             PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) %s%s - LDAP error: %s%s%s%s",
83bcdf
                         ldaprc, message ? message : "", message ? "" : " - ",
83bcdf
                         slapi_err2string(ldaprc), replmsg ? " (" : "", replmsg ? replmsg : "", replmsg ? ")" : "");
83bcdf
+            agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc);
83bcdf
         }
83bcdf
         /* ldaprc == LDAP_SUCCESS */
83bcdf
         else if (replrc != 0) {
83bcdf
             if (replrc == NSDS50_REPL_REPLICA_BUSY) {
83bcdf
                 PR_snprintf(ra->last_update_status, STATUS_LEN,
83bcdf
-                            "Error (%d) Can't acquire busy replica", replrc);
83bcdf
+                            "Error (%d) Can't acquire busy replica (%s)",
83bcdf
+                            replrc, message ? message : "");
83bcdf
+                agmt_set_last_update_status_json(ra, STATUS_WARNING, ldaprc, replrc);
83bcdf
+            } else if (replrc == NSDS50_REPL_TRANSIENT_ERROR  || replrc == NSDS50_REPL_BACKOFF) {
83bcdf
+                PR_snprintf(ra->last_update_status, STATUS_LEN,
83bcdf
+                            "Error (%d) Can't acquire replica (%s)",
83bcdf
+                            replrc, message ? message : "");
83bcdf
+                agmt_set_last_update_status_json(ra, STATUS_WARNING, ldaprc, replrc);
83bcdf
             } else if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) {
83bcdf
                 PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (0) Replication session successful");
83bcdf
+                agmt_set_last_update_status_json(ra, STATUS_GOOD, ldaprc, replrc);
83bcdf
             } else if (replrc == NSDS50_REPL_DISABLED) {
83bcdf
                 PR_snprintf(ra->last_update_status, STATUS_LEN, "Error (%d) Incremental update aborted: "
83bcdf
                                                                 "Replication agreement for %s\n can not be updated while the replica is disabled.\n"
83bcdf
                                                                 "(If the suffix is disabled you must enable it then restart the server for replication to take place).",
83bcdf
                             replrc, ra->long_name ? ra->long_name : "a replica");
83bcdf
+                agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc);
83bcdf
                 /* Log into the errors log, as "ra->long_name" is not accessible from the caller */
83bcdf
                 slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
83bcdf
                               "Incremental update aborted: Replication agreement for \"%s\" "
83bcdf
@@ -2487,17 +2518,35 @@ agmt_set_last_update_status(Repl_Agmt *ra, int ldaprc, int replrc, const char *m
83bcdf
                 PR_snprintf(ra->last_update_status, STATUS_LEN,
83bcdf
                             "Error (%d) Replication error acquiring replica: %s%s(%s)",
83bcdf
                             replrc, message ? message : "", message ? " " : "", protocol_response2string(replrc));
83bcdf
+                agmt_set_last_update_status_json(ra, STATUS_BAD, ldaprc, replrc);
83bcdf
             }
83bcdf
         } else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
83bcdf
         {
83bcdf
             PR_snprintf(ra->last_update_status, STATUS_LEN,
83bcdf
                         "Error (0) Replica acquired successfully: %s", message);
83bcdf
+            agmt_set_last_update_status_json(ra, STATUS_GOOD, ldaprc, replrc);
83bcdf
         } else { /* agmt_set_last_update_status(0,0,NULL) to reset agmt */
83bcdf
             ra->last_update_status[0] = '\0';
83bcdf
+            ra->last_update_status_json[0] = '\0';
83bcdf
         }
83bcdf
     }
83bcdf
 }
83bcdf
 
83bcdf
+static void
83bcdf
+agmt_set_last_init_status_json(Repl_Agmt *ra, char *state, int ldaprc, int replrc, int connrc)
83bcdf
+{
83bcdf
+    char ts[SLAPI_TIMESTAMP_BUFSIZE];
83bcdf
+    time_t now;
83bcdf
+
83bcdf
+    time(&now;;
83bcdf
+    strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now));
83bcdf
+    PR_snprintf(ra->last_init_status_json, STATUS_LEN,
83bcdf
+            "{\"state\": \"%s\", \"ldap_rc\": \"%d\", \"ldap_rc_text\": \"%s\", \"repl_rc\": \"%d\", \"repl_rc_text\": \"%s\", "
83bcdf
+            "\"conn_rc\": \"%d\", \"conn_rc_text\": \"%s\", \"date\": \"%s\", \"message\": \"%s\"}",
83bcdf
+            state, ldaprc, ldap_err2string(ldaprc), replrc, protocol_response2string(replrc),
83bcdf
+            connrc, conn_result2string(connrc), ts, ra->last_init_status);
83bcdf
+}
83bcdf
+
83bcdf
 void
83bcdf
 agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, const char *message)
83bcdf
 {
83bcdf
@@ -2523,16 +2572,16 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
83bcdf
                     replmsg = NULL;
83bcdf
                 }
83bcdf
             }
83bcdf
-            PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s%sLDAP error: %s%s%s%s%s",
83bcdf
+            PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)%s%sLDAP error: %s%s%s%s%s",
83bcdf
                         ldaprc, message ? message : "", message ? "" : " - ",
83bcdf
                         slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "",
83bcdf
                         connrc ? " - " : "", connrc ? connmsg : "");
83bcdf
+            agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc);
83bcdf
         }
83bcdf
         /* ldaprc == LDAP_SUCCESS */
83bcdf
         else if (replrc != 0) {
83bcdf
             if (replrc == NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED) {
83bcdf
-                PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) %s",
83bcdf
-                            ldaprc, "Replication session successful");
83bcdf
+                PR_snprintf(ra->last_init_status, STATUS_LEN, "Replication session successful");
83bcdf
             } else if (replrc == NSDS50_REPL_DISABLED) {
83bcdf
                 if (agmt_is_enabled(ra)) {
83bcdf
                     slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: "
83bcdf
@@ -2543,6 +2592,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
83bcdf
                                                                   "Replication agreement for \"%s\" can not be updated while the suffix is disabled.\n"
83bcdf
                                                                   "You must enable it then restart the server for replication to take place).",
83bcdf
                                 replrc, ra->long_name ? ra->long_name : "a replica");
83bcdf
+                    agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc);
83bcdf
                 } else {
83bcdf
                     /* You do not need to restart the server after enabling the agreement */
83bcdf
                     slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "Total update aborted: "
83bcdf
@@ -2551,6 +2601,7 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
83bcdf
                     PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d) Total update aborted: "
83bcdf
                                                                   "Replication agreement for \"%s\" can not be updated while the agreement is disabled.",
83bcdf
                                 replrc, ra->long_name ? ra->long_name : "a replica");
83bcdf
+                    agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc);
83bcdf
                 }
83bcdf
             } else {
83bcdf
                 PR_snprintf(ra->last_init_status, STATUS_LEN,
83bcdf
@@ -2558,19 +2609,21 @@ agmt_set_last_init_status(Repl_Agmt *ra, int ldaprc, int replrc, int connrc, con
83bcdf
                             replrc, protocol_response2string(replrc),
83bcdf
                             message ? " - " : "", message ? message : "",
83bcdf
                             connrc ? " - " : "", connrc ? connmsg : "");
83bcdf
+                agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc);
83bcdf
             }
83bcdf
         } else if (connrc != CONN_OPERATION_SUCCESS) {
83bcdf
             PR_snprintf(ra->last_init_status, STATUS_LEN,
83bcdf
                         "Error (%d) connection error: %s%s%s",
83bcdf
                         connrc, connmsg,
83bcdf
                         message ? " - " : "", message ? message : "");
83bcdf
-        } else if (message != NULL) /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
83bcdf
-        {
83bcdf
+            agmt_set_last_init_status_json(ra, STATUS_BAD, ldaprc, replrc, connrc);
83bcdf
+        } else if (message != NULL) { /* replrc == NSDS50_REPL_REPLICA_READY == 0 */
83bcdf
             PR_snprintf(ra->last_init_status, STATUS_LEN,
83bcdf
-                        "Error (%d) %s",
83bcdf
-                        ldaprc, message);
83bcdf
+                        "Error (%d) %s", ldaprc, message);
83bcdf
+            agmt_set_last_init_status_json(ra, STATUS_GOOD, ldaprc, replrc, connrc);
83bcdf
         } else { /* agmt_set_last_init_status(0,0,NULL) to reset agmt */
83bcdf
-            PR_snprintf(ra->last_init_status, STATUS_LEN, "Error (%d)", ldaprc);
83bcdf
+            ra->last_init_status[0] = '\0';
83bcdf
+            ra->last_init_status_json[0] = '\0';
83bcdf
         }
83bcdf
     }
83bcdf
 }
83bcdf
@@ -2705,10 +2758,20 @@ get_agmt_status(Slapi_PBlock *pb __attribute__((unused)),
83bcdf
         agmt_get_changecount_string(ra, changecount_string, sizeof(changecount_string));
83bcdf
         slapi_entry_add_string(e, "nsds5replicaChangesSentSinceStartup", changecount_string);
83bcdf
         if (ra->last_update_status[0] == '\0') {
83bcdf
+            char status_msg[STATUS_LEN];
83bcdf
+            char ts[SLAPI_TIMESTAMP_BUFSIZE];
83bcdf
+            time_t now;
83bcdf
+            time(&now;;
83bcdf
+            strftime(ts, sizeof ts, "%FT%TZ", gmtime(&now));
83bcdf
             slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus",
83bcdf
                                    "Error (0) No replication sessions started since server startup");
83bcdf
+            PR_snprintf(status_msg, STATUS_LEN,
83bcdf
+                    "{\"state\": \"green\", \"ldap_rc\": \"0\", \"ldap_rc_text\": \"success\", \"repl_rc\": \"0\", \"repl_rc_text\": \"replica acquired\", "
83bcdf
+                    "\"date\": \"%s\", \"message\": \"Error (0) No replication sessions started since server startup\"}", ts);
83bcdf
+            slapi_entry_add_string(e, "nsds5replicaLastUpdateStatusJSON", status_msg);
83bcdf
         } else {
83bcdf
             slapi_entry_add_string(e, "nsds5replicaLastUpdateStatus", ra->last_update_status);
83bcdf
+            slapi_entry_add_string(e, "nsds5replicaLastUpdateStatusJSON", ra->last_update_status_json);
83bcdf
         }
83bcdf
         slapi_entry_add_string(e, "nsds5replicaUpdateInProgress", ra->update_in_progress ? "TRUE" : "FALSE");
83bcdf
 
83bcdf
@@ -2724,6 +2787,7 @@ get_agmt_status(Slapi_PBlock *pb __attribute__((unused)),
83bcdf
 
83bcdf
         if (ra->last_init_status[0] != '\0') {
83bcdf
             slapi_entry_add_string(e, "nsds5replicaLastInitStatus", ra->last_init_status);
83bcdf
+            slapi_entry_add_string(e, "nsds5replicaLastInitStatusJSON", ra->last_init_status_json);
83bcdf
         }
83bcdf
     }
83bcdf
 bail:
83bcdf
diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c b/ldap/servers/plugins/replication/repl5_protocol_util.c
83bcdf
index a48d4d02a..bb9f9e7e1 100644
83bcdf
--- a/ldap/servers/plugins/replication/repl5_protocol_util.c
83bcdf
+++ b/ldap/servers/plugins/replication/repl5_protocol_util.c
83bcdf
@@ -374,13 +374,13 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
83bcdf
                                       "has the same Replica ID as this one. "
83bcdf
                                       "Replication is aborting.\n",
83bcdf
                                       agmt_get_long_name(prp->agmt));
83bcdf
-                        agmt_set_last_update_status(prp->agmt, 0, 0,
83bcdf
-                                                    "Unable to aquire replica: the replica has the same "
83bcdf
+                        agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_REPLICAID_ERROR,
83bcdf
+                                                    "Unable to acquire replica: the replica has the same "
83bcdf
                                                     "Replica ID as this one. Replication is aborting.");
83bcdf
                         return_value = ACQUIRE_FATAL_ERROR;
83bcdf
                         break;
83bcdf
                     case NSDS50_REPL_BACKOFF:
83bcdf
-                        /* A replication sesssion hook on the replica
83bcdf
+                        /* A replication session hook on the replica
83bcdf
                          * wants us to go into backoff mode. */
83bcdf
                         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
83bcdf
                                       "acquire_replica - "
83bcdf
@@ -487,9 +487,8 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv)
83bcdf
                           "%s: Unable to obtain current CSN. "
83bcdf
                           "Replication is aborting.\n",
83bcdf
                           agmt_get_long_name(prp->agmt));
83bcdf
-            agmt_set_last_update_status(prp->agmt, 0, 0,
83bcdf
-                                        "Unable to obtain current CSN. "
83bcdf
-                                        "Replication is aborting.");
83bcdf
+            agmt_set_last_update_status(prp->agmt, 0, NSDS50_REPL_INTERNAL_ERROR,
83bcdf
+                                        "Unable to obtain current CSN. Replication is aborting.");
83bcdf
             return_value = ACQUIRE_FATAL_ERROR;
83bcdf
         }
83bcdf
     }
83bcdf
@@ -665,6 +664,8 @@ protocol_response2string(int response)
83bcdf
         return "transient warning";
83bcdf
     case NSDS50_REPL_RUV_ERROR:
83bcdf
         return "RUV error";
83bcdf
+    case NSDS50_REPL_REPLICA_NO_RESPONSE:
83bcdf
+        return "no response received";
83bcdf
     default:
83bcdf
         return "unknown error";
83bcdf
     }
83bcdf
-- 
83bcdf
2.21.0
83bcdf