fd9fba
From 0d15568a538349ac41028db6b506d13dd23e8732 Mon Sep 17 00:00:00 2001
fd9fba
From: Chris Lumens <clumens@redhat.com>
fd9fba
Date: Tue, 14 Feb 2023 14:00:37 -0500
fd9fba
Subject: [PATCH] High: libcrmcommon: Fix handling node=NULL in
fd9fba
 pcmk__attrd_api_query.
fd9fba
fd9fba
According to the header file, if node is NULL, pcmk__attrd_api_query
fd9fba
should query the value of the given attribute on all cluster nodes.
fd9fba
This is also what the server expects and how attrd_updater is supposed
fd9fba
to work.
fd9fba
fd9fba
However, pcmk__attrd_api_query has no way of letting callers decide
fd9fba
whether they want to query all nodes or whether they want to use the
fd9fba
local node.  We were passing NULL for the node name, which it took to
fd9fba
mean it should look up the local node name.  This calls
fd9fba
pcmk__node_attr_target, which probes the local cluster name and returns
fd9fba
that to pcmk__attrd_api_query.  If it returns non-NULL, that value will
fd9fba
then be put into the XML IPC call which means the server will only
fd9fba
return the value for that node.
fd9fba
fd9fba
In testing this was usually fine.  However, in pratice, the methods
fd9fba
pcmk__node_attr_target uses to figure out the local cluster node name
fd9fba
involves checking the OCF_RESKEY_CRM_meta_on_node environment variable
fd9fba
among others.
fd9fba
fd9fba
This variable was never set in testing, but can be set in the real
fd9fba
world.  This leads to circumstances where the user did "attrd_updater -QA"
fd9fba
expecting to get the values on all nodes, but instead only got the value
fd9fba
on the local cluster node.
fd9fba
fd9fba
In pacemaker-2.1.4 and prior, pcmk__node_attr_target was simply never
fd9fba
called if the node was NULL but was called otherwise.
fd9fba
fd9fba
The fix is to modify pcmk__attrd_api_query to take an option for
fd9fba
querying all nodes.  If that's present, we'll query all nodes.  If it's
fd9fba
not present, we'll look at the given node name - NULL means look it up,
fd9fba
anything else means just that node.
fd9fba
fd9fba
Regression in 2.1.5 introduced by eb20a65577
fd9fba
---
fd9fba
 include/crm/common/attrd_internal.h     |  6 +++++-
fd9fba
 include/crm/common/ipc_attrd_internal.h |  7 +++++--
fd9fba
 lib/common/ipc_attrd.c                  | 12 ++++++++----
fd9fba
 tools/attrd_updater.c                   |  5 +++--
fd9fba
 4 files changed, 21 insertions(+), 9 deletions(-)
fd9fba
fd9fba
diff --git a/include/crm/common/attrd_internal.h b/include/crm/common/attrd_internal.h
fd9fba
index 389be48..7337c38 100644
fd9fba
--- a/include/crm/common/attrd_internal.h
fd9fba
+++ b/include/crm/common/attrd_internal.h
fd9fba
@@ -1,5 +1,5 @@
fd9fba
 /*
fd9fba
- * Copyright 2004-2022 the Pacemaker project contributors
fd9fba
+ * Copyright 2004-2023 the Pacemaker project contributors
fd9fba
  *
fd9fba
  * The version control history for this file may have further details.
fd9fba
  *
fd9fba
@@ -25,6 +25,10 @@ enum pcmk__node_attr_opts {
fd9fba
     pcmk__node_attr_perm           = (1 << 5),
fd9fba
     pcmk__node_attr_sync_local     = (1 << 6),
fd9fba
     pcmk__node_attr_sync_cluster   = (1 << 7),
fd9fba
+    // pcmk__node_attr_utilization is 8, but that has not been backported.
fd9fba
+    // I'm leaving the gap here in case we backport that in the future and
fd9fba
+    // also to avoid problems on mixed-version clusters.
fd9fba
+    pcmk__node_attr_query_all      = (1 << 9),
fd9fba
 };
fd9fba
 
fd9fba
 #define pcmk__set_node_attr_flags(node_attr_flags, flags_to_set) do {   \
fd9fba
diff --git a/include/crm/common/ipc_attrd_internal.h b/include/crm/common/ipc_attrd_internal.h
fd9fba
index 2c6713f..b1b7584 100644
fd9fba
--- a/include/crm/common/ipc_attrd_internal.h
fd9fba
+++ b/include/crm/common/ipc_attrd_internal.h
fd9fba
@@ -1,5 +1,5 @@
fd9fba
 /*
fd9fba
- * Copyright 2022 the Pacemaker project contributors
fd9fba
+ * Copyright 2022-2023 the Pacemaker project contributors
fd9fba
  *
fd9fba
  * The version control history for this file may have further details.
fd9fba
  *
fd9fba
@@ -110,10 +110,13 @@ int pcmk__attrd_api_purge(pcmk_ipc_api_t *api, const char *node);
fd9fba
  *
fd9fba
  * \param[in,out] api           Connection to pacemaker-attrd
fd9fba
  * \param[in]     node          Look up the attribute for this node
fd9fba
- *                              (or NULL for all nodes)
fd9fba
+ *                              (or NULL for the local node)
fd9fba
  * \param[in]     name          Attribute name
fd9fba
  * \param[in]     options       Bitmask of pcmk__node_attr_opts
fd9fba
  *
fd9fba
+ * \note Passing pcmk__node_attr_query_all will cause the function to query
fd9fba
+ *       the value of \p name on all nodes, regardless of the value of \p node.
fd9fba
+ *
fd9fba
  * \return Standard Pacemaker return code
fd9fba
  */
