Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
pacemaker
bsc#1094208-0001-Fix-controld-able-to-manually-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bsc#1094208-0001-Fix-controld-able-to-manually-confirm-unseen-nodes-a.patch of Package pacemaker
From e9f7252cc003e90f9fad316e255fe16de82f195c Mon Sep 17 00:00:00 2001 From: "Gao,Yan" <ygao@suse.com> Date: Fri, 1 Jun 2018 15:23:49 +0200 Subject: [PATCH 1/2] Fix: controld: able to manually confirm unseen nodes are down 9045bacb4 prevented manual fencing confirmations from creating node entries for random unknown nodes, but it also disabled the ability to do manual fencing confirmations for the nodes that are already known in the CIB but not yet in the membership cache. This commit fixes it by maintaining and utilizing an additional membership cache of known nodes based on the CIB. --- crmd/pengine.c | 5 +- crmd/te_utils.c | 2 +- include/crm/cluster/internal.h | 3 + lib/cluster/membership.c | 177 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 3 deletions(-) diff --git a/crmd/pengine.c b/crmd/pengine.c index fd7b4d49d..8ecb21d69 100644 --- a/crmd/pengine.c +++ b/crmd/pengine.c @@ -320,8 +320,9 @@ do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void CRM_LOG_ASSERT(output != NULL); - /* refresh our remote-node cache when the pengine is invoked */ - crm_remote_peer_cache_refresh(output); + /* Refresh the remote node cache and the known node cache when the + * scheduler is invoked */ + crm_peer_caches_refresh(output); crm_xml_add(output, XML_ATTR_DC_UUID, fsa_our_uuid); crm_xml_add_int(output, XML_ATTR_HAVE_QUORUM, fsa_has_quorum); diff --git a/crmd/te_utils.c b/crmd/te_utils.c index eee5d62d5..280fc95e9 100644 --- a/crmd/te_utils.c +++ b/crmd/te_utils.c @@ -328,7 +328,7 @@ tengine_stonith_notify(stonith_t * st, stonith_event_t * st_event) #endif if (st_event->result == pcmk_ok) { - crm_node_t *peer = crm_find_peer_full(0, st_event->target, CRM_GET_PEER_ANY); + crm_node_t *peer = crm_find_known_peer_full(0, st_event->target, CRM_GET_PEER_ANY); const char *uuid = NULL; gboolean we_are_executioner = safe_str_eq(st_event->executioner, fsa_our_uname); diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h index 6a571e6bb..916e1eba9 100644 --- a/include/crm/cluster/internal.h +++ b/include/crm/cluster/internal.h @@ -472,4 +472,7 @@ gboolean node_name_is_valid(const char *key, const char *name); crm_node_t * crm_find_peer_full(unsigned int id, const char *uname, int flags); crm_node_t * crm_find_peer(unsigned int id, const char *uname); +void crm_peer_caches_refresh(xmlNode *cib); +crm_node_t *crm_find_known_peer_full(unsigned int id, const char *uname, int flags); + #endif diff --git a/lib/cluster/membership.c b/lib/cluster/membership.c index 5744621a5..76df36347 100644 --- a/lib/cluster/membership.c +++ b/lib/cluster/membership.c @@ -61,6 +61,8 @@ GHashTable *crm_peer_cache = NULL; */ GHashTable *crm_remote_peer_cache = NULL; +GHashTable *crm_known_peer_cache = NULL; + unsigned long long crm_peer_seq = 0; gboolean crm_have_quorum = FALSE; static gboolean crm_autoreap = TRUE; @@ -425,6 +427,10 @@ crm_peer_init(void) if (crm_remote_peer_cache == NULL) { crm_remote_peer_cache = g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, NULL, destroy_crm_node); } + + if (crm_known_peer_cache == NULL) { + crm_known_peer_cache = g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, free, destroy_crm_node); + } } void @@ -441,6 +447,13 @@ crm_peer_destroy(void) g_hash_table_destroy(crm_remote_peer_cache); crm_remote_peer_cache = NULL; } + + if (crm_known_peer_cache != NULL) { + crm_trace("Destroying known peer cache with %d members", g_hash_table_size(crm_known_peer_cache)); + g_hash_table_destroy(crm_known_peer_cache); + crm_known_peer_cache = NULL; + } + } void (*crm_status_callback) (enum crm_status_type, crm_node_t *, const void *) = NULL; @@ -1123,3 +1136,167 @@ crm_terminate_member_no_mainloop(int nodeid, const char *uname, int *connection) { return stonith_api_kick(nodeid, uname, 120, TRUE); } + +static crm_node_t * +crm_find_known_peer(const char *id, const char *uname) +{ + GHashTableIter iter; + crm_node_t *node = NULL; + crm_node_t *by_id = NULL; + crm_node_t *by_name = NULL; + + if (uname) { + g_hash_table_iter_init(&iter, crm_known_peer_cache); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { + if (node->uname && strcasecmp(node->uname, uname) == 0) { + crm_trace("Name match: %s = %p", node->uname, node); + by_name = node; + break; + } + } + } + + if (id) { + g_hash_table_iter_init(&iter, crm_known_peer_cache); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { + if(strcasecmp(node->uuid, id) == 0) { + crm_trace("ID match: %s= %p", id, node); + by_id = node; + break; + } + } + } + + node = by_id; /* Good default */ + if (by_id == by_name) { + /* Nothing to do if they match (both NULL counts) */ + crm_trace("Consistent: %p for %s/%s", by_id, id, uname); + + } else if (by_id == NULL && by_name) { + crm_trace("Only one: %p for %s/%s", by_name, id, uname); + + if (id) { + node = NULL; + + } else { + node = by_name; + } + + } else if (by_name == NULL && by_id) { + crm_trace("Only one: %p for %s/%s", by_id, id, uname); + + if (uname) { + node = NULL; + } + + } else if (uname && by_id->uname + && safe_str_eq(uname, by_id->uname)) { + /* Multiple nodes have the same uname in the CIB. + * Return by_id. */ + + } else if (id && by_name->uuid + && safe_str_eq(id, by_name->uuid)) { + /* Multiple nodes have the same id in the CIB. + * Return by_name. */ + node = by_name; + + } else { + node = NULL; + } + + if (node == NULL) { + crm_debug("Couldn't find node%s%s%s%s", + id? " " : "", + id? id : "", + uname? " with name " : "", + uname? uname : ""); + } + + return node; +} + +static void +known_peer_cache_refresh_helper(xmlNode *xml_node, void *user_data) +{ + const char *id = crm_element_value(xml_node, XML_ATTR_ID); + const char *uname = crm_element_value(xml_node, XML_ATTR_UNAME); + crm_node_t * node = NULL; + + CRM_CHECK(id != NULL && uname !=NULL, return); + node = crm_find_known_peer(id, uname); + + if (node == NULL) { + char *uniqueid = crm_generate_uuid(); + + node = calloc(1, sizeof(crm_node_t)); + CRM_ASSERT(node != NULL); + + node->uname = strdup(uname); + CRM_ASSERT(node->uname != NULL); + + node->uuid = strdup(id); + CRM_ASSERT(node->uuid != NULL); + + g_hash_table_replace(crm_known_peer_cache, uniqueid, node); + + } else if (is_set(node->flags, crm_node_dirty)) { + if (safe_str_neq(uname, node->uname)) { + free(node->uname); + node->uname = strdup(uname); + CRM_ASSERT(node->uname != NULL); + } + + /* Node is in cache and hasn't been updated already, so mark it clean */ + clear_bit(node->flags, crm_node_dirty); + } + +} + +#define XPATH_MEMBER_NODE_CONFIG \ + "//" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \ + "/" XML_CIB_TAG_NODE "[not(@type) or @type='member']" + +static void +crm_known_peer_cache_refresh(xmlNode *cib) +{ + crm_peer_init(); + + g_hash_table_foreach(crm_known_peer_cache, mark_dirty, NULL); + + crm_foreach_xpath_result(cib, XPATH_MEMBER_NODE_CONFIG, + known_peer_cache_refresh_helper, NULL); + + /* Remove all old cache entries that weren't seen in the CIB */ + g_hash_table_foreach_remove(crm_known_peer_cache, is_dirty, NULL); +} + +void +crm_peer_caches_refresh(xmlNode *cib) +{ + crm_remote_peer_cache_refresh(cib); + crm_known_peer_cache_refresh(cib); +} + +crm_node_t * +crm_find_known_peer_full(unsigned int id, const char *uname, int flags) +{ + crm_node_t *node = NULL; + char *id_str = NULL; + + CRM_ASSERT(id > 0 || uname != NULL); + + node = crm_find_peer_full(id, uname, flags); + + if (node || !(flags & CRM_GET_PEER_CLUSTER)) { + return node; + } + + if (id > 0) { + id_str = crm_strdup_printf("%u", id); + } + + node = crm_find_known_peer(id_str, uname); + + free(id_str); + return node; +} -- 2.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor