File bsc#1181744-0001-Low-fenced-Remove-relayed-stonith-operation.-Fix-CLB.patch of Package pacemaker.22684

From df71a0721996bf1b2c0c8028b075911d40e345a7 Mon Sep 17 00:00:00 2001
From: Hideo Yamauchi <renayama19661014@ybb.ne.jp>
Date: Wed, 6 May 2020 13:13:27 +0900
Subject: [PATCH] Low: fenced: Remove relayed stonith operation.(Fix:CLBZ#5401)

---
 daemons/fenced/fenced_commands.c | 60 ++++++++++++++++++++++++++++++--
 daemons/fenced/fenced_remote.c   | 23 +++++++++++-
 include/crm/fencing/internal.h   |  1 +
 3 files changed, 81 insertions(+), 3 deletions(-)

Index: pacemaker-2.0.1+20190417.13d370ca9/daemons/fenced/fenced_commands.c
===================================================================
--- pacemaker-2.0.1+20190417.13d370ca9.orig/daemons/fenced/fenced_commands.c
+++ pacemaker-2.0.1+20190417.13d370ca9/daemons/fenced/fenced_commands.c
@@ -2524,6 +2524,55 @@ stonith_send_reply(xmlNode * reply, int
     }
 }
 
+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)
@@ -2583,6 +2632,10 @@ handle_request(crm_client_t * client, ui
         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;
 
@@ -2663,6 +2716,7 @@ handle_request(crm_client_t * client, ui
 
             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);
 
@@ -2672,11 +2726,13 @@ handle_request(crm_client_t * client, ui
                     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;
Index: pacemaker-2.0.1+20190417.13d370ca9/daemons/fenced/fenced_remote.c
===================================================================
--- pacemaker-2.0.1+20190417.13d370ca9.orig/daemons/fenced/fenced_remote.c
+++ pacemaker-2.0.1+20190417.13d370ca9/daemons/fenced/fenced_remote.c
@@ -953,6 +953,7 @@ create_remote_stonith_op(const char *cli
     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);
 
@@ -1003,7 +1004,16 @@ create_remote_stonith_op(const char *cli
         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 */
@@ -1053,6 +1063,8 @@ initiate_remote_stonith_op(crm_client_t
     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;
@@ -1104,6 +1116,15 @@ initiate_remote_stonith_op(crm_client_t
     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);
 
Index: pacemaker-2.0.1+20190417.13d370ca9/include/crm/fencing/internal.h
===================================================================
--- pacemaker-2.0.1+20190417.13d370ca9.orig/include/crm/fencing/internal.h
+++ pacemaker-2.0.1+20190417.13d370ca9/include/crm/fencing/internal.h
@@ -67,6 +67,7 @@ long long stonith__device_parameter_flag
 #  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"
openSUSE Build Service is sponsored by