From 79de5db4ea3f9154391a168eb70d60f7fb535f8b Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Wed, 18 Mar 2020 15:44:24 +0100
Subject: [PATCH 6/9] Feature: stonith_admin: add --delay option to support
 enforced fencing delay

It can be specified with --fence, --reboot or --unfence commands.
The default value -1 disables enforced fencing delay.
---
 include/pcmki/pcmki_fence.h |  4 +++-
 lib/pacemaker/pcmk_fence.c  | 24 +++++++++++++++---------
 fencing/admin.c       | 14 ++++++++++----
 3 files changed, 28 insertions(+), 14 deletions(-)

Index: pacemaker-1.1.18+20180430.b12c320f5/fencing/admin.c
===================================================================
--- pacemaker-1.1.18+20180430.b12c320f5.orig/fencing/admin.c
+++ pacemaker-1.1.18+20180430.b12c320f5/fencing/admin.c
@@ -159,6 +159,10 @@ static struct crm_option long_options[]
         "Operation timeout in seconds (default 120;\n"
         "\t\t\tused with most commands)."
     },
+    {   "delay", required_argument, NULL, 'y',
+        "Enforced fencing delay in seconds (default -1 (disabled);\n"
+        "\t\t\twith --fence, --reboot, --unfence)."
+    },
     {   "as-node-id", no_argument, NULL, 'n',
         "(Advanced) The supplied node is the corosync node ID\n"
         "\t\t\t(with --last)."
@@ -183,6 +187,7 @@ struct {
     char *name;
     int timeout;
     int tolerance;
+    int delay;
     int rc;
 } async_fence_data;
 
@@ -247,11 +252,13 @@ async_fence_helper(gpointer user_data)
 
     st->cmds->register_notification(st, T_STONITH_NOTIFY_FENCE, notify_callback);
 
-    call_id = st->cmds->fence(st,
-                              st_opt_allow_suicide,
-                              async_fence_data.target,
-                              async_fence_data.action,
-                              async_fence_data.timeout, async_fence_data.tolerance);
+    call_id = st->cmds->fence_with_delay(st,
+                                         st_opt_allow_suicide,
+                                         async_fence_data.target,
+                                         async_fence_data.action,
+                                         async_fence_data.timeout,
+                                         async_fence_data.tolerance,
+                                         async_fence_data.delay);
 
     if (call_id < 0) {
         g_main_loop_quit(mainloop);
@@ -267,7 +274,8 @@ async_fence_helper(gpointer user_data)
 }
 
 static int
-mainloop_fencing(stonith_t * st, const char *target, const char *action, int timeout, int tolerance)
+mainloop_fencing(stonith_t * st, const char *target, const char *action,
+                 int timeout, int tolerance, int delay)
 {
     crm_trigger_t *trig;
 
@@ -276,6 +284,7 @@ mainloop_fencing(stonith_t * st, const c
     async_fence_data.action = action;
     async_fence_data.timeout = timeout;
     async_fence_data.tolerance = tolerance;
+    async_fence_data.delay = delay;
     async_fence_data.rc = -1;
 
     trig = mainloop_add_trigger(G_PRIORITY_HIGH, async_fence_helper, NULL);
@@ -407,6 +416,7 @@ main(int argc, char **argv)
     int verbose = 0;
     int argerr = 0;
     int timeout = 120;
+    int delay = -1;
     int option_index = 0;
     int fence_level = 0;
     int no_connect = 0;
@@ -481,6 +491,9 @@ main(int argc, char **argv)
             case 't':
                 timeout = crm_atoi(optarg, NULL);
                 break;
+            case 'y':
+                delay = crm_atoi(optarg, NULL);
+                break;
             case 'B':
             case 'F':
             case 'U':
@@ -657,13 +670,13 @@ main(int argc, char **argv)
             rc = st->cmds->confirm(st, st_opts, target);
             break;
         case 'B':
-            rc = mainloop_fencing(st, target, "reboot", timeout, tolerance);
+            rc = mainloop_fencing(st, target, "reboot", timeout, tolerance, delay);
             break;
         case 'F':
-            rc = mainloop_fencing(st, target, "off", timeout, tolerance);
+            rc = mainloop_fencing(st, target, "off", timeout, tolerance, delay);
             break;
         case 'U':
-            rc = mainloop_fencing(st, target, "on", timeout, tolerance);
+            rc = mainloop_fencing(st, target, "on", timeout, tolerance, delay);
             break;
         case 'h':
             {
