Blame SOURCES/015-fencing-reasons.patch

97a979
From 87365f49b1bee0baa536783865fbd835a9cacc97 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Thu, 2 Dec 2021 16:12:24 -0600
97a979
Subject: [PATCH 01/11] Refactor: libstonithd: functionize getting notification
97a979
 data XML
97a979
97a979
Also, only get the data when needed.
97a979
---
97a979
 lib/fencing/st_client.c | 32 +++++++++++++++++++++++---------
97a979
 1 file changed, 23 insertions(+), 9 deletions(-)
97a979
97a979
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
97a979
index 4823751267..72a0a49408 100644
97a979
--- a/lib/fencing/st_client.c
97a979
+++ b/lib/fencing/st_client.c
97a979
@@ -1312,6 +1312,23 @@ stonith_dump_pending_callbacks(stonith_t * stonith)
97a979
     return g_hash_table_foreach(private->stonith_op_callback_table, stonith_dump_pending_op, NULL);
97a979
 }
97a979
 
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Get the data section of a fencer notification
97a979
+ *
97a979
+ * \param[in] msg    Notification XML
97a979
+ * \param[in] ntype  Notification type
97a979
+ */
97a979
+static xmlNode *
97a979
+get_event_data_xml(xmlNode *msg, const char *ntype)
97a979
+{
97a979
+    char *data_addr = crm_strdup_printf("//%s", ntype);
97a979
+    xmlNode *data = get_xpath_object(data_addr, msg, LOG_DEBUG);
97a979
+
97a979
+    free(data_addr);
97a979
+    return data;
97a979
+}
97a979
+
97a979
 /*
97a979
  <notify t="st_notify" subt="st_device_register" st_op="st_device_register" st_rc="0" >
97a979
    <st_calldata >
97a979
@@ -1336,17 +1353,18 @@ xml_to_event(xmlNode * msg)
97a979
 {
97a979
     stonith_event_t *event = calloc(1, sizeof(stonith_event_t));
97a979
     const char *ntype = crm_element_value(msg, F_SUBTYPE);
97a979
-    char *data_addr = crm_strdup_printf("//%s", ntype);
97a979
-    xmlNode *data = get_xpath_object(data_addr, msg, LOG_DEBUG);
97a979
 
97a979
     crm_log_xml_trace(msg, "stonith_notify");
97a979
 
97a979
     crm_element_value_int(msg, F_STONITH_RC, &(event->result));
97a979
 
97a979
     if (pcmk__str_eq(ntype, T_STONITH_NOTIFY_FENCE, pcmk__str_casei)) {
97a979
-        event->operation = crm_element_value_copy(msg, F_STONITH_OPERATION);
97a979
+        xmlNode *data = get_event_data_xml(msg, ntype);
97a979
 
97a979
-        if (data) {
97a979
+        if (data == NULL) {
97a979
+            crm_err("No data for %s event", ntype);
97a979
+            crm_log_xml_notice(msg, "BadEvent");
97a979
+        } else {
97a979
             event->origin = crm_element_value_copy(data, F_STONITH_ORIGIN);
97a979
             event->action = crm_element_value_copy(data, F_STONITH_ACTION);
97a979
             event->target = crm_element_value_copy(data, F_STONITH_TARGET);
97a979
@@ -1354,14 +1372,10 @@ xml_to_event(xmlNode * msg)
97a979
             event->id = crm_element_value_copy(data, F_STONITH_REMOTE_OP_ID);
97a979
             event->client_origin = crm_element_value_copy(data, F_STONITH_CLIENTNAME);
97a979
             event->device = crm_element_value_copy(data, F_STONITH_DEVICE);
97a979
-
97a979
-        } else {
97a979
-            crm_err("No data for %s event", ntype);
97a979
-            crm_log_xml_notice(msg, "BadEvent");
97a979
         }
97a979
+        event->operation = crm_element_value_copy(msg, F_STONITH_OPERATION);
97a979
     }
97a979
 
97a979
-    free(data_addr);
97a979
     return event;
97a979
 }
97a979
 
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 448f86a029d5d7e3c255d813929003a8cc2cffba Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Fri, 19 Nov 2021 17:01:23 -0600
97a979
Subject: [PATCH 02/11] Refactor: fencing: parse full result from fencer
97a979
 notifications
97a979
97a979
stonith_event_t previously contained only the legacy return code for the
97a979
notification event. Use its new opaque member to store the full result, along
97a979
with accessors (available only internally for now). Nothing uses them yet.
97a979
---
97a979
 include/crm/fencing/internal.h |  5 +++
97a979
 lib/fencing/st_client.c        | 68 ++++++++++++++++++++++++++++++++--
97a979
 2 files changed, 70 insertions(+), 3 deletions(-)
97a979
97a979
diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h
97a979
index eff689e59b..acc16d05e9 100644
97a979
--- a/include/crm/fencing/internal.h
97a979
+++ b/include/crm/fencing/internal.h
97a979
@@ -187,10 +187,15 @@ bool stonith__event_state_eq(stonith_history_t *history, void *user_data);
97a979
 bool stonith__event_state_neq(stonith_history_t *history, void *user_data);
97a979
 
97a979
 int stonith__legacy2status(int rc);
97a979
+
97a979
 int stonith__exit_status(stonith_callback_data_t *data);
97a979
 int stonith__execution_status(stonith_callback_data_t *data);
97a979
 const char *stonith__exit_reason(stonith_callback_data_t *data);
97a979
 
97a979
+int stonith__event_exit_status(stonith_event_t *event);
97a979
+int stonith__event_execution_status(stonith_event_t *event);
97a979
+const char *stonith__event_exit_reason(stonith_event_t *event);
97a979
+
97a979
 /*!
97a979
  * \internal
97a979
  * \brief Is a fencing operation in pending state?
97a979
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
97a979
index 72a0a49408..f58b3a6745 100644
97a979
--- a/lib/fencing/st_client.c
97a979
+++ b/lib/fencing/st_client.c
97a979
@@ -1349,15 +1349,23 @@ get_event_data_xml(xmlNode *msg, const char *ntype)
97a979
  </notify>
97a979
 */
97a979
 static stonith_event_t *
