From 47cfa3890dcdf56dac14e5505da55124bafa8757 Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Wed, 18 Mar 2020 15:33:23 +0100
Subject: [PATCH 04/15] Feature: libstonithd: introduce fence_with_delay()
 operation

A parameter value -1 disables enforced fencing delay.
Operation fence() is now a wrapper for fence_with_delay().
---
 include/crm/fencing/internal.h |  1 +
 include/crm/stonith-ng.h       | 19 +++++++++++++++++++
 lib/fencing/st_client.c        | 25 +++++++++++++++++++++++--
 3 files changed, 43 insertions(+), 2 deletions(-)

Index: pacemaker-1.1.16+20170320.77ea74d/include/crm/fencing/internal.h
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/include/crm/fencing/internal.h
+++ pacemaker-1.1.16+20170320.77ea74d/include/crm/fencing/internal.h
@@ -63,6 +63,7 @@ xmlNode *create_device_registration_xml(
 /*! Timeout period per a device execution */
 #  define F_STONITH_TIMEOUT       "st_timeout"
 #  define F_STONITH_TOLERANCE     "st_tolerance"
+#  define F_STONITH_DELAY         "st_delay"
 /*! Action specific timeout period returned in query of fencing devices. */
 #  define F_STONITH_ACTION_TIMEOUT       "st_action_timeout"
 /*! Host in query result is not allowed to run this action */
Index: pacemaker-1.1.16+20170320.77ea74d/include/crm/stonith-ng.h
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/include/crm/stonith-ng.h
+++ pacemaker-1.1.16+20170320.77ea74d/include/crm/stonith-ng.h
@@ -357,6 +357,25 @@ typedef struct stonith_api_operations_s
                                const char *attr, const char *value,
                                int level, stonith_key_value_t *device_list);
 
+    /*!
+     * \brief Issue a fencing action against a node with enforced fencing delay.
+     *
+     * \note Possible actions are, 'on', 'off', and 'reboot'.
+     *
+     * \param st, stonith connection
+     * \param options, call options
+     * \param node, The target node to fence
+     * \param action, The fencing action to take
+     * \param timeout, The default per device timeout to use with each device
+     *                 capable of fencing the target.
+     * \param delay, Any enforced fencing delay. -1 to disable
+     *
+     * \retval 0 success
+     * \retval negative error code on failure.
+     */
+    int (*fence_with_delay)(stonith_t *st, int options, const char *node, const char *action,
+                            int timeout, int tolerance, int delay);
+
 } stonith_api_operations_t;
 
 struct stonith_s
Index: pacemaker-1.1.16+20170320.77ea74d/lib/fencing/st_client.c
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/lib/fencing/st_client.c
+++ pacemaker-1.1.16+20170320.77ea74d/lib/fencing/st_client.c
@@ -1521,8 +1521,8 @@ stonith_api_status(stonith_t * stonith,
 }
 
 static int
-stonith_api_fence(stonith_t * stonith, int call_options, const char *node, const char *action,
-                  int timeout, int tolerance)
+stonith_api_fence_with_delay(stonith_t * stonith, int call_options, const char *node,
+                             const char *action, int timeout, int tolerance, int delay)
 {
     int rc = 0;
     xmlNode *data = NULL;
@@ -1533,6 +1533,10 @@ stonith_api_fence(stonith_t * stonith, i
     crm_xml_add_int(data, F_STONITH_TIMEOUT, timeout);
     crm_xml_add_int(data, F_STONITH_TOLERANCE, tolerance);
 
+    if (delay >= 0) {
+        crm_xml_add_int(data, F_STONITH_DELAY, delay);
+    }
+
     rc = stonith_send_command(stonith, STONITH_OP_FENCE, data, NULL, call_options, timeout);
     free_xml(data);
 
@@ -1540,6 +1544,14 @@ stonith_api_fence(stonith_t * stonith, i
 }
 
 static int
+stonith_api_fence(stonith_t * stonith, int call_options, const char *node, const char *action,
+                  int timeout, int tolerance)
+{
+    return stonith_api_fence_with_delay(stonith, call_options, node, action,
+                                        timeout, tolerance, -1);
+}
+
+static int
 stonith_api_confirm(stonith_t * stonith, int call_options, const char *target)
 {
     return stonith_api_fence(stonith, call_options | st_opt_manual_ack, target, "off", 0, 0);
@@ -2287,6 +2299,14 @@ stonith_send_command(stonith_t * stonith
     crm_xml_add_int(op_msg, F_STONITH_TIMEOUT, timeout);
     crm_trace("Sending %s message to STONITH service, Timeout: %ds", op, timeout);
 
+    if (data) {
+        const char *delay_s = crm_element_value(data, F_STONITH_DELAY);
+
+        if (delay_s) {
+            crm_xml_add(op_msg, F_STONITH_DELAY, delay_s);
+        }
+    }
+
     rc = crm_ipc_send(native->ipc, op_msg, ipc_flags, 1000 * (timeout + 60), &op_reply);
     free_xml(op_msg);
 
@@ -2488,6 +2508,7 @@ stonith_api_new(void)
     new_stonith->cmds->monitor    = stonith_api_monitor;
     new_stonith->cmds->status     = stonith_api_status;
     new_stonith->cmds->fence      = stonith_api_fence;
+    new_stonith->cmds->fence_with_delay = stonith_api_fence_with_delay;
     new_stonith->cmds->confirm    = stonith_api_confirm;
     new_stonith->cmds->history    = stonith_api_history;
 
