Blame SOURCES/017-fencing-reasons.patch

f312c6
From 523f62eb235836a01ea039c23ada261a494f7b32 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Wed, 10 Nov 2021 15:22:47 -0600
f312c6
Subject: [PATCH 01/11] Feature: libpacemaker: improve result for high-level
f312c6
 fencing API
f312c6
f312c6
Previously, pcmk__fencing_action()'s helpers for asynchronous fencing actions
f312c6
initialized the result to a generic error, and then overrode that only on
f312c6
success.
f312c6
f312c6
Now, set a detailed result for early failures, and use the full result when
f312c6
available from the fencing API.
f312c6
f312c6
A standard return code is still returned to callers at this point.
f312c6
---
f312c6
 lib/pacemaker/pcmk_fence.c | 31 ++++++++++++++++++-------------
f312c6
 1 file changed, 18 insertions(+), 13 deletions(-)
f312c6
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index 7d6acd0de6..125e1b268b 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -32,8 +32,8 @@ static struct {
f312c6
     unsigned int timeout;
f312c6
     unsigned int tolerance;
f312c6
     int delay;
f312c6
-    int rc;
f312c6
-} async_fence_data;
f312c6
+    pcmk__action_result_t result;
f312c6
+} async_fence_data = { NULL, };
f312c6
 
f312c6
 static int
f312c6
 handle_level(stonith_t *st, char *target, int fence_level,
f312c6
@@ -76,14 +76,13 @@ handle_level(stonith_t *st, char *target, int fence_level,
f312c6
 static void
f312c6
 notify_callback(stonith_t * st, stonith_event_t * e)
f312c6
 {
f312c6
-    if (e->result != pcmk_ok) {
f312c6
-        return;
f312c6
-    }
f312c6
+    if (pcmk__str_eq(async_fence_data.target, e->target, pcmk__str_casei)
f312c6
+        && pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_casei)) {
f312c6
 
f312c6
-    if (pcmk__str_eq(async_fence_data.target, e->target, pcmk__str_casei) &&
f312c6
-        pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_casei)) {
f312c6
-
f312c6
-        async_fence_data.rc = e->result;
f312c6
+        pcmk__set_result(&async_fence_data.result,
f312c6
+                         stonith__event_exit_status(e),
f312c6
+                         stonith__event_execution_status(e),
f312c6
+                         stonith__event_exit_reason(e));
f312c6
         g_main_loop_quit(mainloop);
f312c6
     }
f312c6
 }
f312c6
@@ -91,8 +90,9 @@ notify_callback(stonith_t * st, stonith_event_t * e)
f312c6
 static void
f312c6
 fence_callback(stonith_t * stonith, stonith_callback_data_t * data)
f312c6
 {
f312c6
-    async_fence_data.rc = data->rc;
f312c6
-
f312c6
+    pcmk__set_result(&async_fence_data.result, stonith__exit_status(data),
f312c6
+                     stonith__execution_status(data),
f312c6
+                     stonith__exit_reason(data));
f312c6
     g_main_loop_quit(mainloop);
f312c6
 }
f312c6
 
f312c6
@@ -106,6 +106,8 @@ async_fence_helper(gpointer user_data)
f312c6
     if (rc != pcmk_ok) {
f312c6
         fprintf(stderr, "Could not connect to fencer: %s\n", pcmk_strerror(rc));
f312c6
         g_main_loop_quit(mainloop);
f312c6
+        pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
f312c6
+                         PCMK_EXEC_NOT_CONNECTED, NULL);
f312c6
         return TRUE;
f312c6
     }
f312c6
 
f312c6
@@ -121,6 +123,8 @@ async_fence_helper(gpointer user_data)
f312c6
 
f312c6
     if (call_id < 0) {
f312c6
         g_main_loop_quit(mainloop);
f312c6
+        pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
f312c6
+                         PCMK_EXEC_ERROR, pcmk_strerror(call_id));
f312c6
         return TRUE;
f312c6
     }
f312c6
 
f312c6
@@ -146,7 +150,8 @@ pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
     async_fence_data.timeout = timeout;
f312c6
     async_fence_data.tolerance = tolerance;
f312c6
     async_fence_data.delay = delay;
f312c6
-    async_fence_data.rc = pcmk_err_generic;
f312c6
+    pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR, PCMK_EXEC_UNKNOWN,
f312c6
+                     NULL);
f312c6
 
f312c6
     trig = mainloop_add_trigger(G_PRIORITY_HIGH, async_fence_helper, NULL);
f312c6
     mainloop_set_trigger(trig);
f312c6
@@ -156,7 +161,7 @@ pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
 
f312c6
     free(async_fence_data.name);
f312c6
 
f312c6
-    return pcmk_legacy2rc(async_fence_data.rc);
f312c6
+    return stonith__result2rc(&async_fence_data.result);
f312c6
 }
f312c6
 