97a979
-xml_to_event(xmlNode * msg)
97a979
+xml_to_event(xmlNode *msg, pcmk__action_result_t *result)
97a979
 {
97a979
     stonith_event_t *event = calloc(1, sizeof(stonith_event_t));
97a979
     const char *ntype = crm_element_value(msg, F_SUBTYPE);
97a979
 
97a979
+    CRM_ASSERT((event != NULL) && (result != NULL));
97a979
+
97a979
     crm_log_xml_trace(msg, "stonith_notify");
97a979
 
97a979
-    crm_element_value_int(msg, F_STONITH_RC, &(event->result));
97a979
+    // All notification types have the operation result
97a979
+    event->opaque = result;
97a979
+    stonith__xe_get_result(msg, result);
97a979
+
97a979
+    // @COMPAT The API originally provided the result as a legacy return code
97a979
+    event->result = pcmk_rc2legacy(stonith__result2rc(result));
97a979
 
97a979
+    // Fence notifications have additional information
97a979
     if (pcmk__str_eq(ntype, T_STONITH_NOTIFY_FENCE, pcmk__str_casei)) {
97a979
         xmlNode *data = get_event_data_xml(msg, ntype);
97a979
 
97a979
@@ -1392,6 +1400,7 @@ event_free(stonith_event_t * event)
97a979
     free(event->executioner);
97a979
     free(event->device);
97a979
     free(event->client_origin);
97a979
+    pcmk__reset_result((pcmk__action_result_t *) (event->opaque));
97a979
     free(event);
97a979
 }
97a979
 
97a979
@@ -1402,6 +1411,7 @@ stonith_send_notification(gpointer data, gpointer user_data)
97a979
     stonith_notify_client_t *entry = data;
97a979
     stonith_event_t *st_event = NULL;
97a979
     const char *event = NULL;
97a979
+    pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
97a979
 
97a979
     if (blob->xml == NULL) {
97a979
         crm_warn("Skipping callback - NULL message");
97a979
@@ -1427,7 +1437,7 @@ stonith_send_notification(gpointer data, gpointer user_data)
97a979
         return;
97a979
     }
97a979
 
97a979
-    st_event = xml_to_event(blob->xml);
97a979
+    st_event = xml_to_event(blob->xml, &result);
97a979
 
97a979
     crm_trace("Invoking callback for %p/%s event...", entry, event);
97a979
     entry->notify(blob->stonith, st_event);
97a979
@@ -2366,6 +2376,58 @@ stonith__exit_reason(stonith_callback_data_t *data)
97a979
     return ((pcmk__action_result_t *) data->opaque)->exit_reason;
97a979
 }
97a979
 
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Return the exit status from an event notification
97a979
+ *
97a979
+ * \param[in] event  Event
97a979
+ *
97a979
+ * \return Exit status from event
97a979
+ */
97a979
+int
97a979
+stonith__event_exit_status(stonith_event_t *event)
97a979
+{
97a979
+    if ((event == NULL) || (event->opaque == NULL)) {
97a979
+        return CRM_EX_ERROR;
97a979
+    }
97a979
+    return ((pcmk__action_result_t *) event->opaque)->exit_status;
97a979
+}
97a979
+
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Return the execution status from an event notification
97a979
+ *
97a979
+ * \param[in] event  Event
97a979
+ *
97a979
+ * \return Execution status from event
97a979
+ */
97a979
+int
97a979
+stonith__event_execution_status(stonith_event_t *event)
97a979
+{
97a979
+    if ((event == NULL) || (event->opaque == NULL)) {
97a979
+        return PCMK_EXEC_UNKNOWN;
97a979
+    }
97a979
+    return ((pcmk__action_result_t *) event->opaque)->execution_status;
97a979
+}
97a979
+
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Return the exit reason from an event notification
97a979
+ *
97a979
+ * \param[in] event  Event
97a979
+ *
97a979
+ * \return Exit reason from event
97a979
+ */
97a979
+const char *
97a979
+stonith__event_exit_reason(stonith_event_t *event)
97a979
+{
97a979
+    if ((event == NULL) || (event->opaque == NULL)) {
97a979
+        return NULL;
97a979
+    }
97a979
+    return ((pcmk__action_result_t *) event->opaque)->exit_reason;
97a979
+}
97a979
+
97a979
+
97a979
 // Deprecated functions kept only for backward API compatibility
97a979
 // LCOV_EXCL_START
97a979
 
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 8dab65e65fe760052d1151749a7bfb2203445813 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Fri, 19 Nov 2021 17:02:28 -0600
97a979
Subject: [PATCH 03/11] Refactor: fencing: parse full result from synchronous
97a979
 fencer replies
97a979
97a979
stonith_send_command() now parses the full result from synchronous fencer
97a979
replies, and maps that to a legacy return code, rather than parse the legacy
97a979
return code directly.
97a979
97a979
The full result is not used yet, and won't be until we can break backward API
97a979
compatibility, since the API functions that call stonith_send_command()
97a979
currently return a legacy code.
97a979
---
97a979
 lib/fencing/st_client.c | 8 +++++---
97a979
 1 file changed, 5 insertions(+), 3 deletions(-)
