b04960
From ba17007f04d2fdbd2147c14c7eedb0de137ff448 Mon Sep 17 00:00:00 2001
b04960
From: Ken Gaillot <kgaillot@redhat.com>
b04960
Date: Fri, 13 Dec 2019 11:38:49 -0600
b04960
Subject: [PATCH 05/10] Low: controller: don't clear shutdown locks when node
b04960
 rejoins
b04960
b04960
Add new controld_delete_node_state() values for clearing resource history
b04960
while preserving shutdown locks. This is accomplished by deleting all
b04960
unlocked lrm_resource entries and all lrm_rsc_op entries, instead of the entire
b04960
lrm subsection.
b04960
---
b04960
 crmd/cib.c            | 22 +++++++++++++++++++++-
b04960
 crmd/crmd_utils.h     |  2 ++
b04960
 crmd/join_dc.c        |  7 +++++--
b04960
 crmd/remote_lrmd_ra.c | 18 +++++++++++-------
b04960
 4 files changed, 39 insertions(+), 10 deletions(-)
b04960
b04960
diff --git a/crmd/cib.c b/crmd/cib.c
b04960
index e8c6376..a9e4ed3 100644
b04960
--- a/crmd/cib.c
b04960
+++ b/crmd/cib.c
b04960
@@ -247,12 +247,21 @@ cib_delete_callback(xmlNode *msg, int call_id, int rc, xmlNode *output,
b04960
 // Node's lrm section (name 1x)
b04960
 #define XPATH_NODE_LRM          XPATH_NODE_STATE "/" XML_CIB_TAG_LRM
b04960
 
b04960
+// Node's lrm_rsc_op entries and lrm_resource entries without lock (name 2x)
b04960
+#define XPATH_NODE_LRM_UNLOCKED XPATH_NODE_STATE "//" XML_LRM_TAG_RSC_OP    \
b04960
+                                "|" XPATH_NODE_STATE                        \
b04960
+                                "//" XML_LRM_TAG_RESOURCE                   \
b04960
+                                "[not(@" XML_CONFIG_ATTR_SHUTDOWN_LOCK ")]"
b04960
+
b04960
 // Node's transient_attributes section (name 1x)
b04960
 #define XPATH_NODE_ATTRS        XPATH_NODE_STATE "/" XML_TAG_TRANSIENT_NODEATTRS
b04960
 
b04960
 // Everything under node_state (name 1x)
b04960
 #define XPATH_NODE_ALL          XPATH_NODE_STATE "/*"
b04960
 
b04960
+// Unlocked history + transient attributes (name 3x)
b04960
+#define XPATH_NODE_ALL_UNLOCKED XPATH_NODE_LRM_UNLOCKED "|" XPATH_NODE_ATTRS
b04960
+
b04960
 /*!
b04960
  * \internal
b04960
  * \brief Delete subsection of a node's CIB node_state
b04960
@@ -274,6 +283,11 @@ controld_delete_node_state(const char *uname, enum controld_section_e section,
b04960
             xpath = crm_strdup_printf(XPATH_NODE_LRM, uname);
b04960
             desc = crm_strdup_printf("resource history for node %s", uname);
b04960
             break;
b04960
+        case controld_section_lrm_unlocked:
b04960
+            xpath = crm_strdup_printf(XPATH_NODE_LRM_UNLOCKED, uname, uname);
b04960
+            desc = crm_strdup_printf("resource history (other than shutdown "
b04960
+                                     "locks) for node %s", uname);
b04960
+            break;
b04960
         case controld_section_attrs:
b04960
             xpath = crm_strdup_printf(XPATH_NODE_ATTRS, uname);
b04960
             desc = crm_strdup_printf("transient attributes for node %s", uname);
b04960
@@ -282,6 +296,12 @@ controld_delete_node_state(const char *uname, enum controld_section_e section,
b04960
             xpath = crm_strdup_printf(XPATH_NODE_ALL, uname);
b04960
             desc = crm_strdup_printf("all state for node %s", uname);
b04960
             break;
b04960
+        case controld_section_all_unlocked:
b04960
+            xpath = crm_strdup_printf(XPATH_NODE_ALL_UNLOCKED,
b04960
+                                      uname, uname, uname);
b04960
+            desc = crm_strdup_printf("all state (other than shutdown locks) "
b04960
+                                     "for node %s", uname);
b04960
+            break;
b04960
     }
b04960
 
b04960
     if (fsa_cib_conn == NULL) {
b04960
@@ -290,7 +310,7 @@ controld_delete_node_state(const char *uname, enum controld_section_e section,
b04960
     } else {
b04960
         int call_id;
b04960
 
b04960
-        options |= cib_quorum_override|cib_xpath;
b04960
+        options |= cib_quorum_override|cib_xpath|cib_multiple;
b04960
         call_id = fsa_cib_conn->cmds->delete(fsa_cib_conn, xpath, NULL, options);
b04960
         crm_info("Deleting %s (via CIB call %d) " CRM_XS " xpath=%s",
b04960
                  desc, call_id, xpath);
b04960
diff --git a/crmd/crmd_utils.h b/crmd/crmd_utils.h
b04960
index 9ecce88..77dcfc2 100644
b04960
--- a/crmd/crmd_utils.h
b04960
+++ b/crmd/crmd_utils.h
b04960
@@ -120,8 +120,10 @@ bool controld_action_is_recordable(const char *action);
b04960
 // Subsections of node_state
b04960
 enum controld_section_e {
b04960
     controld_section_lrm,
b04960
+    controld_section_lrm_unlocked,
b04960
     controld_section_attrs,
b04960
     controld_section_all,
b04960
+    controld_section_all_unlocked
b04960
 };
b04960
 
b04960
 void controld_delete_node_state(const char *uname,
b04960
diff --git a/crmd/join_dc.c b/crmd/join_dc.c
b04960
index 8284695..1553078 100644
b04960
--- a/crmd/join_dc.c
b04960
+++ b/crmd/join_dc.c
b04960
@@ -534,6 +534,7 @@ do_dc_join_ack(long long action,
b04960
     int join_id = -1;
b04960
     int call_id = 0;
b04960
     ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);
b04960
+    enum controld_section_e section = controld_section_lrm;
b04960
 
b04960
     const char *op = crm_element_value(join_ack->msg, F_CRM_TASK);
b04960
     const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
b04960
@@ -583,8 +584,10 @@ do_dc_join_ack(long long action,
b04960
     /* Update CIB with node's current LRM state. A new transition will be
b04960
      * triggered later, when the CIB notifies us of the change.
b04960
      */
b04960
-    controld_delete_node_state(join_from, controld_section_lrm,
b04960
-                               cib_scope_local);
b04960
+    if (controld_shutdown_lock_enabled) {
b04960
+        section = controld_section_lrm_unlocked;
b04960
+    }
b04960
+    controld_delete_node_state(join_from, section, cib_scope_local);
b04960
     if (safe_str_eq(join_from, fsa_our_uname)) {
b04960
         xmlNode *now_dc_lrmd_state = controld_query_executor_state(fsa_our_uname);
b04960
 
b04960
diff --git a/crmd/remote_lrmd_ra.c b/crmd/remote_lrmd_ra.c
b04960
index c4f58d6..3870431 100644
b04960
--- a/crmd/remote_lrmd_ra.c
b04960
+++ b/crmd/remote_lrmd_ra.c
b04960
@@ -1,5 +1,5 @@
b04960
-/* 
b04960
- * Copyright 2013-2019 the Pacemaker project contributors
b04960
+/*
b04960
+ * Copyright 2013-2020 the Pacemaker project contributors
b04960
  *
b04960
  * The version control history for this file may have further details.
b04960
  * 
b04960
@@ -191,17 +191,21 @@ remote_node_up(const char *node_name)
b04960
     int call_opt, call_id = 0;
b04960
     xmlNode *update, *state;
b04960
     crm_node_t *node;
b04960
+    enum controld_section_e section = controld_section_all;
b04960
 
b04960
     CRM_CHECK(node_name != NULL, return);
b04960
     crm_info("Announcing pacemaker_remote node %s", node_name);
b04960
 
b04960
-    /* Clear node's entire state (resource history and transient attributes).
b04960
-     * The transient attributes should and normally will be cleared when the
b04960
-     * node leaves, but since remote node state has a number of corner cases,
b04960
-     * clear them here as well, to be sure.
b04960
+    /* Clear node's entire state (resource history and transient attributes)
b04960
+     * other than shutdown locks. The transient attributes should and normally
b04960
+     * will be cleared when the node leaves, but since remote node state has a
b04960
+     * number of corner cases, clear them here as well, to be sure.
b04960
      */
b04960
     call_opt = crmd_cib_smart_opt();
b04960
-    controld_delete_node_state(node_name, controld_section_all, call_opt);
b04960
+    if (controld_shutdown_lock_enabled) {
b04960
+        section = controld_section_all_unlocked;
b04960
+    }
b04960
+    controld_delete_node_state(node_name, section, call_opt);
b04960
 
b04960
     /* Clear node's probed attribute */
b04960
     update_attrd(node_name, CRM_OP_PROBED, NULL, NULL, TRUE);
b04960
-- 
b04960
1.8.3.1
b04960