Blame SOURCES/015-fencing-reasons.patch

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