f312c6
 #ifdef BUILD_PUBLIC_LIBPACEMAKER
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 008868fae5d1b0d6d8dc61f7acfb3856801ddd52 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 15:36:10 -0600
f312c6
Subject: [PATCH 02/11] Refactor: libpacemaker: add exit reason to high-level
f312c6
 fencing API
f312c6
f312c6
Nothing uses it as of this commit
f312c6
---
f312c6
 include/pacemaker.h         |  5 ++++-
f312c6
 include/pcmki/pcmki_fence.h |  5 ++++-
f312c6
 lib/pacemaker/pcmk_fence.c  | 10 +++++++---
f312c6
 tools/stonith_admin.c       |  6 +++---
f312c6
 4 files changed, 18 insertions(+), 8 deletions(-)
f312c6
f312c6
diff --git a/include/pacemaker.h b/include/pacemaker.h
f312c6
index a8523c969e..0daa4c5945 100644
f312c6
--- a/include/pacemaker.h
f312c6
+++ b/include/pacemaker.h
f312c6
@@ -189,12 +189,15 @@ int pcmk_list_nodes(xmlNodePtr *xml, char *node_types);
f312c6
  *                      again.
f312c6
  * \param[in] delay     Apply a fencing delay. Value -1 means disable also any
f312c6
  *                      static/random fencing delays from pcmk_delay_base/max.
f312c6
+ * \param[out] reason   If not NULL, where to put descriptive failure reason
f312c6
  *
f312c6
  * \return Standard Pacemaker return code
f312c6
+ * \note If \p reason is not NULL, the caller is responsible for freeing its
f312c6
+ *       returned value.
f312c6
  */
f312c6
 int pcmk_fence_action(stonith_t *st, const char *target, const char *action,
f312c6
                       const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                      int delay);
f312c6
+                      int delay, char **reason);
f312c6
 
f312c6
 /*!
f312c6
  * \brief List the fencing operations that have occurred for a specific node.
f312c6
diff --git a/include/pcmki/pcmki_fence.h b/include/pcmki/pcmki_fence.h
f312c6
index d4cef68f5c..c3da0361d7 100644
f312c6
--- a/include/pcmki/pcmki_fence.h
f312c6
+++ b/include/pcmki/pcmki_fence.h
f312c6
@@ -28,12 +28,15 @@
f312c6
  *                      again.
f312c6
  * \param[in] delay     Apply a fencing delay. Value -1 means disable also any
f312c6
  *                      static/random fencing delays from pcmk_delay_base/max
f312c6
+ * \param[out] reason   If not NULL, where to put descriptive failure reason
f312c6
  *
f312c6
  * \return Standard Pacemaker return code
f312c6
+ * \note If \p reason is not NULL, the caller is responsible for freeing its
f312c6
+ *       returned value.
f312c6
  */
f312c6
 int pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
                        const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                       int delay);
f312c6
+                       int delay, char **reason);
f312c6
 
