From a0cbd527aacc35fd8e4312865597333680326296 Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Wed, 1 Apr 2020 13:12:29 +0200
Subject: [PATCH 12/15] Feature: fencer: any delays from pcmk_delay_base/max
 are added to requested fencing delay

Requested fencing delay doesn't take precedence over any configured
pcmk_delay_base/max.

A delay value -1 now means disable also any static/random fencing delays
from pcmk_delay_base/max. It's not used by any consumers for now.
---
 fencing/commands.c  | 54 +++++++++++++++----------------
 fencing/remote.c    | 13 +++-----
 fencing/internal.h |  4 +--
 include/crm/stonith-ng.h          |  5 +--
 lib/fencing/st_client.c           |  7 ++--
 5 files changed, 38 insertions(+), 45 deletions(-)

Index: pacemaker-1.1.18+20180430.b12c320f5/fencing/commands.c
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/fencing/commands.c
+++ pacemaker-1.1.18+20180430.b12c320f5/fencing/commands.c
@@ -242,8 +242,7 @@ create_async_command(xmlNode * msg)
     crm_element_value_int(msg, F_STONITH_CALLOPTS, &(cmd->options));
     crm_element_value_int(msg, F_STONITH_TIMEOUT, &(cmd->default_timeout));
     cmd->timeout = cmd->default_timeout;
-    // Default value -1 means no enforced fencing delay
-    cmd->start_delay = -1;
+    // Value -1 means disable any static/random fencing delays
     crm_element_value_int(msg, F_STONITH_DELAY, &(cmd->start_delay));
 
     cmd->origin = crm_element_value_copy(msg, F_ORIG);