97a979
97a979
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
97a979
index f58b3a6745..5fec7529e3 100644
97a979
--- a/lib/fencing/st_client.c
97a979
+++ b/lib/fencing/st_client.c
97a979
@@ -1537,11 +1537,13 @@ stonith_send_command(stonith_t * stonith, const char *op, xmlNode * data, xmlNod
97a979
     crm_element_value_int(op_reply, F_STONITH_CALLID, &reply_id);
97a979
 
97a979
     if (reply_id == stonith->call_id) {
97a979
+        pcmk__action_result_t result = PCMK__UNKNOWN_RESULT;
97a979
+
97a979
         crm_trace("Synchronous reply %d received", reply_id);
97a979
 
97a979
-        if (crm_element_value_int(op_reply, F_STONITH_RC, &rc) != 0) {
97a979
-            rc = -ENOMSG;
97a979
-        }
97a979
+        stonith__xe_get_result(op_reply, &result);
97a979
+        rc = pcmk_rc2legacy(stonith__result2rc(&result));
97a979
+        pcmk__reset_result(&result);
97a979
 
97a979
         if ((call_options & st_opt_discard_reply) || output_data == NULL) {
97a979
             crm_trace("Discarding reply");
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 1beb319d8c62ab93b4c08b26a4e03151906c6189 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Mon, 6 Dec 2021 17:13:44 -0600
97a979
Subject: [PATCH 04/11] Log: fencing: improve cts-fence-helper result logs
97a979
97a979
Use the full result from the fencing event
97a979
---
97a979
 daemons/fenced/cts-fence-helper.c | 12 ++++++++----
97a979
 1 file changed, 8 insertions(+), 4 deletions(-)
97a979
97a979
diff --git a/daemons/fenced/cts-fence-helper.c b/daemons/fenced/cts-fence-helper.c
97a979
index e222a59f9f..858cddc9de 100644
97a979
--- a/daemons/fenced/cts-fence-helper.c
97a979
+++ b/daemons/fenced/cts-fence-helper.c
97a979
@@ -125,10 +125,14 @@ st_callback(stonith_t * st, stonith_event_t * e)
97a979
         crm_exit(CRM_EX_DISCONNECT);
97a979
     }
97a979
 
97a979
-    crm_notice("Operation %s requested by %s %s for peer %s.  %s reported: %s (ref=%s)",
97a979
-               e->operation, e->origin, e->result == pcmk_ok ? "completed" : "failed",
97a979
-               e->target, e->executioner ? e->executioner : "<none>",
97a979
-               pcmk_strerror(e->result), e->id);
97a979
+    crm_notice("Operation '%s' targeting %s by %s for %s: %s (exit=%d, ref=%s)",
97a979
+               ((e->operation == NULL)? "unknown" : e->operation),
97a979
+               ((e->target == NULL)? "no node" : e->target),
97a979
+               ((e->executioner == NULL)? "any node" : e->executioner),
97a979
+               ((e->origin == NULL)? "unknown client" : e->origin),
97a979
+               pcmk_exec_status_str(stonith__event_execution_status(e)),
97a979
+               stonith__event_exit_status(e),
97a979
+               ((e->id == NULL)? "none" : e->id));
97a979
 
97a979
     if (expected_notifications) {
97a979
         expected_notifications--;
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From b26f701833ade5d7441fba317832d6e827bd16d0 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 14 Dec 2021 16:52:09 -0600
97a979
Subject: [PATCH 05/11] Test: cts-fence-helper: update expected return code
97a979
97a979
Before recent changes, libstonithd obtained the fence API's legacy result code
97a979
directly from the fencer's XML reply, meaning that the legacy code was the
97a979
result of the fencer's mapping of the full result (including the action stderr).
97a979
97a979
After those changes, libstonithd now ignores the legacy code in the fencer's
97a979
reply, and instead maps the legacy code itself from the full result in the
97a979
fencer's reply.
97a979
97a979
However, the fencer's reply does not have the action stderr, so failures that
97a979
mapped to -pcmk_err_generic on the server side now map to -ENODATA on the
97a979
client side. Update cts-fence-helper's expected return code to match (neither
97a979
code is particularly useful, so there wouldn't be much benefit from having the
97a979
fencer pass the action stderr with replies, which would be considerable
97a979
additional work).
97a979
---
97a979
 daemons/fenced/cts-fence-helper.c | 4 ++--
97a979
 1 file changed, 2 insertions(+), 2 deletions(-)
97a979
97a979
diff --git a/daemons/fenced/cts-fence-helper.c b/daemons/fenced/cts-fence-helper.c
97a979
index 858cddc9de..e3113452ef 100644
97a979
--- a/daemons/fenced/cts-fence-helper.c
97a979
+++ b/daemons/fenced/cts-fence-helper.c
97a979
@@ -207,10 +207,10 @@ run_fence_failure_test(void)
97a979
                 "Register device1 for failure test", 1, 0);
97a979
 
97a979
     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "off", 3, 0),
97a979
-                "Fence failure results off", 1, -pcmk_err_generic);
97a979
+                "Fence failure results off", 1, -ENODATA);
97a979
 
97a979
     single_test(st->cmds->fence(st, st_opts, "false_1_node2", "reboot", 3, 0),
97a979
-                "Fence failure results reboot", 1, -pcmk_err_generic);
97a979
+                "Fence failure results reboot", 1, -ENODATA);
97a979
 
97a979
     single_test(st->cmds->remove_device(st, st_opts, "test-id1"),
97a979
                 "Remove device1 for failure test", 1, 0);
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 123429de229c2148e320c76530b95e6ba458b9f6 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 7 Dec 2021 10:28:48 -0600
97a979
Subject: [PATCH 06/11] Low: controller: compare fencing targets
97a979
 case-insensitively
97a979
97a979
... since they are node names
97a979
---
97a979
 daemons/controld/controld_fencing.c | 2 +-
97a979
 1 file changed, 1 insertion(+), 1 deletion(-)
97a979
97a979
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
97a979
index f8d2fc13f4..70e141dc28 100644
97a979
--- a/daemons/controld/controld_fencing.c
97a979
+++ b/daemons/controld/controld_fencing.c
97a979
@@ -466,7 +466,7 @@ tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
         return;
97a979
 