f312c6
 /*!
f312c6
  * \brief List the fencing operations that have occurred for a specific node.
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index 125e1b268b..dbf084fb6b 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -139,7 +139,7 @@ async_fence_helper(gpointer user_data)
f312c6
 int
f312c6
 pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
                    const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                   int delay)
f312c6
+                   int delay, char **reason)
f312c6
 {
f312c6
     crm_trigger_t *trig;
f312c6
 
f312c6
@@ -161,6 +161,9 @@ pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
 
f312c6
     free(async_fence_data.name);
f312c6
 
f312c6
+    if ((reason != NULL) && (async_fence_data.result.exit_reason != NULL)) {
f312c6
+        *reason = strdup(async_fence_data.result.exit_reason);
f312c6
+    }
f312c6
     return stonith__result2rc(&async_fence_data.result);
f312c6
 }
f312c6
 
f312c6
@@ -168,9 +171,10 @@ pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
 int
f312c6
 pcmk_fence_action(stonith_t *st, const char *target, const char *action,
f312c6
                   const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                  int delay)
f312c6
+                  int delay, char **reason)
f312c6
 {
f312c6
-    return pcmk__fence_action(st, target, action, name, timeout, tolerance, delay);
f312c6
+    return pcmk__fence_action(st, target, action, name, timeout, tolerance,
f312c6
+                              delay, reason);
f312c6
 }
f312c6
 #endif
f312c6
 
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index 2d48326e1b..fdc7c46d49 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -571,17 +571,17 @@ main(int argc, char **argv)
f312c6
 
f312c6
         case 'B':
f312c6
             rc = pcmk__fence_action(st, target, "reboot", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay);
f312c6
+                                    options.tolerance*1000, options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'F':
f312c6
             rc = pcmk__fence_action(st, target, "off", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay);
f312c6
+                                    options.tolerance*1000, options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'U':
f312c6
             rc = pcmk__fence_action(st, target, "on", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay);
f312c6
+                                    options.tolerance*1000, options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'h':
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 7570510f9985ba75ef73fb824f28109e135ace0a Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 15:40:48 -0600
f312c6
Subject: [PATCH 03/11] Refactor: libpacemaker: rename high-level fencing API
f312c6
f312c6
Rename pcmk_fence_action() to pcmk_request_fencing(), and its internal
f312c6
equivalent pcmk__fence_action() to pcmk__request_fencing(). The change is
f312c6
backward-compatible because pcmk_fence_action() has not been exposed publicly
f312c6
yet.
f312c6
f312c6
"Fence action" can be easily confused with libcrmservice actions, liblrmd
f312c6
actions, libstonithd actions, scheduler actions, and so forth.
f312c6
f312c6
Also, the new name makes it clearer that the caller is requesting that the
f312c6
cluster perform fencing, and not directly performing fencing.
f312c6
---
f312c6
 include/pacemaker.h         | 20 ++++++++++----------
f312c6
 include/pcmki/pcmki_fence.h | 16 ++++++++--------
f312c6
 lib/pacemaker/pcmk_fence.c  | 16 ++++++++--------
f312c6
 tools/stonith_admin.c       | 18 ++++++++++++------
f312c6
 4 files changed, 38 insertions(+), 32 deletions(-)
f312c6
f312c6
diff --git a/include/pacemaker.h b/include/pacemaker.h
f312c6
index 0daa4c5945..e581f975a9 100644
f312c6
--- a/include/pacemaker.h
f312c6
+++ b/include/pacemaker.h
f312c6
@@ -177,27 +177,27 @@ int pcmk_list_nodes(xmlNodePtr *xml, char *node_types);
f312c6
 #ifdef BUILD_PUBLIC_LIBPACEMAKER
f312c6
 
f312c6
 /*!
f312c6
- * \brief Perform a STONITH action.
f312c6
+ * \brief Ask the cluster to perform fencing
f312c6
  *
f312c6
- * \param[in] st        A connection to the STONITH API.
f312c6
- * \param[in] target    The node receiving the action.
f312c6
- * \param[in] action    The action to perform.
f312c6
+ * \param[in] st        A connection to the fencer API
f312c6
+ * \param[in] target    The node that should be fenced
f312c6
+ * \param[in] action    The fencing action (on, off, reboot) to perform
f312c6
  * \param[in] name      Who requested the fence action?
f312c6
- * \param[in] timeout   How long to wait for the operation to complete (in ms).
f312c6
+ * \param[in] timeout   How long to wait for the operation to complete (in ms)
f312c6
  * \param[in] tolerance If a successful action for \p target happened within
f312c6
  *                      this many ms, return 0 without performing the action
f312c6
- *                      again.
f312c6
+ *                      again
f312c6
  * \param[in] delay     Apply a fencing delay. Value -1 means disable also any
f312c6
- *                      static/random fencing delays from pcmk_delay_base/max.
f312c6
+ *                      static/random fencing delays from pcmk_delay_base/max
f312c6
  * \param[out] reason   If not NULL, where to put descriptive failure reason
f312c6
  *
f312c6
  * \return Standard Pacemaker return code
f312c6
  * \note If \p reason is not NULL, the caller is responsible for freeing its
f312c6
  *       returned value.
f312c6
  */
f312c6
-int pcmk_fence_action(stonith_t *st, const char *target, const char *action,
f312c6
-                      const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                      int delay, char **reason);
f312c6
+int pcmk_request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
+                         const char *name, unsigned int timeout,
f312c6
+                         unsigned int tolerance, int delay, char **reason);
f312c6
 
f312c6
 /*!
f312c6
  * \brief List the fencing operations that have occurred for a specific node.
f312c6
diff --git a/include/pcmki/pcmki_fence.h b/include/pcmki/pcmki_fence.h
f312c6
index c3da0361d7..e3a7e27264 100644
f312c6
--- a/include/pcmki/pcmki_fence.h
f312c6
+++ b/include/pcmki/pcmki_fence.h
f312c6
@@ -13,14 +13,14 @@
f312c6
 #  include <crm/common/output_internal.h>
f312c6
 
f312c6
 /*!
f312c6
- * \brief Perform a STONITH action.
f312c6
+ * \brief Ask the cluster to perform fencing
f312c6
  *
f312c6
- * \note This is the internal version of pcmk_fence_action().  External users
f312c6
+ * \note This is the internal version of pcmk_request_fencing(). External users
f312c6
  *       of the pacemaker API should use that function instead.
f312c6
  *
f312c6
- * \param[in] st        A connection to the STONITH API.
f312c6
- * \param[in] target    The node receiving the action.
f312c6
- * \param[in] action    The action to perform.
f312c6
+ * \param[in] st        A connection to the fencer API
f312c6
+ * \param[in] target    The node that should be fenced
f312c6
+ * \param[in] action    The fencing action (on, off, reboot) to perform
f312c6
  * \param[in] name      Who requested the fence action?
f312c6
  * \param[in] timeout   How long to wait for the operation to complete (in ms).
f312c6
  * \param[in] tolerance If a successful action for \p target happened within
f312c6
@@ -34,9 +34,9 @@
f312c6
  * \note If \p reason is not NULL, the caller is responsible for freeing its
f312c6
  *       returned value.
f312c6
  */
