Blame SOURCES/019-shutdown-lock.patch

ed4e54
From cf1e90ffe764f3639799206db9444ae32821386b Mon Sep 17 00:00:00 2001
ed4e54
From: Ken Gaillot <kgaillot@redhat.com>
ed4e54
Date: Fri, 10 Jan 2020 18:18:07 -0600
ed4e54
Subject: [PATCH 15/18] Low: scheduler: clear resource history when appropriate
ed4e54
ed4e54
Tell the controller to clear resource history from the CIB when a resource has
ed4e54
a shutdown lock that expired or was cancelled because the resource is already
ed4e54
active elsewhere.
ed4e54
---
ed4e54
 include/crm/pengine/internal.h      |  4 +++-
ed4e54
 include/crm/pengine/pe_types.h      |  4 +++-
ed4e54
 lib/pacemaker/pcmk_sched_allocate.c |  1 +
ed4e54
 lib/pacemaker/pcmk_sched_graph.c    | 16 ++++++++++++++--
ed4e54
 lib/pacemaker/pcmk_sched_native.c   |  6 ++++++
ed4e54
 lib/pengine/unpack.c                |  1 +
ed4e54
 lib/pengine/utils.c                 | 34 ++++++++++++++++++++++++++++++++--
ed4e54
 7 files changed, 60 insertions(+), 6 deletions(-)
ed4e54
ed4e54
diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
ed4e54
index 119624d..bc2c70e 100644
ed4e54
--- a/include/crm/pengine/internal.h
ed4e54
+++ b/include/crm/pengine/internal.h
ed4e54
@@ -1,5 +1,5 @@
ed4e54
 /*
ed4e54
- * Copyright 2004-2019 the Pacemaker project contributors
ed4e54
+ * Copyright 2004-2020 the Pacemaker project contributors
ed4e54
  *
ed4e54
  * The version control history for this file may have further details.
ed4e54
  *
ed4e54
@@ -435,5 +435,7 @@ void pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name,
ed4e54
                                 pe_working_set_t *data_set);
ed4e54
 
ed4e54
 bool pe__resource_is_disabled(pe_resource_t *rsc);
ed4e54
+pe_action_t *pe__clear_resource_history(pe_resource_t *rsc, pe_node_t *node,
ed4e54
+                                        pe_working_set_t *data_set);
ed4e54
 
ed4e54
 #endif
ed4e54
diff --git a/include/crm/pengine/pe_types.h b/include/crm/pengine/pe_types.h
ed4e54
index 123d8ef..572787b 100644
ed4e54
--- a/include/crm/pengine/pe_types.h
ed4e54
+++ b/include/crm/pengine/pe_types.h
ed4e54
@@ -1,5 +1,5 @@
ed4e54
 /*
ed4e54
- * Copyright 2004-2019 the Pacemaker project contributors
ed4e54
+ * Copyright 2004-2020 the Pacemaker project contributors
ed4e54
  *
ed4e54
  * The version control history for this file may have further details.
ed4e54
  *
ed4e54
@@ -287,6 +287,8 @@ enum pe_action_flags {
ed4e54
     pe_action_reschedule = 0x02000,
ed4e54
     pe_action_tracking = 0x04000,
ed4e54
     pe_action_dedup = 0x08000, //! Internal state tracking when creating graph
ed4e54
+
ed4e54
+    pe_action_dc = 0x10000,         //! Action may run on DC instead of target
ed4e54
 };
ed4e54
 /* *INDENT-ON* */
ed4e54
 
ed4e54
diff --git a/lib/pacemaker/pcmk_sched_allocate.c b/lib/pacemaker/pcmk_sched_allocate.c
ed4e54
index 884e1bd..195d055 100644
ed4e54
--- a/lib/pacemaker/pcmk_sched_allocate.c
ed4e54
+++ b/lib/pacemaker/pcmk_sched_allocate.c
ed4e54
@@ -1026,6 +1026,7 @@ apply_shutdown_lock(pe_resource_t *rsc, pe_working_set_t *data_set)
ed4e54
             pe_rsc_info(rsc,
ed4e54
                         "Cancelling shutdown lock because %s is already active",
ed4e54
                         rsc->id);
ed4e54
+            pe__clear_resource_history(rsc, rsc->lock_node, data_set);
ed4e54
             rsc->lock_node = NULL;
ed4e54
             rsc->lock_time = 0;
ed4e54
         }
