Blame SOURCES/015-fencing-reasons.patch

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