@@ -450,7 +449,7 @@ schedule_stonith_command(async_command_t
 {
     int delay_max = 0;
     int delay_base = 0;
-    bool delay_enforced = (cmd->start_delay >= 0);
+    int requested_delay = cmd->start_delay;
 
     CRM_CHECK(cmd != NULL, return);
     CRM_CHECK(device != NULL, return);
@@ -483,35 +482,36 @@ schedule_stonith_command(async_command_t
     device->pending_ops = g_list_append(device->pending_ops, cmd);
     mainloop_set_trigger(device->work);
 
-    // No enforced fencing delay
-    if (delay_enforced == FALSE) {
-        delay_max = get_action_delay_max(device, cmd->action);
-        delay_base = get_action_delay_base(device, cmd->action);
-        if (delay_max == 0) {
-            delay_max = delay_base;
-        }
-        if (delay_max < delay_base) {
-            crm_warn("Base-delay (%ds) is larger than max-delay (%ds) "
-                     "for %s on %s - limiting to max-delay",
-                     delay_base, delay_max, cmd->action, device->id);
-            delay_base = delay_max;
-        }
-        if (delay_max > 0) {
-            // coverity[dont_call] We're not using rand() for security
-            cmd->start_delay =
-                ((delay_max != delay_base)?(rand() % (delay_max - delay_base)):0)
-                + delay_base;
-        }
+    // Value -1 means disable any static/random fencing delays
+    if (requested_delay < 0) {
+        return;
+    }
+
+    delay_max = get_action_delay_max(device, cmd->action);
+    delay_base = get_action_delay_base(device, cmd->action);
+    if (delay_max == 0) {
+        delay_max = delay_base;
+    }
+    if (delay_max < delay_base) {
+        crm_warn("Base-delay (%ds) is larger than max-delay (%ds) "
+                 "for %s on %s - limiting to max-delay",
+                 delay_base, delay_max, cmd->action, device->id);
+        delay_base = delay_max;
+    }
+    if (delay_max > 0) {
+        // coverity[dont_call] We're not using rand() for security
+        cmd->start_delay +=
+            ((delay_max != delay_base)?(rand() % (delay_max - delay_base)):0)
+            + delay_base;
     }
 
     if (cmd->start_delay > 0) {
-        crm_notice("Delaying '%s' action%s%s on %s for %s%ds (timeout=%ds, base=%ds, "
-                   "max=%ds)",
+        crm_notice("Delaying '%s' action%s%s on %s for %ds (timeout=%ds, "
+                   "requested_delay=%ds, base=%ds, max=%ds)",
                    cmd->action,
                    cmd->victim ? " targeting " : "", cmd->victim ? cmd->victim : "",
-                   device->id, delay_enforced ? "enforced " : "",
-                   cmd->start_delay, cmd->timeout,
-                   delay_base, delay_max);
+                   device->id, cmd->start_delay, cmd->timeout,
+                   requested_delay, delay_base, delay_max);
         cmd->delay_id =
             g_timeout_add_seconds(cmd->start_delay, start_delay_helper, cmd);
     }
Index: pacemaker-1.1.18+20180430.b12c320f5/fencing/remote.c
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/fencing/remote.c
+++ pacemaker-1.1.18+20180430.b12c320f5/fencing/remote.c
@@ -805,7 +805,7 @@ stonith_topology_next(remote_fencing_op_
                   op->client_name, op->originator, op->id);
         set_op_device_list(op, tp->levels[op->level]);
 
-        // The enforced delay has been applied for the first fencing level
+        // The requested delay has been applied for the first fencing level
         if (op->level > 1 && op->delay > 0) {
             op->delay = 0;
         }
@@ -966,9 +966,7 @@ create_remote_stonith_op(const char *cli
     op = calloc(1, sizeof(remote_fencing_op_t));
 
     crm_element_value_int(request, F_STONITH_TIMEOUT, &(op->base_timeout));
-
-    // Default value -1 means no enforced fencing delay
-    op->delay = -1;
+    // Value -1 means disable any static/random fencing delays
     crm_element_value_int(request, F_STONITH_DELAY, &(op->delay));
 
     if (peer && dev) {
@@ -1411,7 +1409,7 @@ advance_op_topology(remote_fencing_op_t
         crm_trace("Next for %s on behalf of %s@%s (rc was %d)",
                   op->target, op->originator, op->client_name, rc);
 
-        // The enforced delay has been applied for the first device
+        // The requested delay has been applied for the first device
         if (op->delay > 0) {
             op->delay = 0;
         }
@@ -1469,10 +1467,7 @@ call_remote_stonith(remote_fencing_op_t
         crm_xml_add(remote_op, F_STONITH_CLIENTNAME, op->client_name);
         crm_xml_add_int(remote_op, F_STONITH_TIMEOUT, timeout);
         crm_xml_add_int(remote_op, F_STONITH_CALLOPTS, op->call_options);
-
-        if (op->delay >= 0) {
-            crm_xml_add_int(remote_op, F_STONITH_DELAY, op->delay);
-        }
+        crm_xml_add_int(remote_op, F_STONITH_DELAY, op->delay);
 
         if (device) {
             timeout_one = TIMEOUT_MULTIPLY_FACTOR *
Index: pacemaker-1.1.18+20180430.b12c320f5/fencing/internal.h
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/fencing/internal.h
+++ pacemaker-1.1.18+20180430.b12c320f5/fencing/internal.h
@@ -105,8 +105,8 @@ typedef struct remote_fencing_op_s {
      * values associated with the devices this fencing operation may call */
     gint total_timeout;
 
-    /*! Enforced fencing delay.
-     * Default value -1 means no enforced fencing delay. */
+    /*! Requested fencing delay.
+     * Value -1 means disable any static/random fencing delays. */
     int delay;
 
     /*! Delegate is the node being asked to perform a fencing action
Index: pacemaker-1.1.18+20180430.b12c320f5/include/crm/stonith-ng.h
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/include/crm/stonith-ng.h
+++ pacemaker-1.1.18+20180430.b12c320f5/include/crm/stonith-ng.h
@@ -361,7 +361,7 @@ typedef struct stonith_api_operations_s
                                int level, stonith_key_value_t *device_list);
 
     /*!
-     * \brief Issue a fencing action against a node with enforced fencing delay.
+     * \brief Issue a fencing action against a node with requested fencing delay.
      *
      * \note Possible actions are, 'on', 'off', and 'reboot'.
      *
@@ -371,7 +371,8 @@ typedef struct stonith_api_operations_s
      * \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
+     * \param delay, Apply a fencing delay. Value -1 means disable also any
+     *               static/random fencing delays from pcmk_delay_base/max
      *
      * \retval 0 success
      * \retval negative error code on failure.
Index: pacemaker-1.1.18+20180430.b12c320f5/lib/fencing/st_client.c
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/lib/fencing/st_client.c
+++ pacemaker-1.1.18+20180430.b12c320f5/lib/fencing/st_client.c
@@ -1423,10 +1423,7 @@ stonith_api_fence_with_delay(stonith_t *
     crm_xml_add(data, F_STONITH_ACTION, action);
     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);
-    }
+    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);
@@ -1439,7 +1436,7 @@ stonith_api_fence(stonith_t * stonith, i
                   int timeout, int tolerance)
 {
     return stonith_api_fence_with_delay(stonith, call_options, node, action,
-                                        timeout, tolerance, -1);
+                                        timeout, tolerance, 0);
 }
 
 static int