f312c6
-int pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
-                       const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                       int delay, char **reason);
f312c6
+int pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
+                          const char *name, unsigned int timeout,
f312c6
+                          unsigned int tolerance, int delay, char **reason);
f312c6
 
f312c6
 /*!
f312c6
  * \brief List the fencing operations that have occurred for a specific node.
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index dbf084fb6b..1b7feb54b2 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -137,9 +137,9 @@ async_fence_helper(gpointer user_data)
f312c6
 }
f312c6
 
f312c6
 int
f312c6
-pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
-                   const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                   int delay, char **reason)
f312c6
+pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
+                      const char *name, unsigned int timeout,
f312c6
+                      unsigned int tolerance, int delay, char **reason)
f312c6
 {
f312c6
     crm_trigger_t *trig;
f312c6
 
f312c6
@@ -169,12 +169,12 @@ pcmk__fence_action(stonith_t *st, const char *target, const char *action,
f312c6
 
f312c6
 #ifdef BUILD_PUBLIC_LIBPACEMAKER
f312c6
 int
f312c6
-pcmk_fence_action(stonith_t *st, const char *target, const char *action,
f312c6
-                  const char *name, unsigned int timeout, unsigned int tolerance,
f312c6
-                  int delay, char **reason)
f312c6
+pcmk_request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
+                     const char *name, unsigned int timeout,
f312c6
+                     unsigned int tolerance, int delay, char **reason)
f312c6
 {
f312c6
-    return pcmk__fence_action(st, target, action, name, timeout, tolerance,
f312c6
-                              delay, reason);
f312c6
+    return pcmk__request_fencing(st, target, action, name, timeout, tolerance,
f312c6
+                                 delay, reason);
f312c6
 }
f312c6
 #endif
f312c6
 
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index fdc7c46d49..56948b3875 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -570,18 +570,24 @@ main(int argc, char **argv)
f312c6
             break;
f312c6
 
f312c6
         case 'B':
f312c6
-            rc = pcmk__fence_action(st, target, "reboot", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay, NULL);
f312c6
+            rc = pcmk__request_fencing(st, target, "reboot", name,
f312c6
+                                       options.timeout * 1000,
f312c6
+                                       options.tolerance * 1000,
f312c6
+                                       options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'F':
f312c6
-            rc = pcmk__fence_action(st, target, "off", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay, NULL);
f312c6
+            rc = pcmk__request_fencing(st, target, "off", name,
f312c6
+                                       options.timeout * 1000,
f312c6
+                                       options.tolerance * 1000,
f312c6
+                                       options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'U':
f312c6
-            rc = pcmk__fence_action(st, target, "on", name, options.timeout*1000,
f312c6
-                                    options.tolerance*1000, options.delay, NULL);
f312c6
+            rc = pcmk__request_fencing(st, target, "on", name,
f312c6
+                                       options.timeout * 1000,
f312c6
+                                       options.tolerance * 1000,
f312c6
+                                       options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'h':
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 247eb303df934944c0b72b162bb661cee6e0ed8b Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 15:52:37 -0600
f312c6
Subject: [PATCH 04/11] Refactor: tools: drop unnecessary string duplication in
f312c6
 stonith_admin
f312c6
f312c6
---
f312c6
 tools/stonith_admin.c | 11 ++++-------
f312c6
 1 file changed, 4 insertions(+), 7 deletions(-)
f312c6
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index 56948b3875..c11e302e76 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -360,8 +360,6 @@ main(int argc, char **argv)
f312c6
 
f312c6
     pcmk__cli_init_logging("stonith_admin", args->verbosity);
f312c6
 
f312c6
-    name = strdup(crm_system_name);
f312c6
-
f312c6
     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
f312c6
     if (rc != pcmk_rc_ok) {
f312c6
         exit_code = CRM_EX_ERROR;
f312c6
@@ -496,7 +494,7 @@ main(int argc, char **argv)
f312c6
     if (st == NULL) {
f312c6
         rc = -ENOMEM;
f312c6
     } else if (!no_connect) {
f312c6
-        rc = st->cmds->connect(st, name, NULL);
f312c6
+        rc = st->cmds->connect(st, crm_system_name, NULL);
f312c6
     }
f312c6
     if (rc < 0) {
f312c6
         out->err(out, "Could not connect to fencer: %s", pcmk_strerror(rc));
f312c6
@@ -570,21 +568,21 @@ main(int argc, char **argv)
f312c6
             break;
f312c6
 
f312c6
         case 'B':
f312c6
-            rc = pcmk__request_fencing(st, target, "reboot", name,
f312c6
+            rc = pcmk__request_fencing(st, target, "reboot", crm_system_name,
f312c6
                                        options.timeout * 1000,
f312c6
                                        options.tolerance * 1000,
f312c6
                                        options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'F':
f312c6
-            rc = pcmk__request_fencing(st, target, "off", name,
f312c6
+            rc = pcmk__request_fencing(st, target, "off", crm_system_name,
f312c6
                                        options.timeout * 1000,
f312c6
                                        options.tolerance * 1000,
f312c6
                                        options.delay, NULL);
f312c6
             break;
f312c6
 
f312c6
         case 'U':
f312c6
-            rc = pcmk__request_fencing(st, target, "on", name,
f312c6
+            rc = pcmk__request_fencing(st, target, "on", crm_system_name,
f312c6
                                        options.timeout * 1000,
f312c6
                                        options.tolerance * 1000,
f312c6
                                        options.delay, NULL);
f312c6
@@ -619,7 +617,6 @@ main(int argc, char **argv)
f312c6
         out->finish(out, exit_code, true, NULL);
f312c6
         pcmk__output_free(out);
f312c6
     }
f312c6
-    free(name);
f312c6
     stonith_key_value_freeall(options.params, 1, 1);
f312c6
 
f312c6
     if (st != NULL) {
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From a7888bf6868d8d9d9c77f65ae9983cf748bb0548 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 15:56:34 -0600
f312c6
Subject: [PATCH 05/11] Refactor: tools: functionize requesting fencing in
f312c6
 stonith_admin
f312c6
f312c6
... to reduce code duplication and improve readability
f312c6
---
f312c6
 tools/stonith_admin.c | 27 +++++++++++++++------------
f312c6
 1 file changed, 15 insertions(+), 12 deletions(-)
f312c6
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index c11e302e76..f738a9c888 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -331,6 +331,18 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
f312c6
     return context;
f312c6
 }
f312c6
 
f312c6
+// \return Standard Pacemaker return code
f312c6
+static int
f312c6
+request_fencing(stonith_t *st, const char *target, const char *command)
f312c6
+{
f312c6
+    int rc = pcmk__request_fencing(st, target, command, crm_system_name,
f312c6
+                                       options.timeout * 1000,
f312c6
+                                       options.tolerance * 1000,
f312c6
+                                       options.delay, NULL);
f312c6
+
f312c6
+    return rc;
f312c6
+}
f312c6
+
f312c6
 int
f312c6
 main(int argc, char **argv)
f312c6
 {
f312c6
@@ -568,24 +580,15 @@ main(int argc, char **argv)
f312c6
             break;
f312c6
 
f312c6
         case 'B':
f312c6
-            rc = pcmk__request_fencing(st, target, "reboot", crm_system_name,
f312c6
-                                       options.timeout * 1000,
f312c6
-                                       options.tolerance * 1000,
f312c6
-                                       options.delay, NULL);
f312c6
+            rc = request_fencing(st, target, "reboot");
f312c6
             break;
f312c6
 
f312c6
         case 'F':
f312c6
-            rc = pcmk__request_fencing(st, target, "off", crm_system_name,
f312c6
-                                       options.timeout * 1000,
f312c6
-                                       options.tolerance * 1000,
f312c6
-                                       options.delay, NULL);
f312c6
+            rc = request_fencing(st, target, "off");
f312c6
             break;
f312c6
 
f312c6
         case 'U':
f312c6
-            rc = pcmk__request_fencing(st, target, "on", crm_system_name,
f312c6
-                                       options.timeout * 1000,
f312c6
-                                       options.tolerance * 1000,
f312c6
-                                       options.delay, NULL);
f312c6
+            rc = request_fencing(st, target, "on");
f312c6
             break;
f312c6
 
f312c6
         case 'h':
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 2da32df780983ec1197e857eed5eeb5bf1101889 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 16:05:19 -0600
f312c6
Subject: [PATCH 06/11] Feature: tools: display failure reasons for
f312c6
 stonith_admin fencing commands
f312c6
f312c6
Previously, stonith_admin's --fence/--unfence/--reboot options did not output
f312c6
any error message on failure. Now, they do, including the exit reason, if
f312c6
available.
f312c6
---
f312c6
 tools/stonith_admin.c | 30 +++++++++++++++++++++++++-----
f312c6
 1 file changed, 25 insertions(+), 5 deletions(-)
f312c6
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index f738a9c888..5590faf11e 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -333,13 +333,33 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
f312c6
 
f312c6
 // \return Standard Pacemaker return code
f312c6
 static int
f312c6
-request_fencing(stonith_t *st, const char *target, const char *command)
f312c6
+request_fencing(stonith_t *st, const char *target, const char *command,
f312c6
+                GError **error)
f312c6
 {
f312c6
+    char *reason = NULL;
f312c6
     int rc = pcmk__request_fencing(st, target, command, crm_system_name,
f312c6
                                        options.timeout * 1000,
f312c6
                                        options.tolerance * 1000,
f312c6
-                                       options.delay, NULL);
f312c6
+                                       options.delay, &reason);
f312c6
 
f312c6
+    if (rc != pcmk_rc_ok) {
f312c6
+        const char *rc_str = pcmk_rc_str(rc);
f312c6
+
f312c6
+        // If reason is identical to return code string, don't display it twice
f312c6
+        if (pcmk__str_eq(rc_str, reason, pcmk__str_none)) {
f312c6
+            free(reason);
f312c6
+            reason = NULL;
f312c6
+        }
f312c6
+
f312c6
+        g_set_error(error, PCMK__RC_ERROR, rc,
f312c6
+                    "Couldn't %sfence %s: %s%s%s%s",
f312c6
+                    ((strcmp(command, "on") == 0)? "un" : ""),
f312c6
+                    target, pcmk_rc_str(rc),
f312c6
+                    ((reason == NULL)? "" : " ("),
f312c6
+                    ((reason == NULL)? "" : reason),
f312c6
+                    ((reason == NULL)? "" : ")"));
f312c6
+    }
f312c6
+    free(reason);
f312c6
     return rc;
f312c6
 }
f312c6
 
f312c6
@@ -580,15 +600,15 @@ main(int argc, char **argv)
f312c6
             break;
f312c6
 
f312c6
         case 'B':
f312c6
-            rc = request_fencing(st, target, "reboot");
f312c6
+            rc = request_fencing(st, target, "reboot", &error);
f312c6
             break;
f312c6
 
f312c6
         case 'F':
f312c6
-            rc = request_fencing(st, target, "off");
f312c6
+            rc = request_fencing(st, target, "off", &error);
f312c6
             break;
f312c6
 
f312c6
         case 'U':
f312c6
-            rc = request_fencing(st, target, "on");
f312c6
+            rc = request_fencing(st, target, "on", &error);
f312c6
             break;
f312c6
 
f312c6
         case 'h':
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 2d99eba4c326d3b13dbbe446971ea5febd5d05be Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Fri, 10 Dec 2021 16:08:49 -0600
f312c6
Subject: [PATCH 07/11] Feature: libpacemaker: return exit reason for fencer
f312c6
 connection failures
f312c6
f312c6
... instead of outputting to stderr directly, so that the caller (i.e.
f312c6
stonith_admin) can output the error in the correct output format.
f312c6
---
f312c6
 lib/pacemaker/pcmk_fence.c | 3 +--
f312c6
 1 file changed, 1 insertion(+), 2 deletions(-)
f312c6
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index 1b7feb54b2..d17b07cda2 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -104,10 +104,9 @@ async_fence_helper(gpointer user_data)
f312c6
     int rc = stonith_api_connect_retry(st, async_fence_data.name, 10);
f312c6
 
f312c6
     if (rc != pcmk_ok) {
f312c6
-        fprintf(stderr, "Could not connect to fencer: %s\n", pcmk_strerror(rc));
f312c6
         g_main_loop_quit(mainloop);
f312c6
         pcmk__set_result(&async_fence_data.result, CRM_EX_ERROR,
f312c6
-                         PCMK_EXEC_NOT_CONNECTED, NULL);
f312c6
+                         PCMK_EXEC_NOT_CONNECTED, pcmk_strerror(rc));
f312c6
         return TRUE;
f312c6
     }
f312c6
 
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 4480ef0602f47450bdddfbde360a6a8327710927 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Mon, 17 Jan 2022 09:39:39 -0600
f312c6
Subject: [PATCH 08/11] Low: libpacemaker: compare fence action names
f312c6
 case-sensitively
f312c6
f312c6
---
f312c6
 lib/pacemaker/pcmk_fence.c | 6 +++---
f312c6
 1 file changed, 3 insertions(+), 3 deletions(-)
f312c6
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index d17b07cda2..2a8f50a555 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -1,5 +1,5 @@
f312c6
 /*
f312c6
- * Copyright 2009-2021 the Pacemaker project contributors
f312c6
+ * Copyright 2009-2022 the Pacemaker project contributors
f312c6
  *
f312c6
  * The version control history for this file may have further details.
f312c6
  *
f312c6
@@ -77,7 +77,7 @@ static void
f312c6
 notify_callback(stonith_t * st, stonith_event_t * e)
f312c6
 {
f312c6
     if (pcmk__str_eq(async_fence_data.target, e->target, pcmk__str_casei)
f312c6
-        && pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_casei)) {
f312c6
+        && pcmk__str_eq(async_fence_data.action, e->action, pcmk__str_none)) {
f312c6
 
f312c6
         pcmk__set_result(&async_fence_data.result,
f312c6
                          stonith__event_exit_status(e),
f312c6
@@ -549,7 +549,7 @@ pcmk__reduce_fence_history(stonith_history_t *history)
f312c6
             if ((hp->state == st_done) || (hp->state == st_failed)) {
f312c6
                 /* action not in progress */