ed4e54
diff --git a/lib/pacemaker/pcmk_sched_graph.c b/lib/pacemaker/pcmk_sched_graph.c
ed4e54
index 2861f3d..355ffca 100644
ed4e54
--- a/lib/pacemaker/pcmk_sched_graph.c
ed4e54
+++ b/lib/pacemaker/pcmk_sched_graph.c
ed4e54
@@ -586,10 +586,11 @@ update_action(pe_action_t *then, pe_working_set_t *data_set)
ed4e54
 
ed4e54
             /* 'then' is required, so we must abandon 'first'
ed4e54
              * (e.g. a required stop cancels any reload).
ed4e54
-             * Only used with reload actions as 'first'.
ed4e54
              */
ed4e54
             set_bit(other->action->flags, pe_action_optional);
ed4e54
-            clear_bit(first->rsc->flags, pe_rsc_reload);
ed4e54
+            if (!strcmp(first->task, CRMD_ACTION_RELOAD)) {
ed4e54
+                clear_bit(first->rsc->flags, pe_rsc_reload);
ed4e54
+            }
ed4e54
         }
ed4e54
 
ed4e54
         if (first->rsc && then->rsc && (first->rsc != then->rsc)
ed4e54
@@ -1039,6 +1040,11 @@ action2xml(action_t * action, gboolean as_input, pe_working_set_t *data_set)
ed4e54
     } else if (safe_str_eq(action->task, CRM_OP_LRM_REFRESH)) {
ed4e54
         action_xml = create_xml_node(NULL, XML_GRAPH_TAG_CRM_EVENT);
ed4e54
 
ed4e54
+    } else if (safe_str_eq(action->task, CRM_OP_LRM_DELETE)) {
ed4e54
+        // CIB-only clean-up for shutdown locks
ed4e54
+        action_xml = create_xml_node(NULL, XML_GRAPH_TAG_CRM_EVENT);
ed4e54
+        crm_xml_add(action_xml, PCMK__XA_MODE, XML_TAG_CIB);
ed4e54
+
ed4e54
 /* 	} else if(safe_str_eq(action->task, RSC_PROBED)) { */
ed4e54
 /* 		action_xml = create_xml_node(NULL, XML_GRAPH_TAG_CRM_EVENT); */
ed4e54
 
ed4e54
@@ -1051,6 +1057,7 @@ action2xml(action_t * action, gboolean as_input, pe_working_set_t *data_set)
ed4e54
 
ed4e54
     } else {
ed4e54
         action_xml = create_xml_node(NULL, XML_GRAPH_TAG_RSC_OP);
ed4e54
+
ed4e54
 #if ENABLE_VERSIONED_ATTRS
ed4e54
         rsc_details = pe_rsc_action_details(action);
ed4e54
 #endif
ed4e54
@@ -1392,6 +1399,11 @@ should_dump_action(pe_action_t *action)
ed4e54
         log_action(LOG_DEBUG, "Unallocated action", action, false);
ed4e54
         return false;
ed4e54
 
ed4e54
+    } else if (is_set(action->flags, pe_action_dc)) {
ed4e54
+        crm_trace("Action %s (%d) should be dumped: "
ed4e54
+                  "can run on DC instead of %s",
ed4e54
+                  action->uuid, action->id, action->node->details->uname);
ed4e54
+
ed4e54
     } else if (pe__is_guest_node(action->node)
ed4e54
                && !action->node->details->remote_requires_reset) {
ed4e54
         crm_trace("Action %s (%d) should be dumped: "
ed4e54
diff --git a/lib/pacemaker/pcmk_sched_native.c b/lib/pacemaker/pcmk_sched_native.c
ed4e54
index 9ebdd35..714a7a0 100644
ed4e54
--- a/lib/pacemaker/pcmk_sched_native.c
ed4e54
+++ b/lib/pacemaker/pcmk_sched_native.c
ed4e54
@@ -1403,6 +1403,12 @@ native_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
ed4e54
                             pe_order_runnable_left, data_set);
ed4e54
     }
ed4e54
 
ed4e54
+    // Don't clear resource history if probing on same node
ed4e54
+    custom_action_order(rsc, generate_op_key(rsc->id, CRM_OP_LRM_DELETE, 0),
ed4e54
+                        NULL, rsc, generate_op_key(rsc->id, RSC_STATUS, 0),
ed4e54
+                        NULL, pe_order_same_node|pe_order_then_cancels_first,
ed4e54
+                        data_set);
ed4e54
+
ed4e54
     // Certain checks need allowed nodes