97a979
     } else if ((st_event->result == pcmk_ok)
97a979
-               && pcmk__str_eq(st_event->target, fsa_our_uname, pcmk__str_none)) {
97a979
+               && pcmk__str_eq(st_event->target, fsa_our_uname, pcmk__str_casei)) {
97a979
 
97a979
         /* We were notified of our own fencing. Most likely, either fencing was
97a979
          * misconfigured, or fabric fencing that doesn't cut cluster
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 3a067b8e58b3aefb49b2af1c35d0ad28b2de8784 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 7 Dec 2021 10:37:56 -0600
97a979
Subject: [PATCH 07/11] Refactor: controller: best practices for handling
97a979
 fencing notifications
97a979
97a979
Rename tengine_stonith_notify() to handle_fence_notification(), rename its
97a979
st_event argument to event, add a doxygen block, and use some new variables and
97a979
reformatting to make it easier to follow (and change later).
97a979
---
97a979
 daemons/controld/controld_fencing.c | 131 ++++++++++++++++------------
97a979
 1 file changed, 75 insertions(+), 56 deletions(-)
97a979
97a979
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
97a979
index 70e141dc28..00626444da 100644
97a979
--- a/daemons/controld/controld_fencing.c
97a979
+++ b/daemons/controld/controld_fencing.c
97a979
@@ -435,39 +435,59 @@ tengine_stonith_connection_destroy(stonith_t *st, stonith_event_t *e)
97a979
     }
97a979
 }
97a979
 
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Handle an event notification from the fencing API
97a979
+ *
97a979
+ * \param[in] st     Fencing API connection
97a979
+ * \param[in] event  Fencing API event notification
97a979
+ */
97a979
 static void
97a979
-tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
+handle_fence_notification(stonith_t *st, stonith_event_t *event)
97a979
 {
97a979
+    bool succeeded = true;
97a979
+    const char *executioner = "the cluster";
97a979
+    const char *client = "a client";
97a979
+
97a979
     if (te_client_id == NULL) {
97a979
         te_client_id = crm_strdup_printf("%s.%lu", crm_system_name,
97a979
                                          (unsigned long) getpid());
97a979
     }
97a979
 
97a979
-    if (st_event == NULL) {
97a979
+    if (event == NULL) {
97a979
         crm_err("Notify data not found");
97a979
         return;
97a979
     }
97a979
 
97a979
-    crmd_alert_fencing_op(st_event);
97a979
+    if (event->executioner != NULL) {
97a979
+        executioner = event->executioner;
97a979
+    }
97a979
+    if (event->client_origin != NULL) {
97a979
+        client = event->client_origin;
97a979
+    }
97a979
 
97a979
-    if ((st_event->result == pcmk_ok) && pcmk__str_eq("on", st_event->action, pcmk__str_casei)) {
97a979
-        crm_notice("%s was successfully unfenced by %s (at the request of %s)",
97a979
-                   st_event->target,
97a979
-                   st_event->executioner? st_event->executioner : "<anyone>",
97a979
-                   st_event->origin);
97a979
-                /* TODO: Hook up st_event->device */
97a979
-        return;
97a979
+    if (event->result != pcmk_ok) {
97a979
+        succeeded = false;
97a979
+    }
97a979
 
97a979
-    } else if (pcmk__str_eq("on", st_event->action, pcmk__str_casei)) {
97a979
-        crm_err("Unfencing of %s by %s failed: %s (%d)",
97a979
-                st_event->target,
97a979
-                st_event->executioner? st_event->executioner : "<anyone>",
97a979
-                pcmk_strerror(st_event->result), st_event->result);
97a979
-        return;
97a979
+    crmd_alert_fencing_op(event);
97a979
 
97a979
-    } else if ((st_event->result == pcmk_ok)
97a979
-               && pcmk__str_eq(st_event->target, fsa_our_uname, pcmk__str_casei)) {
97a979
+    if (pcmk__str_eq("on", event->action, pcmk__str_none)) {
97a979
+        // Unfencing doesn't need special handling, just a log message
97a979
+        if (succeeded) {
97a979
+            crm_notice("%s was successfully unfenced by %s (at the request of %s)",
97a979
+                       event->target, executioner, event->origin);
97a979
+                    /* TODO: Hook up event->device */
97a979
+        } else {
97a979
+            crm_err("Unfencing of %s by %s failed: %s (%d)",
97a979
+                    event->target, executioner,
97a979
+                    pcmk_strerror(st_event->result), st_event->result);
97a979
+        }
97a979
+        return;
97a979
+    }
97a979
 
97a979
+    if (succeeded
97a979
+        && pcmk__str_eq(event->target, fsa_our_uname, pcmk__str_casei)) {
97a979
         /* We were notified of our own fencing. Most likely, either fencing was
97a979
          * misconfigured, or fabric fencing that doesn't cut cluster
97a979
          * communication is in use.
97a979
@@ -478,44 +498,41 @@ tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
          * our subsequent election votes as "not part of our cluster".
97a979
          */
97a979
         crm_crit("We were allegedly just fenced by %s for %s!",
97a979
-                 st_event->executioner? st_event->executioner : "the cluster",
97a979
-                 st_event->origin); /* Dumps blackbox if enabled */
97a979
+                 executioner, event->origin); // Dumps blackbox if enabled
97a979
         if (fence_reaction_panic) {
97a979
             pcmk__panic(__func__);
97a979
         } else {
97a979
             crm_exit(CRM_EX_FATAL);
97a979
         }
97a979
-        return;
97a979
+        return; // Should never get here
97a979
     }
97a979
 
97a979
-    /* Update the count of stonith failures for this target, in case we become
97a979
+    /* Update the count of fencing failures for this target, in case we become
97a979
      * DC later. The current DC has already updated its fail count in
97a979
      * tengine_stonith_callback().
97a979
      */
97a979
-    if (!AM_I_DC && pcmk__str_eq(st_event->operation, T_STONITH_NOTIFY_FENCE, pcmk__str_casei)) {
97a979
-        if (st_event->result == pcmk_ok) {
97a979
-            st_fail_count_reset(st_event->target);
97a979
+    if (!AM_I_DC
97a979
+        && pcmk__str_eq(event->operation, T_STONITH_NOTIFY_FENCE,
97a979
+                        pcmk__str_casei)) {
97a979
+
97a979
+        if (succeeded) {
97a979
+            st_fail_count_reset(event->target);
97a979
         } else {
97a979
-            st_fail_count_increment(st_event->target);
97a979
+            st_fail_count_increment(event->target);
97a979
         }
97a979
     }
97a979
 
97a979
     crm_notice("Peer %s was%s terminated (%s) by %s on behalf of %s: %s "
97a979
                CRM_XS " initiator=%s ref=%s",
97a979
-               st_event->target, st_event->result == pcmk_ok ? "" : " not",
97a979
-               st_event->action,
97a979
-               st_event->executioner ? st_event->executioner : "<anyone>",
97a979
-               (st_event->client_origin? st_event->client_origin : "<unknown>"),
97a979
-               pcmk_strerror(st_event->result),
97a979
-               st_event->origin, st_event->id);
97a979
-
97a979
-    if (st_event->result == pcmk_ok) {
97a979
-        crm_node_t *peer = pcmk__search_known_node_cache(0, st_event->target,
97a979
+               event->target, (succeeded? "" : " not"),
97a979
+               event->action, executioner, client,
97a979
+               pcmk_strerror(event->result),
97a979
+               event->origin, event->id);
97a979
+
97a979
+    if (succeeded) {
97a979
+        crm_node_t *peer = pcmk__search_known_node_cache(0, event->target,
97a979
                                                          CRM_GET_PEER_ANY);
97a979
         const char *uuid = NULL;
97a979
-        gboolean we_are_executioner = pcmk__str_eq(st_event->executioner,
97a979
-                                                   fsa_our_uname,
97a979
-                                                   pcmk__str_casei);
97a979
 
97a979
         if (peer == NULL) {
97a979
             return;
97a979
@@ -523,10 +540,9 @@ tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
 
97a979
         uuid = crm_peer_uuid(peer);
97a979
 
97a979
-        crm_trace("target=%s dc=%s", st_event->target, fsa_our_dc);
97a979
-        if(AM_I_DC) {
97a979
+        if (AM_I_DC) {
97a979
             /* The DC always sends updates */
97a979
-            send_stonith_update(NULL, st_event->target, uuid);
97a979
+            send_stonith_update(NULL, event->target, uuid);
97a979
 
97a979
             /* @TODO Ideally, at this point, we'd check whether the fenced node
97a979
              * hosted any guest nodes, and call remote_node_down() for them.
97a979
@@ -536,31 +552,33 @@ tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
              * on the scheduler creating fence pseudo-events for the guests.
97a979
              */
97a979
 
97a979
-            if (st_event->client_origin
97a979
-                && !pcmk__str_eq(st_event->client_origin, te_client_id, pcmk__str_casei)) {
97a979
-
97a979
-                /* Abort the current transition graph if it wasn't us
97a979
-                 * that invoked stonith to fence someone
97a979
+            if (!pcmk__str_eq(client, te_client_id, pcmk__str_casei)) {
97a979
+                /* Abort the current transition if it wasn't the cluster that
97a979
+                 * initiated fencing.
97a979
                  */
97a979
-                crm_info("External fencing operation from %s fenced %s", st_event->client_origin, st_event->target);
97a979
-                abort_transition(INFINITY, tg_restart, "External Fencing Operation", NULL);
97a979
+                crm_info("External fencing operation from %s fenced %s",
97a979
+                         client, event->target);
97a979
+                abort_transition(INFINITY, tg_restart,
97a979
+                                 "External Fencing Operation", NULL);
97a979
             }
97a979
 
97a979
             /* Assume it was our leader if we don't currently have one */
97a979
-        } else if (pcmk__str_eq(fsa_our_dc, st_event->target, pcmk__str_null_matches | pcmk__str_casei)
97a979
+        } else if (pcmk__str_eq(fsa_our_dc, event->target,
97a979
+                                pcmk__str_null_matches|pcmk__str_casei)
97a979
                    && !pcmk_is_set(peer->flags, crm_remote_node)) {
97a979
 
97a979
             crm_notice("Fencing target %s %s our leader",
97a979
-                       st_event->target, (fsa_our_dc? "was" : "may have been"));
97a979
+                       event->target, (fsa_our_dc? "was" : "may have been"));
97a979
 
97a979
             /* Given the CIB resyncing that occurs around elections,
97a979
              * have one node update the CIB now and, if the new DC is different,
97a979
              * have them do so too after the election
97a979
              */
97a979
-            if (we_are_executioner) {
97a979
-                send_stonith_update(NULL, st_event->target, uuid);
97a979
+            if (pcmk__str_eq(event->executioner, fsa_our_uname,
97a979
+                             pcmk__str_casei)) {
97a979
+                send_stonith_update(NULL, event->target, uuid);
97a979
             }
97a979
-            add_stonith_cleanup(st_event->target);
97a979
+            add_stonith_cleanup(event->target);
97a979
         }
97a979
 
97a979
         /* If the target is a remote node, and we host its connection,
97a979
@@ -569,7 +587,7 @@ tengine_stonith_notify(stonith_t *st, stonith_event_t *st_event)
97a979
          * so the failure might not otherwise be detected until the next poke.
97a979
          */
97a979
         if (pcmk_is_set(peer->flags, crm_remote_node)) {
97a979
-            remote_ra_fail(st_event->target);
97a979
+            remote_ra_fail(event->target);
97a979
         }
97a979
 
97a979
         crmd_peer_down(peer, TRUE);
97a979
@@ -632,7 +650,7 @@ te_connect_stonith(gpointer user_data)
97a979
                                                  tengine_stonith_connection_destroy);
97a979
         stonith_api->cmds->register_notification(stonith_api,
97a979
                                                  T_STONITH_NOTIFY_FENCE,
97a979
-                                                 tengine_stonith_notify);
97a979
+                                                 handle_fence_notification);
97a979
         stonith_api->cmds->register_notification(stonith_api,
97a979
                                                  T_STONITH_NOTIFY_HISTORY_SYNCED,
97a979
                                                  tengine_stonith_history_synced);
97a979
@@ -837,7 +855,8 @@ tengine_stonith_callback(stonith_t *stonith, stonith_callback_data_t *data)
97a979
         }
97a979
 
97a979
         /* Increment the fail count now, so abort_for_stonith_failure() can
97a979
-         * check it. Non-DC nodes will increment it in tengine_stonith_notify().
97a979
+         * check it. Non-DC nodes will increment it in
97a979
+         * handle_fence_notification().
97a979
          */
97a979
         st_fail_count_increment(target);
97a979
         abort_for_stonith_failure(abort_action, target, NULL);
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 5ec9dcbbe1ee7f6252968f87d7df5a5ea17244fb Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 7 Dec 2021 10:40:21 -0600
97a979
Subject: [PATCH 08/11] Log: controller: improve messages when handling fencing
97a979
 notifications
97a979
97a979
Now that the fencing API provides a full result including exit reasons with
97a979
fencing event notifications, make the controller logs more useful and
97a979
consistent.
97a979
---
97a979
 daemons/controld/controld_fencing.c | 34 ++++++++++++++++++++---------
97a979
 1 file changed, 24 insertions(+), 10 deletions(-)
97a979
97a979
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
97a979
index 00626444da..0aa9ef083c 100644
97a979
--- a/daemons/controld/controld_fencing.c
97a979
+++ b/daemons/controld/controld_fencing.c
97a979
@@ -448,6 +448,8 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event)
97a979
     bool succeeded = true;
97a979
     const char *executioner = "the cluster";
97a979
     const char *client = "a client";
97a979
+    const char *reason = NULL;
97a979
+    int exec_status;
97a979
 
97a979
     if (te_client_id == NULL) {
97a979
         te_client_id = crm_strdup_printf("%s.%lu", crm_system_name,
97a979
@@ -466,22 +468,31 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event)
97a979
         client = event->client_origin;
97a979
     }
97a979
 
97a979
-    if (event->result != pcmk_ok) {
97a979
+    exec_status = stonith__event_execution_status(event);
97a979
+    if ((stonith__event_exit_status(event) != CRM_EX_OK)
97a979
+        || (exec_status != PCMK_EXEC_DONE)) {
97a979
         succeeded = false;
97a979
+        if (exec_status == PCMK_EXEC_DONE) {
97a979
+            exec_status = PCMK_EXEC_ERROR;
97a979
+        }
97a979
     }
97a979
+    reason = stonith__event_exit_reason(event);
97a979
 
97a979
     crmd_alert_fencing_op(event);
97a979
 
97a979
     if (pcmk__str_eq("on", event->action, pcmk__str_none)) {
97a979
         // Unfencing doesn't need special handling, just a log message
97a979
         if (succeeded) {
97a979
-            crm_notice("%s was successfully unfenced by %s (at the request of %s)",
97a979
-                       event->target, executioner, event->origin);
97a979
+            crm_notice("%s was unfenced by %s at the request of %s@%s",
97a979
+                       event->target, executioner, client, event->origin);
97a979
                     /* TODO: Hook up event->device */
97a979
         } else {
97a979
-            crm_err("Unfencing of %s by %s failed: %s (%d)",
97a979
+            crm_err("Unfencing of %s by %s failed (%s%s%s) with exit status %d",
97a979
                     event->target, executioner,
97a979
-                    pcmk_strerror(st_event->result), st_event->result);
97a979
+                    pcmk_exec_status_str(exec_status),
97a979
+                    ((reason == NULL)? "" : ": "),
97a979
+                    ((reason == NULL)? "" : reason),
97a979
+                    stonith__event_exit_status(event));
97a979
         }
97a979
         return;
97a979
     }
97a979
@@ -522,12 +533,15 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event)
97a979
         }
97a979
     }
97a979
 
97a979
-    crm_notice("Peer %s was%s terminated (%s) by %s on behalf of %s: %s "
97a979
-               CRM_XS " initiator=%s ref=%s",
97a979
+    crm_notice("Peer %s was%s terminated (%s) by %s on behalf of %s@%s: "
97a979
+               "%s%s%s%s " CRM_XS " event=%s",
97a979
                event->target, (succeeded? "" : " not"),
97a979
-               event->action, executioner, client,
97a979
-               pcmk_strerror(event->result),
97a979
-               event->origin, event->id);
97a979
+               event->action, executioner, client, event->origin,
97a979
+               (succeeded? "OK" : pcmk_exec_status_str(exec_status)),
97a979
+               ((reason == NULL)? "" : " ("),
97a979
+               ((reason == NULL)? "" : reason),
97a979
+               ((reason == NULL)? "" : ")"),
97a979
+               event->id);
97a979
 
97a979
     if (succeeded) {
97a979
         crm_node_t *peer = pcmk__search_known_node_cache(0, event->target,
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From fb484933ce7c8f3325300a9e01a114db1bbb5b70 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 7 Dec 2021 11:33:15 -0600
97a979
Subject: [PATCH 09/11] Refactor: controller: move alert functions into own
97a979
 source file
97a979
97a979
---
97a979
 daemons/controld/Makefile.am            |  1 +
97a979
 daemons/controld/controld_alerts.c      | 92 +++++++++++++++++++++++++
97a979
 daemons/controld/controld_execd_state.c | 75 --------------------
97a979
 3 files changed, 93 insertions(+), 75 deletions(-)
97a979
 create mode 100644 daemons/controld/controld_alerts.c
97a979
97a979
diff --git a/daemons/controld/Makefile.am b/daemons/controld/Makefile.am
97a979
index db45bcba4a..0a29925c0b 100644
97a979
--- a/daemons/controld/Makefile.am
97a979
+++ b/daemons/controld/Makefile.am
97a979
@@ -43,6 +43,7 @@ pacemaker_controld_LDADD = $(top_builddir)/lib/fencing/libstonithd.la		\
97a979
 			   $(CLUSTERLIBS)
97a979
 
97a979
 pacemaker_controld_SOURCES = pacemaker-controld.c	\
97a979
+			     controld_alerts.c		\
97a979
 			     controld_attrd.c		\
97a979
 			     controld_callbacks.c	\
97a979
 			     controld_based.c		\
97a979
diff --git a/daemons/controld/controld_alerts.c b/daemons/controld/controld_alerts.c
97a979
new file mode 100644
97a979
index 0000000000..bd92795cf0
97a979
--- /dev/null
97a979
+++ b/daemons/controld/controld_alerts.c
97a979
@@ -0,0 +1,92 @@
97a979
+/*
97a979
+ * Copyright 2012-2021 the Pacemaker project contributors
97a979
+ *
97a979
+ * The version control history for this file may have further details.
97a979
+ *
97a979
+ * This source code is licensed under the GNU General Public License version 2
97a979
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
97a979
+ */
97a979
+
97a979
+#include <crm_internal.h>
97a979
+
97a979
+#include <glib.h>
97a979
+#include <libxml/tree.h>
97a979
+
97a979
+#include <crm/lrmd.h>
97a979
+#include <crm/lrmd_internal.h>
97a979
+#include <crm/pengine/rules_internal.h>
97a979
+#include <crm/pengine/status.h>
97a979
+#include <crm/stonith-ng.h>
97a979
+
97a979
+#include <pacemaker-controld.h>
97a979
+
97a979
+static GList *crmd_alert_list = NULL;
97a979
+
97a979
+void
97a979
+crmd_unpack_alerts(xmlNode *alerts)
97a979
+{
97a979
+    pe_free_alert_list(crmd_alert_list);
97a979
+    crmd_alert_list = pe_unpack_alerts(alerts);
97a979
+}
97a979
+
97a979
+void
97a979
+crmd_alert_node_event(crm_node_t *node)
97a979
+{
97a979
+    lrm_state_t *lrm_state;
97a979
+
97a979
+    if (crmd_alert_list == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    lrm_state = lrm_state_find(fsa_our_uname);
97a979
+    if (lrm_state == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    lrmd_send_node_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
97a979
+                         node->uname, node->id, node->state);
97a979
+}
97a979
+
97a979
+void
97a979
+crmd_alert_fencing_op(stonith_event_t * e)
97a979
+{
97a979
+    char *desc;
97a979
+    lrm_state_t *lrm_state;
97a979
+
97a979
+    if (crmd_alert_list == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    lrm_state = lrm_state_find(fsa_our_uname);
97a979
+    if (lrm_state == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    desc = crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s (ref=%s)",
97a979
+                             e->action, e->target,
97a979
+                             (e->executioner? e->executioner : "<no-one>"),
97a979
+                             e->client_origin, e->origin,
97a979
+                             pcmk_strerror(e->result), e->id);
97a979
+
97a979
+    lrmd_send_fencing_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
97a979
+                            e->target, e->operation, desc, e->result);
97a979
+    free(desc);
97a979
+}
97a979
+
97a979
+void
97a979
+crmd_alert_resource_op(const char *node, lrmd_event_data_t * op)
97a979
+{
97a979
+    lrm_state_t *lrm_state;
97a979
+
97a979
+    if (crmd_alert_list == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    lrm_state = lrm_state_find(fsa_our_uname);
97a979
+    if (lrm_state == NULL) {
97a979
+        return;
97a979
+    }
97a979
+
97a979
+    lrmd_send_resource_alert((lrmd_t *) lrm_state->conn, crmd_alert_list, node,
97a979
+                             op);
97a979
+}
97a979
diff --git a/daemons/controld/controld_execd_state.c b/daemons/controld/controld_execd_state.c
97a979
index 67c376a426..5dce6c6d59 100644
97a979
--- a/daemons/controld/controld_execd_state.c
97a979
+++ b/daemons/controld/controld_execd_state.c
97a979
@@ -777,78 +777,3 @@ lrm_state_unregister_rsc(lrm_state_t * lrm_state,
97a979
      */
97a979
     return ((lrmd_t *) lrm_state->conn)->cmds->unregister_rsc(lrm_state->conn, rsc_id, options);
97a979
 }
97a979
-
97a979
-/*
97a979
- * Functions for sending alerts via local executor connection
97a979
- */
97a979
-
97a979
-static GList *crmd_alert_list = NULL;
97a979
-
97a979
-void
97a979
-crmd_unpack_alerts(xmlNode *alerts)
97a979
-{
97a979
-    pe_free_alert_list(crmd_alert_list);
97a979
-    crmd_alert_list = pe_unpack_alerts(alerts);
97a979
-}
97a979
-
97a979
-void
97a979
-crmd_alert_node_event(crm_node_t *node)
97a979
-{
97a979
-    lrm_state_t *lrm_state;
97a979
-
97a979
-    if (crmd_alert_list == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    lrm_state = lrm_state_find(fsa_our_uname);
97a979
-    if (lrm_state == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    lrmd_send_node_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
97a979
-                         node->uname, node->id, node->state);
97a979
-}
97a979
-
97a979
-void
97a979
-crmd_alert_fencing_op(stonith_event_t * e)
97a979
-{
97a979
-    char *desc;
97a979
-    lrm_state_t *lrm_state;
97a979
-
97a979
-    if (crmd_alert_list == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    lrm_state = lrm_state_find(fsa_our_uname);
97a979
-    if (lrm_state == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    desc = crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s (ref=%s)",
97a979
-                             e->action, e->target,
97a979
-                             (e->executioner? e->executioner : "<no-one>"),
97a979
-                             e->client_origin, e->origin,
97a979
-                             pcmk_strerror(e->result), e->id);
97a979
-
97a979
-    lrmd_send_fencing_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
97a979
-                            e->target, e->operation, desc, e->result);
97a979
-    free(desc);
97a979
-}
97a979
-
97a979
-void
97a979
-crmd_alert_resource_op(const char *node, lrmd_event_data_t * op)
97a979
-{
97a979
-    lrm_state_t *lrm_state;
97a979
-
97a979
-    if (crmd_alert_list == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    lrm_state = lrm_state_find(fsa_our_uname);
97a979
-    if (lrm_state == NULL) {
97a979
-        return;
97a979
-    }
97a979
-
97a979
-    lrmd_send_resource_alert((lrmd_t *) lrm_state->conn, crmd_alert_list, node,
97a979
-                             op);
97a979
-}
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 3d0b57406bcde6682623e9d62c8ee95878345eb1 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Tue, 7 Dec 2021 11:25:41 -0600
97a979
Subject: [PATCH 10/11] Feature: controller,tools: improve description for
97a979
 fencing alerts/traps
97a979
97a979
This functionizes creating a description for fencing events, so it can be used
97a979
by both the controller for alerts and crm_mon for traps, for consistency.
97a979
97a979
Now that we have the full result including exit reason, we can improve the
97a979
description, but the format is kept similar to before to minimize the change.
97a979
97a979
The alert/trap also includes the legacy return code for the event, but we can't
97a979
change that now because lrmd_send_fencing_alert() and the alert/trap
97a979
environment variables are public API.
97a979
---
97a979
 daemons/controld/controld_alerts.c |  8 ++-----
97a979
 include/crm/fencing/internal.h     |  1 +
97a979
 lib/fencing/st_client.c            | 38 ++++++++++++++++++++++++++++++
97a979
 tools/crm_mon.c                    |  5 ++--
97a979
 4 files changed, 43 insertions(+), 9 deletions(-)
97a979
97a979
diff --git a/daemons/controld/controld_alerts.c b/daemons/controld/controld_alerts.c
97a979
index bd92795cf0..2e0a67dba2 100644
97a979
--- a/daemons/controld/controld_alerts.c
97a979
+++ b/daemons/controld/controld_alerts.c
97a979
@@ -12,6 +12,7 @@
97a979
 #include <glib.h>
97a979
 #include <libxml/tree.h>
97a979
 
97a979
+#include <crm/fencing/internal.h>
97a979
 #include <crm/lrmd.h>
97a979
 #include <crm/lrmd_internal.h>
97a979
 #include <crm/pengine/rules_internal.h>
97a979
@@ -62,12 +63,7 @@ crmd_alert_fencing_op(stonith_event_t * e)
97a979
         return;
97a979
     }
97a979
 
97a979
-    desc = crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s (ref=%s)",
97a979
-                             e->action, e->target,
97a979
-                             (e->executioner? e->executioner : "<no-one>"),
97a979
-                             e->client_origin, e->origin,
97a979
-                             pcmk_strerror(e->result), e->id);
97a979
-
97a979
+    desc = stonith__event_description(e);
97a979
     lrmd_send_fencing_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
97a979
                             e->target, e->operation, desc, e->result);
97a979
     free(desc);
97a979
diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h
97a979
index acc16d05e9..d2b49f831a 100644
97a979
--- a/include/crm/fencing/internal.h
97a979
+++ b/include/crm/fencing/internal.h
97a979
@@ -195,6 +195,7 @@ const char *stonith__exit_reason(stonith_callback_data_t *data);
97a979
 int stonith__event_exit_status(stonith_event_t *event);
97a979
 int stonith__event_execution_status(stonith_event_t *event);
97a979
 const char *stonith__event_exit_reason(stonith_event_t *event);
97a979
+char *stonith__event_description(stonith_event_t *event);
97a979
 
97a979
 /*!
97a979
  * \internal
97a979
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
97a979
index 5fec7529e3..b1de912b2a 100644
97a979
--- a/lib/fencing/st_client.c
97a979
+++ b/lib/fencing/st_client.c
97a979
@@ -2429,6 +2429,44 @@ stonith__event_exit_reason(stonith_event_t *event)
97a979
     return ((pcmk__action_result_t *) event->opaque)->exit_reason;
97a979
 }
97a979
 
97a979
+/*!
97a979
+ * \internal
97a979
+ * \brief Return a human-friendly description of a fencing event
97a979
+ *
97a979
+ * \param[in] event  Event to describe
97a979
+ *
97a979
+ * \return Newly allocated string with description of \p event
97a979
+ * \note The caller is responsible for freeing the return value.
97a979
+ *       This function asserts on memory errors and never returns NULL.
97a979
+ * \note This currently is useful only for events of type
97a979
+ *       T_STONITH_NOTIFY_FENCE.
97a979
+ */
97a979
+char *
97a979
+stonith__event_description(stonith_event_t *event)
97a979
+{
97a979
+    const char *reason;
97a979
+    const char *status;
97a979
+
97a979
+    if (stonith__event_execution_status(event) != PCMK_EXEC_DONE) {
97a979
+        status = pcmk_exec_status_str(stonith__event_execution_status(event));
97a979
+    } else if (stonith__event_exit_status(event) != CRM_EX_OK) {
97a979
+        status = pcmk_exec_status_str(PCMK_EXEC_ERROR);
97a979
+    } else {
97a979
+        status = crm_exit_str(CRM_EX_OK);
97a979
+    }
97a979
+    reason = stonith__event_exit_reason(event);
97a979
+
97a979
+    return crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s%s%s%s (ref=%s)",
97a979
+                             event->action, event->target,
97a979
+                             (event->executioner? event->executioner : "the cluster"),
97a979
+                             (event->client_origin? event->client_origin : "a client"),
97a979
+                             event->origin, status,
97a979
+                             ((reason == NULL)? "" : " ("),
97a979
+                             ((reason == NULL)? "" : reason),
97a979
+                             ((reason == NULL)? "" : ")"),
97a979
+                             event->id);
97a979
+}
97a979
+
97a979
 
97a979
 // Deprecated functions kept only for backward API compatibility
97a979
 // LCOV_EXCL_START
97a979
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
97a979
index a6c459aaf7..e7b4fe2847 100644
97a979
--- a/tools/crm_mon.c
97a979
+++ b/tools/crm_mon.c
97a979
@@ -2237,9 +2237,8 @@ mon_st_callback_event(stonith_t * st, stonith_event_t * e)
97a979
         /* disconnect cib as well and have everything reconnect */
97a979
         mon_cib_connection_destroy(NULL);
97a979
     } else if (options.external_agent) {
97a979
-        char *desc = crm_strdup_printf("Operation %s requested by %s for peer %s: %s (ref=%s)",
97a979
-                                    e->operation, e->origin, e->target, pcmk_strerror(e->result),
97a979
-                                    e->id);
97a979
+        char *desc = stonith__event_description(e);
97a979
+
97a979
         send_custom_trap(e->target, NULL, e->operation, pcmk_ok, e->result, 0, desc);
97a979
         free(desc);
97a979
     }
97a979
-- 
97a979
2.27.0
97a979
97a979
97a979
From 2fe03c2165680c717a1f6106c5150be7d117f1a5 Mon Sep 17 00:00:00 2001
97a979
From: Ken Gaillot <kgaillot@redhat.com>
97a979
Date: Fri, 14 Jan 2022 10:45:03 -0600
97a979
Subject: [PATCH 11/11] Low: controller: compare case-sensitively where
97a979
 appropriate
97a979
97a979
---
97a979
 daemons/controld/controld_fencing.c | 4 ++--
97a979
 1 file changed, 2 insertions(+), 2 deletions(-)
97a979
97a979
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
97a979
index 0aa9ef083c..15954b2358 100644
97a979
--- a/daemons/controld/controld_fencing.c
97a979
+++ b/daemons/controld/controld_fencing.c
97a979
@@ -1,5 +1,5 @@
97a979
 /*
97a979
- * Copyright 2004-2021 the Pacemaker project contributors
97a979
+ * Copyright 2004-2022 the Pacemaker project contributors
97a979
  *
97a979
  * The version control history for this file may have further details.
97a979
  *
97a979
@@ -524,7 +524,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event)
97a979
      */
97a979
     if (!AM_I_DC
97a979
         && pcmk__str_eq(event->operation, T_STONITH_NOTIFY_FENCE,
97a979
-                        pcmk__str_casei)) {
97a979
+                        pcmk__str_none)) {
97a979
 
97a979
         if (succeeded) {
97a979
             st_fail_count_reset(event->target);
97a979
-- 
97a979
2.27.0
97a979