Blob Blame History Raw
From c3e2a63e08046b25f1773504d8c1ab431d3abf78 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Thu, 21 Nov 2019 14:48:02 -0600
Subject: [PATCH 01/10] Feature: scheduler: add shutdown lock cluster options

This commit adds shutdown-lock and shutdown-lock-limit options (just the
options, not the feature itself).

shutdown-lock defaults to false, which preserves current behavior. The intended
purpose of setting it to true is to *prevent* recovery of a node's resources
elsewhere when the node is cleanly shut down, until the node rejoins. If
shutdown-lock-limit is set to a nonzero time duration, the cluster will
be allowed to recover the resources if the node has not rejoined within this
time.

The use case is when rebooting a node (such as for software updates) is done by
cluster-unaware system administrators during scheduled maintenance windows,
resources prefer specific nodes, and resource recovery time is high.
---
 include/crm/msg_xml.h        |  6 +++++-
 include/crm/pengine/status.h |  2 ++
 lib/pengine/common.c         | 26 ++++++++++++++++++++++++--
 lib/pengine/unpack.c         | 10 ++++++++++
 4 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h
index de99959..50fdf45 100644
--- a/include/crm/msg_xml.h
+++ b/include/crm/msg_xml.h
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2020 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -378,6 +380,8 @@
 #  define XML_CONFIG_ATTR_FORCE_QUIT	"shutdown-escalation"
 #  define XML_CONFIG_ATTR_RECHECK	"cluster-recheck-interval"
 #  define XML_CONFIG_ATTR_FENCE_REACTION	"fence-reaction"
+#  define XML_CONFIG_ATTR_SHUTDOWN_LOCK         "shutdown-lock"
+#  define XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT   "shutdown-lock-limit"
 
 #  define XML_ALERT_ATTR_PATH		"path"
 #  define XML_ALERT_ATTR_TIMEOUT	"timeout"
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
index 415f60e..c6d4bdb 100644
--- a/include/crm/pengine/status.h
+++ b/include/crm/pengine/status.h
@@ -83,6 +83,7 @@ enum pe_find {
 #  define pe_flag_start_failure_fatal   0x00001000ULL
 #  define pe_flag_remove_after_stop     0x00002000ULL
 #  define pe_flag_startup_fencing       0x00004000ULL
+#  define pe_flag_shutdown_lock         0x00008000ULL
 
 #  define pe_flag_startup_probes        0x00010000ULL
 #  define pe_flag_have_status           0x00020000ULL
@@ -148,6 +149,7 @@ typedef struct pe_working_set_s {
 
     GList *param_check; // History entries that need to be checked
     GList *stop_needed; // Containers that need stop actions
+    guint shutdown_lock;// How long (seconds) to lock resources to shutdown node
 } pe_working_set_t;
 
 enum pe_check_parameters {
diff --git a/lib/pengine/common.c b/lib/pengine/common.c
index e82434a..fc976d3 100644
--- a/lib/pengine/common.c
+++ b/lib/pengine/common.c
@@ -1,5 +1,7 @@
-/* 
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+/*
+ * Copyright 2004-2020 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -101,6 +103,26 @@ pe_cluster_option pe_opts[] = {
 	  "When set to TRUE, the cluster will immediately ban a resource from a node if it fails to start there. When FALSE, the cluster will instead check the resource's fail count against its migration-threshold." },
 	{ "enable-startup-probes", NULL, "boolean", NULL, "true", &check_boolean,
 	  "Should the cluster check for active resources during startup", NULL },
+    {
+        XML_CONFIG_ATTR_SHUTDOWN_LOCK,
+        NULL, "boolean", NULL, "false", &check_boolean,
+        "Whether to lock resources to a cleanly shut down node",
+        "When true, resources active on a node when it is cleanly shut down "
+            "are kept \"locked\" to that node (not allowed to run elsewhere) "
+            "until they start again on that node after it rejoins (or for at "
+            "most shutdown-lock-limit, if set). Stonith resources and "
+            "Pacemaker Remote connections are never locked. Clone and bundle "
+            "instances and the master role of promotable clones are currently "
+            "never locked, though support could be added in a future release."
+    },
+    {
+        XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT,
+        NULL, "time", NULL, "0", &check_timer,
+        "Do not lock resources to a cleanly shut down node longer than this",
+        "If shutdown-lock is true and this is set to a nonzero time duration, "
+            "shutdown locks will expire after this much time has passed since "
+            "the shutdown was initiated, even if the node has not rejoined."
+    },
 
 	/* Stonith Options */
 	{ "stonith-enabled", "stonith_enabled", "boolean", NULL, "true", &check_boolean,
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
index 24e56f5..7b0d837 100644
--- a/lib/pengine/unpack.c
+++ b/lib/pengine/unpack.c
@@ -340,6 +340,16 @@ unpack_config(xmlNode * config, pe_working_set_t * data_set)
     data_set->placement_strategy = pe_pref(data_set->config_hash, "placement-strategy");
     crm_trace("Placement strategy: %s", data_set->placement_strategy);
 
+    set_config_flag(data_set, "shutdown-lock", pe_flag_shutdown_lock);
+    crm_trace("Resources will%s be locked to cleanly shut down nodes",
+              (is_set(data_set->flags, pe_flag_shutdown_lock)? "" : " not"));
+    if (is_set(data_set->flags, pe_flag_shutdown_lock)) {
+        value = pe_pref(data_set->config_hash,
+                        XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT);
+        data_set->shutdown_lock = crm_get_interval(value) / 1000;
+        crm_trace("Shutdown locks expire after %us", data_set->shutdown_lock);
+    }
+
     return TRUE;
 }
 
-- 
1.8.3.1