ed4e54
     if (check_unfencing || check_utilization || rsc->container) {
ed4e54
         allowed_nodes = allowed_nodes_as_list(rsc, data_set);
ed4e54
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
ed4e54
index 5139e60..87edc83 100644
ed4e54
--- a/lib/pengine/unpack.c
ed4e54
+++ b/lib/pengine/unpack.c
ed4e54
@@ -2218,6 +2218,7 @@ unpack_shutdown_lock(xmlNode *rsc_entry, pe_resource_t *rsc, pe_node_t *node,
ed4e54
                 > (lock_time + data_set->shutdown_lock))) {
ed4e54
             pe_rsc_info(rsc, "Shutdown lock for %s on %s expired",
ed4e54
                         rsc->id, node->details->uname);
ed4e54
+            pe__clear_resource_history(rsc, node, data_set);
ed4e54
         } else {
ed4e54
             rsc->lock_node = node;
ed4e54
             rsc->lock_time = lock_time;
ed4e54
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
ed4e54
index 586d92c..b61455d 100644
ed4e54
--- a/lib/pengine/utils.c
ed4e54
+++ b/lib/pengine/utils.c
ed4e54
@@ -520,6 +520,11 @@ custom_action(resource_t * rsc, char *key, const char *task,
ed4e54
         }
ed4e54
         action->uuid = strdup(key);
ed4e54
 
ed4e54
+        if (safe_str_eq(task, CRM_OP_LRM_DELETE)) {
ed4e54
+            // Resource history deletion for a node can be done on the DC
ed4e54
+            pe_set_action_bit(action, pe_action_dc);
ed4e54
+        }
ed4e54
+
ed4e54
         pe_set_action_bit(action, pe_action_runnable);
ed4e54
         if (optional) {
ed4e54
             pe_set_action_bit(action, pe_action_optional);
ed4e54
@@ -588,7 +593,8 @@ custom_action(resource_t * rsc, char *key, const char *task,
ed4e54
             pe_set_action_bit(action, pe_action_optional);
ed4e54
 /*   			action->runnable = FALSE; */
ed4e54
 
ed4e54
-        } else if (action->node->details->online == FALSE
ed4e54
+        } else if (is_not_set(action->flags, pe_action_dc)
ed4e54
+                   && !(action->node->details->online)
ed4e54
                    && (!pe__is_guest_node(action->node)
ed4e54
                        || action->node->details->remote_requires_reset)) {
ed4e54
             pe_clear_action_bit(action, pe_action_runnable);
ed4e54
@@ -600,7 +606,8 @@ custom_action(resource_t * rsc, char *key, const char *task,
ed4e54
                 pe_fence_node(data_set, action->node, "resource actions are unrunnable");
ed4e54
             }
ed4e54
 
ed4e54
-        } else if (action->node->details->pending) {
ed4e54
+        } else if (is_not_set(action->flags, pe_action_dc)
ed4e54
+                   && action->node->details->pending) {
ed4e54
             pe_clear_action_bit(action, pe_action_runnable);
ed4e54
             do_crm_log(warn_level, "Action %s on %s is unrunnable (pending)",
ed4e54
                        action->uuid, action->node->details->uname);
ed4e54
@@ -714,6 +721,8 @@ unpack_operation_on_fail(action_t * action)
ed4e54
 
ed4e54
             value = on_fail;
ed4e54
         }
ed4e54
+    } else if (safe_str_eq(action->task, CRM_OP_LRM_DELETE)) {
ed4e54
+        value = "ignore";
ed4e54
     }
ed4e54
 
ed4e54
     return value;
ed4e54
@@ -2595,3 +2604,24 @@ pe__resource_is_disabled(pe_resource_t *rsc)
ed4e54
     }
ed4e54
     return false;
ed4e54
 }
ed4e54
+
ed4e54
+/*!
ed4e54
+ * \internal
ed4e54
+ * \brief Create an action to clear a resource's history from CIB
ed4e54
+ *
ed4e54
+ * \param[in] rsc   Resource to clear
ed4e54
+ * \param[in] node  Node to clear history on
ed4e54
+ *
ed4e54
+ * \return New action to clear resource history
ed4e54
+ */
ed4e54
+pe_action_t *
ed4e54
+pe__clear_resource_history(pe_resource_t *rsc, pe_node_t *node,
ed4e54
+                           pe_working_set_t *data_set)
ed4e54
+{
ed4e54
+    char *key = NULL;
ed4e54
+
ed4e54
+    CRM_ASSERT(rsc && node);
ed4e54
+    key = generate_op_key(rsc->id, CRM_OP_LRM_DELETE, 0);
ed4e54
+    return custom_action(rsc, key, CRM_OP_LRM_DELETE, node, FALSE, TRUE,
ed4e54
+                         data_set);
ed4e54
+}
ed4e54
-- 
ed4e54
1.8.3.1
ed4e54