fd9fba
 int pcmk__attrd_api_query(pcmk_ipc_api_t *api, const char *node, const char *name,
fd9fba
diff --git a/lib/common/ipc_attrd.c b/lib/common/ipc_attrd.c
fd9fba
index 4606509..dece49b 100644
fd9fba
--- a/lib/common/ipc_attrd.c
fd9fba
+++ b/lib/common/ipc_attrd.c
fd9fba
@@ -1,5 +1,5 @@
fd9fba
 /*
fd9fba
- * Copyright 2011-2022 the Pacemaker project contributors
fd9fba
+ * Copyright 2011-2023 the Pacemaker project contributors
fd9fba
  *
fd9fba
  * The version control history for this file may have further details.
fd9fba
  *
fd9fba
@@ -332,10 +332,14 @@ pcmk__attrd_api_query(pcmk_ipc_api_t *api, const char *node, const char *name,
fd9fba
         return EINVAL;
fd9fba
     }
fd9fba
 
fd9fba
-    target = pcmk__node_attr_target(node);
fd9fba
+    if (pcmk_is_set(options, pcmk__node_attr_query_all)) {
fd9fba
+        node = NULL;
fd9fba
+    } else {
fd9fba
+        target = pcmk__node_attr_target(node);
fd9fba
 
fd9fba
-    if (target != NULL) {
fd9fba
-        node = target;
fd9fba
+        if (target != NULL) {
fd9fba
+            node = target;
fd9fba
+        }
fd9fba
     }
fd9fba
 
fd9fba
     request = create_attrd_op(NULL);
fd9fba
diff --git a/tools/attrd_updater.c b/tools/attrd_updater.c
fd9fba
index 3cd766d..cbd341d 100644
fd9fba
--- a/tools/attrd_updater.c
fd9fba
+++ b/tools/attrd_updater.c
fd9fba
@@ -376,6 +376,7 @@ attrd_event_cb(pcmk_ipc_api_t *attrd_api, enum pcmk_ipc_event event_type,
fd9fba
 static int
fd9fba
 send_attrd_query(pcmk__output_t *out, const char *attr_name, const char *attr_node, gboolean query_all)
fd9fba
 {
fd9fba
+    uint32_t options = pcmk__node_attr_none;
fd9fba
     pcmk_ipc_api_t *attrd_api = NULL;
fd9fba
     int rc = pcmk_rc_ok;
fd9fba
 
fd9fba
@@ -400,10 +401,10 @@ send_attrd_query(pcmk__output_t *out, const char *attr_name, const char *attr_no
fd9fba
 
fd9fba
     /* Decide which node(s) to query */
fd9fba
     if (query_all == TRUE) {
fd9fba
-        attr_node = NULL;
fd9fba
+        options |= pcmk__node_attr_query_all;
fd9fba
     }
fd9fba
 
fd9fba
-    rc = pcmk__attrd_api_query(attrd_api, attr_node, attr_name, 0);
fd9fba
+    rc = pcmk__attrd_api_query(attrd_api, attr_node, attr_name, options);
fd9fba
 
fd9fba
     if (rc != pcmk_rc_ok) {
fd9fba
         g_set_error(&error, PCMK__RC_ERROR, rc, "Could not query value of %s: %s (%d)",
fd9fba
-- 
fd9fba
2.31.1
fd9fba