From c3e2a63e08046b25f1773504d8c1ab431d3abf78 Mon Sep 17 00:00:00 2001 From: Ken Gaillot 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 + * 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_RECHECK "cluster-recheck-interval" # define XML_CONFIG_ATTR_FENCE_REACTION "fence-reaction" # define XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY "priority-fencing-delay" +# 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 @@ -147,6 +148,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 int ninstances; // Total number of resource instances int priority_fencing_delay; // Priority fencing delay } pe_working_set_t; 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 +/* + * 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