f312c6
                 if (pcmk__str_eq(hp->target, np->target, pcmk__str_casei) &&
f312c6
-                    pcmk__str_eq(hp->action, np->action, pcmk__str_casei) &&
f312c6
+                    pcmk__str_eq(hp->action, np->action, pcmk__str_none) &&
f312c6
                     (hp->state == np->state) &&
f312c6
                     ((hp->state == st_done) ||
f312c6
                      pcmk__str_eq(hp->delegate, np->delegate, pcmk__str_casei))) {
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From fe4c65a3b9e715c2b535709f989f2369d3637b78 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Mon, 17 Jan 2022 09:45:24 -0600
f312c6
Subject: [PATCH 09/11] Refactor: libpacemaker: avoid unnecessary string
f312c6
 duplication
f312c6
f312c6
... and don't leave any dynamic memory hanging around
f312c6
---
f312c6
 lib/pacemaker/pcmk_fence.c | 11 ++++++++---
f312c6
 1 file changed, 8 insertions(+), 3 deletions(-)
f312c6
f312c6
diff --git a/lib/pacemaker/pcmk_fence.c b/lib/pacemaker/pcmk_fence.c
f312c6
index 2a8f50a555..260fa5ab8e 100644
f312c6
--- a/lib/pacemaker/pcmk_fence.c
f312c6
+++ b/lib/pacemaker/pcmk_fence.c
f312c6
@@ -141,6 +141,7 @@ pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
                       unsigned int tolerance, int delay, char **reason)
