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