From ee01715f3ae7ff64da6f8aad0d3537faa84b013b Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 28 Oct 2024 11:24:08 -0500
Subject: [PATCH 05/16] Refactor: libcrmcluster: allow searching by XML ID in
 pcmk__search_node_caches()

---
 daemons/attrd/attrd_ipc.c            |  2 +-
 daemons/based/based_messages.c       |  2 +-
 daemons/controld/controld_corosync.c |  2 +-
 daemons/controld/controld_fencing.c  |  2 +-
 daemons/controld/controld_messages.c |  8 ++++---
 daemons/fenced/fenced_commands.c     |  2 +-
 daemons/fenced/fenced_history.c      |  2 +-
 daemons/fenced/fenced_remote.c       |  2 +-
 include/crm/cluster/internal.h       |  1 +
 lib/cluster/cpg.c                    |  2 +-
 lib/cluster/membership.c             | 35 ++++++++++++++++++----------
 11 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/daemons/attrd/attrd_ipc.c b/daemons/attrd/attrd_ipc.c
index 4b26cdb3d7..5ab2763dbf 100644
--- a/daemons/attrd/attrd_ipc.c
+++ b/daemons/attrd/attrd_ipc.c
@@ -155,7 +155,7 @@ attrd_client_peer_remove(pcmk__request_t *request)
             pcmk__node_status_t *node = NULL;
             char *host_alloc = NULL;
 