f312c6
 {
f312c6
     crm_trigger_t *trig;
f312c6
+    int rc = pcmk_rc_ok;
f312c6
 
f312c6
     async_fence_data.st = st;
f312c6
     async_fence_data.name = strdup(name);
f312c6
@@ -160,10 +161,14 @@ pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
 
f312c6
     free(async_fence_data.name);
f312c6
 
f312c6
-    if ((reason != NULL) && (async_fence_data.result.exit_reason != NULL)) {
f312c6
-        *reason = strdup(async_fence_data.result.exit_reason);
f312c6
+    if (reason != NULL) {
f312c6
+        // Give the caller ownership of the exit reason
f312c6
+        *reason = async_fence_data.result.exit_reason;
f312c6
+        async_fence_data.result.exit_reason = NULL;
f312c6
     }
f312c6
-    return stonith__result2rc(&async_fence_data.result);
f312c6
+    rc = stonith__result2rc(&async_fence_data.result);
f312c6
+    pcmk__reset_result(&async_fence_data.result);
f312c6
+    return rc;
f312c6
 }
f312c6
 
f312c6
 #ifdef BUILD_PUBLIC_LIBPACEMAKER
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 7b7af07796f05a1adabdac655582be2e17106f81 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Mon, 17 Jan 2022 10:07:10 -0600
f312c6
Subject: [PATCH 10/11] Doc: libpacemaker: improve pcmk__request_fencing()
f312c6
 doxygen block
f312c6
f312c6
---
f312c6
 include/pacemaker.h         |  6 ++++--
f312c6
 include/pcmki/pcmki_fence.h | 15 +++++++++------
f312c6
 2 files changed, 13 insertions(+), 8 deletions(-)
f312c6
f312c6
diff --git a/include/pacemaker.h b/include/pacemaker.h
f312c6
index e581f975a9..266a844892 100644
f312c6
--- a/include/pacemaker.h
f312c6
+++ b/include/pacemaker.h
f312c6
@@ -187,8 +187,10 @@ int pcmk_list_nodes(xmlNodePtr *xml, char *node_types);
f312c6
  * \param[in] tolerance If a successful action for \p target happened within
f312c6
  *                      this many ms, return 0 without performing the action
f312c6
  *                      again
f312c6
- * \param[in] delay     Apply a fencing delay. Value -1 means disable also any
f312c6
- *                      static/random fencing delays from pcmk_delay_base/max
f312c6
+ * \param[in] delay     Apply this delay (in milliseconds) before initiating the
f312c6
+ *                      fencing action (a value of -1 applies no delay and also
f312c6
+ *                      disables any fencing delay from pcmk_delay_base and
f312c6
+ *                      pcmk_delay_max)
f312c6
  * \param[out] reason   If not NULL, where to put descriptive failure reason
f312c6
  *
f312c6
  * \return Standard Pacemaker return code
f312c6
diff --git a/include/pcmki/pcmki_fence.h b/include/pcmki/pcmki_fence.h
f312c6
index e3a7e27264..4a2fe3c481 100644
f312c6
--- a/include/pcmki/pcmki_fence.h
f312c6
+++ b/include/pcmki/pcmki_fence.h
f312c6
@@ -1,5 +1,5 @@
f312c6
 /*
f312c6
- * Copyright 2019-2021 the Pacemaker project contributors
f312c6
+ * Copyright 2019-2022 the Pacemaker project contributors
f312c6
  *
f312c6
  * The version control history for this file may have further details.
f312c6
  *
f312c6
@@ -22,17 +22,20 @@
f312c6
  * \param[in] target    The node that should be fenced
f312c6
  * \param[in] action    The fencing action (on, off, reboot) to perform
f312c6
  * \param[in] name      Who requested the fence action?
f312c6
- * \param[in] timeout   How long to wait for the operation to complete (in ms).
f312c6
+ * \param[in] timeout   How long to wait for the operation to complete (in ms)
f312c6
  * \param[in] tolerance If a successful action for \p target happened within
f312c6
- *                      this many ms, return 0 without performing the action
f312c6
- *                      again.
f312c6
- * \param[in] delay     Apply a fencing delay. Value -1 means disable also any
f312c6
- *                      static/random fencing delays from pcmk_delay_base/max
f312c6
+ *                      this many milliseconds, return success without
f312c6
+ *                      performing the action again
f312c6
+ * \param[in] delay     Apply this delay (in milliseconds) before initiating the
f312c6
+ *                      fencing action (a value of -1 applies no delay and also
f312c6
+ *                      disables any fencing delay from pcmk_delay_base and
f312c6
+ *                      pcmk_delay_max)
f312c6
  * \param[out] reason   If not NULL, where to put descriptive failure reason
f312c6
  *
f312c6
  * \return Standard Pacemaker return code
f312c6
  * \note If \p reason is not NULL, the caller is responsible for freeing its
f312c6
  *       returned value.
f312c6
+ * \todo delay is eventually used with g_timeout_add() and should be guint
f312c6
  */
f312c6
 int pcmk__request_fencing(stonith_t *st, const char *target, const char *action,
f312c6
                           const char *name, unsigned int timeout,
f312c6
-- 
f312c6
2.27.0
f312c6
f312c6
f312c6
From 61fb7271712e1246eb6d9472dc1afc7cd10e0a79 Mon Sep 17 00:00:00 2001
f312c6
From: Ken Gaillot <kgaillot@redhat.com>
f312c6
Date: Mon, 17 Jan 2022 10:18:02 -0600
f312c6
Subject: [PATCH 11/11] Fix: tools: get stonith_admin -T option working again
f312c6
f312c6
Regression introduced in 2.0.3 by 3910b6fec
f312c6
f312c6
This reverts commit 247eb303df934944c0b72b162bb661cee6e0ed8b
f312c6
("Refactor: tools: drop unnecessary string duplication in stonith_admin")
f312c6
and fixes a regression introduced when stonith_admin was converted to use
f312c6
GOption.
f312c6
f312c6
The -T option is intended to override the client name passed to the fencer API,
f312c6
but the client name was set to the default (crm_system_name) after option
f312c6
processing had already been done, so any value for -T was overwritten by the
f312c6
default, and its memory was leaked.
f312c6
f312c6
This commit sets the default only if -T was not used.
f312c6
---
f312c6
 tools/stonith_admin.c | 15 ++++++++++-----
f312c6
 1 file changed, 10 insertions(+), 5 deletions(-)
f312c6
f312c6
diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c
f312c6
index 5590faf11e..54774b6fee 100644
f312c6
--- a/tools/stonith_admin.c
f312c6
+++ b/tools/stonith_admin.c
f312c6
@@ -337,10 +337,10 @@ request_fencing(stonith_t *st, const char *target, const char *command,
f312c6
                 GError **error)
f312c6
 {
f312c6
     char *reason = NULL;
f312c6
-    int rc = pcmk__request_fencing(st, target, command, crm_system_name,
f312c6
-                                       options.timeout * 1000,
f312c6
-                                       options.tolerance * 1000,
f312c6
-                                       options.delay, &reason);
f312c6
+    int rc = pcmk__request_fencing(st, target, command, name,
f312c6
+                                   options.timeout * 1000,
f312c6
+                                   options.tolerance * 1000,
f312c6
+                                   options.delay, &reason);
f312c6
 
f312c6
     if (rc != pcmk_rc_ok) {
f312c6
         const char *rc_str = pcmk_rc_str(rc);
f312c6
@@ -392,6 +392,10 @@ main(int argc, char **argv)
f312c6
 
f312c6
     pcmk__cli_init_logging("stonith_admin", args->verbosity);
f312c6
 
f312c6
+    if (name == NULL) {
f312c6
+        name = strdup(crm_system_name);
f312c6
+    }
f312c6
+
f312c6
     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
f312c6
     if (rc != pcmk_rc_ok) {
f312c6
         exit_code = CRM_EX_ERROR;
f312c6
@@ -526,7 +530,7 @@ main(int argc, char **argv)
f312c6
     if (st == NULL) {
f312c6
         rc = -ENOMEM;
f312c6
     } else if (!no_connect) {
f312c6
-        rc = st->cmds->connect(st, crm_system_name, NULL);
f312c6
+        rc = st->cmds->connect(st, name, NULL);
f312c6
     }
f312c6
     if (rc < 0) {
f312c6
         out->err(out, "Could not connect to fencer: %s", pcmk_strerror(rc));
f312c6
@@ -640,6 +644,7 @@ main(int argc, char **argv)
f312c6
         out->finish(out, exit_code, true, NULL);
f312c6
         pcmk__output_free(out);
f312c6
     }
f312c6
+    free(name);
f312c6
     stonith_key_value_freeall(options.params, 1, 1);
f312c6
 
f312c6
     if (st != NULL) {
f312c6
-- 
f312c6
2.27.0
f312c6