File bsc#1181744-0001-Low-fenced-Remove-relayed-stonith-operation.-Fix-CLB-1.1.patch of Package pacemaker.19778
From cae1b8d6357f6516358c77982524d4d96bf5cd58 Mon Sep 17 00:00:00 2001
From: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Fri, 8 May 2020 18:22:02 +0200
Subject: [PATCH] Low: fenced: Remove relayed stonith operation.(Fix:CLBZ#5401)
---
fencing/commands.c | 60 ++++++++++++++++++++++++++++++++--
fencing/remote.c | 22 ++++++++++++-
include/crm/fencing/internal.h | 1 +
3 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/fencing/commands.c b/fencing/commands.c
index 8dfb1d6b4..1040af759 100644
--- a/fencing/commands.c
+++ b/fencing/commands.c
@@ -2509,6 +2509,55 @@ stonith_send_reply(xmlNode * reply, int call_options, const char *remote_peer,
}
}
+static void
+remove_relay_op(xmlNode * request)
+{
+ xmlNode *dev = get_xpath_object("//@" F_STONITH_ACTION, request, LOG_TRACE);
+ const char *relay_op_id = NULL;
+ const char *op_id = NULL;
+ const char *client_name = NULL;
+ const char *target = NULL;
+ remote_fencing_op_t *relay_op = NULL;
+
+ if (dev) {
+ target = crm_element_value(dev, F_STONITH_TARGET);
+ }
+
+ relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID_RELAY);
+ op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
+ client_name = crm_element_value(request, F_STONITH_CLIENTNAME);
+
+ /* Delete RELAY operation. */
+ if (relay_op_id && target && safe_str_eq(target, stonith_our_uname)) {
+ relay_op = g_hash_table_lookup(stonith_remote_op_list, relay_op_id);
+
+ if (relay_op) {
+ GHashTableIter iter;
+ remote_fencing_op_t *list_op = NULL;
+ g_hash_table_iter_init(&iter, stonith_remote_op_list);
+
+ /* If the operation to be deleted is registered as a duplicate, delete the registration. */
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&list_op)) {
+ GListPtr dup_iter = NULL;
+ if (list_op != relay_op) {
+ for (dup_iter = list_op->duplicates; dup_iter != NULL; dup_iter = dup_iter->next) {
+ remote_fencing_op_t *other = dup_iter->data;
+ if (other == relay_op) {
+ other->duplicates = g_list_remove(other->duplicates, relay_op);
+ break;
+ }
+ }
+ }
+ }
+ crm_info("Delete the relay op : %s - %s of %s for %s.(replaced by op : %s - %s of %s for %s)",
+ relay_op->id, relay_op->action, relay_op->target, relay_op->client_name,
+ op_id, relay_op->action, target, client_name);
+
+ g_hash_table_remove(stonith_remote_op_list, relay_op_id);
+ }
+ }
+}
+
static int
handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * request,
const char *remote_peer)
@@ -2556,6 +2605,10 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req
if (remote_peer) {
create_remote_stonith_op(client_id, request, TRUE); /* Record it for the future notification */
}
+
+ /* Delete the DC node RELAY operation. */
+ remove_relay_op(request);
+
stonith_query(request, remote_peer, client_id, call_options);
return 0;
@@ -2636,6 +2689,7 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req
if (alternate_host && client) {
const char *client_id = NULL;
+ remote_fencing_op_t *op = NULL;
crm_notice("Forwarding complex self fencing request to peer %s", alternate_host);
@@ -2645,11 +2699,13 @@ handle_request(crm_client_t * client, uint32_t id, uint32_t flags, xmlNode * req
client_id = crm_element_value(request, F_STONITH_CLIENTID);
}
- /* Create a record of it, otherwise call_id will be 0 if we need to notify of failures */
- create_remote_stonith_op(client_id, request, FALSE);
+ /* Create an operation for RELAY and send the ID in the RELAY message. */
+ /* When a QUERY response is received, delete the RELAY operation to avoid the existence of duplicate operations. */
+ op = create_remote_stonith_op(client_id, request, FALSE);
crm_xml_add(request, F_STONITH_OPERATION, STONITH_OP_RELAY);
crm_xml_add(request, F_STONITH_CLIENTID, client->id);
+ crm_xml_add(request, F_STONITH_REMOTE_OP_ID, op->id);
send_cluster_message(crm_get_peer(0, alternate_host), crm_msg_stonith_ng, request,
FALSE);
rc = -EINPROGRESS;
diff --git a/fencing/remote.c b/fencing/remote.c
index 9658b65d4..184f01eed 100644
--- a/fencing/remote.c
+++ b/fencing/remote.c
@@ -977,6 +977,7 @@ create_remote_stonith_op(const char *client, xmlNode * request, gboolean peer)
remote_fencing_op_t *op = NULL;
xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request, LOG_TRACE);
int call_options = 0;
+ const char *operation = NULL;
init_stonith_remote_op_hash_table(&stonith_remote_op_list);
@@ -1027,7 +1028,15 @@ create_remote_stonith_op(const char *client, xmlNode * request, gboolean peer)
op->client_id = strdup(client);
}
- op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);
+ /* For a RELAY operation, set fenced on the client. */
+ operation = crm_element_value(request, F_STONITH_OPERATION);
+
+ if (crm_str_eq(operation, STONITH_OP_RELAY, TRUE)) {
+ op->client_name = crm_strdup_printf("%s.%lu", crm_system_name,
+ (unsigned long) getpid());
+ } else {
+ op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);
+ }
op->target = crm_element_value_copy(dev, F_STONITH_TARGET);
op->request = copy_xml(request); /* TODO: Figure out how to avoid this */
@@ -1077,6 +1086,8 @@ initiate_remote_stonith_op(crm_client_t * client, xmlNode * request, gboolean ma
xmlNode *query = NULL;
const char *client_id = NULL;
remote_fencing_op_t *op = NULL;
+ const char *relay_op_id = NULL;
+ const char *operation = NULL;
if (client) {
client_id = client->id;
@@ -1128,6 +1139,15 @@ initiate_remote_stonith_op(crm_client_t * client, xmlNode * request, gboolean ma
crm_xml_add(query, F_STONITH_CLIENTNAME, op->client_name);
crm_xml_add_int(query, F_STONITH_TIMEOUT, op->base_timeout);
+ /* In case of RELAY operation, RELAY information is added to the query to delete the original operation of RELAY. */
+ operation = crm_element_value(request, F_STONITH_OPERATION);
+ if (crm_str_eq(operation, STONITH_OP_RELAY, TRUE)) {
+ relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
+ if (relay_op_id) {
+ crm_xml_add(query, F_STONITH_REMOTE_OP_ID_RELAY, relay_op_id);
+ }
+ }
+
send_cluster_message(NULL, crm_msg_stonith_ng, query, FALSE);
free_xml(query);
diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h
index 63fcb09e7..5220001a2 100644
--- a/include/crm/fencing/internal.h
+++ b/include/crm/fencing/internal.h
@@ -66,6 +66,7 @@ long long stonith__device_parameter_flags(xmlNode *metadata);
# define F_STONITH_OPERATION "st_op"
# define F_STONITH_TARGET "st_target"
# define F_STONITH_REMOTE_OP_ID "st_remote_op"
+# define F_STONITH_REMOTE_OP_ID_RELAY "st_remote_op_relay"
# define F_STONITH_RC "st_rc"
/*! Timeout period per a device execution */
# define F_STONITH_TIMEOUT "st_timeout"
--
2.26.2