Blob Blame History Raw
From: Andrew Beekhof <andrew@beekhof.net>
Date: Tue, 8 Sep 2015 12:05:04 +1000
Subject: [PATCH] Refactor: membership: Safely autoreap nodes without code
 duplication

(cherry picked from commit acd660a1bdf40ada599041cb14d2128632d2e7a5)
---
 lib/cluster/membership.c | 43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c
index b7958eb..3081e54 100644
--- a/lib/cluster/membership.c
+++ b/lib/cluster/membership.c
@@ -795,8 +795,8 @@ crm_update_peer_expected(const char *source, crm_node_t * node, const char *expe
  *       called within a cache iteration if reaping is possible,
  *       otherwise reaping could invalidate the iterator.
  */
-crm_node_t *
-crm_update_peer_state(const char *source, crm_node_t * node, const char *state, int membership)
+static crm_node_t *
+crm_update_peer_state_iter(const char *source, crm_node_t * node, const char *state, int membership, GHashTableIter *iter)
 {
     gboolean is_member;
 
@@ -822,13 +822,19 @@ crm_update_peer_state(const char *source, crm_node_t * node, const char *state,
         free(last);
 
         if (!is_member && crm_autoreap) {
-            if (status_type == crm_status_rstate) {
+            if(iter) {
+                crm_notice("Purged 1 peer with id=%u and/or uname=%s from the membership cache", node->id, node->uname);
+                g_hash_table_iter_remove(iter);
+
+            } else if (status_type == crm_status_rstate) {
                 crm_remote_peer_cache_remove(node->uname);
+
             } else {
                 reap_crm_member(node->id, node->uname);
             }
             node = NULL;
         }
+
     } else {
         crm_trace("%s: Node %s[%u] - state is unchanged (%s)", source, node->uname, node->id,
                   state);
@@ -836,6 +842,12 @@ crm_update_peer_state(const char *source, crm_node_t * node, const char *state,
     return node;
 }
 
+crm_node_t *
+crm_update_peer_state(const char *source, crm_node_t * node, const char *state, int membership)
+{
+    return crm_update_peer_state_iter(source, node, state, membership, NULL);
+}
+
 /*!
  * \internal
  * \brief Reap all nodes from cache whose membership information does not match
@@ -853,26 +865,13 @@ crm_reap_unseen_nodes(uint64_t membership)
     while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&node)) {
         if (node->last_seen != membership) {
             if (node->state) {
-                /* crm_update_peer_state() cannot be called here, because that
-                 * might modify the peer cache, invalidating our iterator
+                /*
+                 * Calling crm_update_peer_state_iter() allows us to
+                 * remove the node from crm_peer_cache without
+                 * invalidating our iterator
                  */
-                if (safe_str_eq(node->state, CRM_NODE_LOST)) {
-                    crm_trace("Node %s[%u] - state is unchanged (%s)",
-                              node->uname, node->id, CRM_NODE_LOST);
-                } else {
-                    char *last = node->state;
-
-                    node->state = strdup(CRM_NODE_LOST);
-                    crm_notice("Node %s[%u] - state is now %s (was %s)",
-                               node->uname, node->id, CRM_NODE_LOST, last);
-                    if (crm_status_callback) {
-                        crm_status_callback(crm_status_nstate, node, last);
-                    }
-                    if (crm_autoreap) {
-                        g_hash_table_iter_remove(&iter);
-                    }
-                    free(last);
-                }
+                crm_update_peer_state_iter(__FUNCTION__, node, CRM_NODE_LOST, membership, &iter);
+
             } else {
                 crm_info("State of node %s[%u] is still unknown",
                          node->uname, node->id);