-            node = pcmk__search_node_caches(nodeid, NULL,
+            node = pcmk__search_node_caches(nodeid, NULL, NULL,
                                             pcmk__node_search_cluster_member);
             if ((node != NULL) && (node->name != NULL)) {
                 // Use cached name if available
diff --git a/daemons/based/based_messages.c b/daemons/based/based_messages.c
index 25d31f49ac..e8a85904f7 100644
--- a/daemons/based/based_messages.c
+++ b/daemons/based/based_messages.c
@@ -254,7 +254,7 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
             // Notify originating peer so it can notify its local clients
             pcmk__node_status_t *origin = NULL;
 
-            origin = pcmk__search_node_caches(0, host,
+            origin = pcmk__search_node_caches(0, host, NULL,
                                               pcmk__node_search_cluster_member);
 
             crm_info("Rejecting upgrade request from %s: %s "
diff --git a/daemons/controld/controld_corosync.c b/daemons/controld/controld_corosync.c
index 02b0e823ad..61cf6293cc 100644
--- a/daemons/controld/controld_corosync.c
+++ b/daemons/controld/controld_corosync.c
@@ -119,7 +119,7 @@ cpg_membership_callback(cpg_handle_t handle, const struct cpg_name *cpg_name,
     if (controld_globals.dc_name != NULL) {
         pcmk__node_status_t *peer = NULL;
 
-        peer = pcmk__search_node_caches(0, controld_globals.dc_name,
+        peer = pcmk__search_node_caches(0, controld_globals.dc_name, NULL,
                                         pcmk__node_search_cluster_member);
         if (peer != NULL) {
             for (int i = 0; i < left_list_entries; ++i) {
diff --git a/daemons/controld/controld_fencing.c b/daemons/controld/controld_fencing.c
index e24523cbb0..093f48eb45 100644
--- a/daemons/controld/controld_fencing.c
+++ b/daemons/controld/controld_fencing.c
@@ -591,7 +591,7 @@ handle_fence_notification(stonith_t *st, stonith_event_t *event)
                                |pcmk__node_search_cluster_cib;
 
         pcmk__node_status_t *peer = pcmk__search_node_caches(0, event->target,
-                                                             flags);
+                                                             NULL, flags);
         const char *uuid = NULL;
 
         if (peer == NULL) {
diff --git a/daemons/controld/controld_messages.c b/daemons/controld/controld_messages.c
index 1f4b3891ce..65b1b829ce 100644
--- a/daemons/controld/controld_messages.c
+++ b/daemons/controld/controld_messages.c
@@ -501,7 +501,7 @@ relay_message(xmlNode * msg, gboolean originated_locally)
     }
 
     if (!broadcast) {
-        node_to = pcmk__search_node_caches(0, host_to,
+        node_to = pcmk__search_node_caches(0, host_to, NULL,
                                            pcmk__node_search_cluster_member);
         if (node_to == NULL) {
             crm_warn("Ignoring message %s because node %s is unknown",
@@ -943,7 +943,8 @@ handle_node_info_request(const xmlNode *msg)
         value = controld_globals.cluster->priv->node_name;
     }
 
-    node = pcmk__search_node_caches(node_id, value, pcmk__node_search_any);
+    node = pcmk__search_node_caches(node_id, value, NULL,
+                                    pcmk__node_search_any);
     if (node) {
         crm_xml_add(reply_data, PCMK_XA_ID, node->xml_id);
         crm_xml_add(reply_data, PCMK_XA_UNAME, node->name);
@@ -1070,7 +1071,8 @@ handle_request(xmlNode *stored_msg, enum crmd_fsa_cause cause)
     if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) {
         const char *from = crm_element_value(stored_msg, PCMK__XA_SRC);
         pcmk__node_status_t *node =
-            pcmk__search_node_caches(0, from, pcmk__node_search_cluster_member);
+            pcmk__search_node_caches(0, from, NULL,
+                                     pcmk__node_search_cluster_member);
 
         pcmk__update_peer_expected(__func__, node, CRMD_JOINSTATE_DOWN);
         if(AM_I_DC == FALSE) {
diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
index 082a4f5af3..9205ec727d 100644
--- a/daemons/fenced/fenced_commands.c
+++ b/daemons/fenced/fenced_commands.c
@@ -2875,7 +2875,7 @@ fence_locally(xmlNode *msg, pcmk__action_result_t *result)
             pcmk__node_status_t *node = NULL;
 
             pcmk__scan_min_int(host, &nodeid, 0);
-            node = pcmk__search_node_caches(nodeid, NULL,
+            node = pcmk__search_node_caches(nodeid, NULL, NULL,
                                             pcmk__node_search_any
                                             |pcmk__node_search_cluster_cib);
             if (node != NULL) {
diff --git a/daemons/fenced/fenced_history.c b/daemons/fenced/fenced_history.c
index a5285209be..d1e088a617 100644
--- a/daemons/fenced/fenced_history.c
+++ b/daemons/fenced/fenced_history.c
@@ -487,7 +487,7 @@ stonith_fence_history(xmlNode *msg, xmlNode **output,
             pcmk__node_status_t *node = NULL;
 
             pcmk__scan_min_int(target, &nodeid, 0);
-            node = pcmk__search_node_caches(nodeid, NULL,
+            node = pcmk__search_node_caches(nodeid, NULL, NULL,
                                             pcmk__node_search_any
                                             |pcmk__node_search_cluster_cib);
             if (node != NULL) {
diff --git a/daemons/fenced/fenced_remote.c b/daemons/fenced/fenced_remote.c
index 1e19c51dc3..0f92ed5f30 100644
--- a/daemons/fenced/fenced_remote.c
+++ b/daemons/fenced/fenced_remote.c
@@ -1245,7 +1245,7 @@ create_remote_stonith_op(const char *client, xmlNode *request, gboolean peer)
         pcmk__node_status_t *node = NULL;
 
         pcmk__scan_min_int(op->target, &nodeid, 0);
-        node = pcmk__search_node_caches(nodeid, NULL,
+        node = pcmk__search_node_caches(nodeid, NULL, NULL,
                                         pcmk__node_search_any
                                         |pcmk__node_search_cluster_cib);
 
diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h
index 11a82beee3..0afca28950 100644
--- a/include/crm/cluster/internal.h
+++ b/include/crm/cluster/internal.h
@@ -309,6 +309,7 @@ void pcmk__cluster_forget_cluster_node(uint32_t id, const char *node_name);
 void pcmk__cluster_forget_remote_node(const char *node_name);
 pcmk__node_status_t *pcmk__search_node_caches(unsigned int id,
                                               const char *uname,
+                                              const char *xml_id,
                                               uint32_t flags);
 void pcmk__purge_node_from_cache(const char *node_name, uint32_t node_id);
 
diff --git a/lib/cluster/cpg.c b/lib/cluster/cpg.c
index 559dd408e0..fa9892e993 100644
--- a/lib/cluster/cpg.c
+++ b/lib/cluster/cpg.c
@@ -576,7 +576,7 @@ node_left(const char *cpg_group_name, int event_counter,
           size_t member_list_entries)
 {
     pcmk__node_status_t *peer =
-        pcmk__search_node_caches(cpg_peer->nodeid, NULL,
+        pcmk__search_node_caches(cpg_peer->nodeid, NULL, NULL,
                                  pcmk__node_search_cluster_member);
     const struct cpg_address **rival = NULL;
 
diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c
index 0705b6570d..bccbe12aa7 100644
--- a/lib/cluster/membership.c
+++ b/lib/cluster/membership.c
@@ -156,7 +156,7 @@ pcmk__cluster_lookup_remote_node(const char *node_name)
      * entry unless it has a node ID, which means the name actually is
      * associated with a cluster node. (@TODO return an error in that case?)
      */
-    node = pcmk__search_node_caches(0, node_name,
+    node = pcmk__search_node_caches(0, node_name, NULL,
                                     pcmk__node_search_cluster_member);
     if ((node != NULL) && (node->xml_id == NULL)) {
         /* node_name could be a pointer into the cache entry being removed, so
@@ -791,36 +791,47 @@ search_cluster_member_cache(unsigned int id, const char *uname,
  * \internal
  * \brief Search caches for a node (cluster or Pacemaker Remote)
  *
- * \param[in] id     If not 0, cluster node ID to search for
- * \param[in] uname  If not NULL, node name to search for
- * \param[in] flags  Group of enum pcmk__node_search_flags
+ * \param[in] id      If not 0, cluster node ID to search for
+ * \param[in] uname   If not NULL, node name to search for
+ * \param[in] xml_id  If not NULL, CIB XML ID of node to search for
+ * \param[in] flags   Group of enum pcmk__node_search_flags
  *
  * \return Node cache entry if found, otherwise NULL
  */
 pcmk__node_status_t *
-pcmk__search_node_caches(unsigned int id, const char *uname, uint32_t flags)
+pcmk__search_node_caches(unsigned int id, const char *uname,
+                         const char *xml_id, uint32_t flags)
 {
     pcmk__node_status_t *node = NULL;
 
-    pcmk__assert((id > 0) || (uname != NULL));
+    pcmk__assert((id > 0) || (uname != NULL) || (xml_id != NULL));
 
     pcmk__cluster_init_node_caches();
 
-    if ((uname != NULL) && pcmk_is_set(flags, pcmk__node_search_remote)) {
-        node = g_hash_table_lookup(pcmk__remote_peer_cache, uname);
+    if (pcmk_is_set(flags, pcmk__node_search_remote)) {
+        if (uname != NULL) {
+            node = g_hash_table_lookup(pcmk__remote_peer_cache, uname);
+        } else if (xml_id != NULL) {
+            node = g_hash_table_lookup(pcmk__remote_peer_cache, xml_id);
+        }
     }
 
     if ((node == NULL)
         && pcmk_is_set(flags, pcmk__node_search_cluster_member)) {
 
-        node = search_cluster_member_cache(id, uname, NULL);
+        node = search_cluster_member_cache(id, uname, xml_id);
     }
 
     if ((node == NULL) && pcmk_is_set(flags, pcmk__node_search_cluster_cib)) {
-        char *id_str = (id == 0)? NULL : crm_strdup_printf("%u", id);
+        if (xml_id != NULL) {
+            node = find_cib_cluster_node(xml_id, uname);
+        } else {
+            // Assumes XML ID is node ID as string (as with Corosync)
+            char *id_str = (id == 0)? NULL : crm_strdup_printf("%u", id);
 
-        node = find_cib_cluster_node(id_str, uname);
-        free(id_str);
+            node = find_cib_cluster_node(id_str, uname);
+            free(id_str);
+        }
     }
 
     return node;
-- 
2.43.0

