File bsc#1171372-0008-Fix-libstonithd-add-port-or-plug-parameter-according.patch of Package pacemaker.19271

From 4331bd3c24ffb93fe4c47095c86efd41fbffad8d Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Wed, 6 May 2020 21:47:47 +0200
Subject: [PATCH 8/8] Fix: libstonithd: add `port` or `plug` parameter
 according to metadata on `validate` if no `pcmk_host_argument` specified

---
 include/crm/fencing/internal.h |  2 +-
 lib/fencing/st_client.c        |  8 +++-
 lib/fencing/st_rhcs.c          | 76 ++++++++++++++++++++++++++++++----
 3 files changed, 76 insertions(+), 10 deletions(-)

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
@@ -154,7 +154,7 @@ int stonith__list_rhcs_agents(stonith_ke
 int stonith__rhcs_metadata(const char *agent, int timeout, char **output);
 bool stonith__agent_is_rhcs(const char *agent);
 int stonith__rhcs_validate(stonith_t *st, int call_options, const char *target,
-                           const char *agent, GHashTable *params,
+                           const char *agent, GHashTable *params, const char *host_arg,
                            int timeout, char **output, char **error_output);
 
 #endif
Index: pacemaker-2.0.1+20190417.13d370ca9/lib/fencing/st_client.c
===================================================================
--- pacemaker-2.0.1+20190417.13d370ca9.orig/lib/fencing/st_client.c
+++ pacemaker-2.0.1+20190417.13d370ca9/lib/fencing/st_client.c
@@ -2231,11 +2231,15 @@ stonith_api_validate(stonith_t *st, int
      * that is incorrect, we will need to allow the caller to pass the target).
      */
     const char *target = "node1";
+    const char *host_arg = NULL;
 
     GHashTable *params_table = crm_str_table_new();
 
     // Convert parameter list to a hash table
     for (; params; params = params->next) {
+        if (safe_str_eq(params->key, STONITH_ATTR_HOSTARG)) {
+            host_arg = params->value;
+        }
 
         // Strip out Pacemaker-implemented parameters
         if (!crm_starts_with(params->key, "pcmk_")
@@ -2264,8 +2268,8 @@ stonith_api_validate(stonith_t *st, int
     switch (stonith_get_namespace(agent, namespace_s)) {
         case st_namespace_rhcs:
             rc = stonith__rhcs_validate(st, call_options, target, agent,
-                                        params_table, timeout, output,
-                                        error_output);
+                                        params_table, host_arg, timeout,
+                                        output, error_output);
             break;
 
 #if HAVE_STONITH_STONITH_H
Index: pacemaker-2.0.1+20190417.13d370ca9/lib/fencing/st_rhcs.c
===================================================================
--- pacemaker-2.0.1+20190417.13d370ca9.orig/lib/fencing/st_rhcs.c
+++ pacemaker-2.0.1+20190417.13d370ca9/lib/fencing/st_rhcs.c
@@ -110,12 +110,12 @@ stonith_rhcs_parameter_not_required(xmlN
  *
  * \param[in]  agent    Agent to execute
  * \param[in]  timeout  Action timeout
- * \param[out] output   Where to store action output (or NULL to ignore)
+ * \param[out] metadata Where to store output xmlNode (or NULL to ignore)
  *
  * \todo timeout is currently ignored; shouldn't we use it?
  */
-int
-stonith__rhcs_metadata(const char *agent, int timeout, char **output)
+static int
+stonith__rhcs_get_metadata(const char *agent, int timeout, xmlNode **metadata)
 {
     char *buffer = NULL;
     xmlNode *xml = NULL;
@@ -180,6 +180,38 @@ stonith__rhcs_metadata(const char *agent
     stonith_rhcs_parameter_not_required(xml, "plug");
     stonith_rhcs_parameter_not_required(xml, "port");
 
+    if (metadata) {
+        *metadata = xml;
+
+    } else {
+        free_xml(xml);
+    }
+
+    return pcmk_ok;
+}
+
+/*!
+ * \brief Execute RHCS-compatible agent's meta-data action
+ *
+ * \param[in]  agent    Agent to execute
+ * \param[in]  timeout  Action timeout
+ * \param[out] output   Where to store action output (or NULL to ignore)
+ *
+ * \todo timeout is currently ignored; shouldn't we use it?
+ */
+int
+stonith__rhcs_metadata(const char *agent, int timeout, char **output)
+{
+    char *buffer = NULL;
+    xmlNode *xml = NULL;
+
+    int rc = stonith__rhcs_get_metadata(agent, timeout, &xml);
+
+    if (rc != pcmk_ok) {
+        free_xml(xml);
+        return rc;
+    }
+
     buffer = dump_xml_formatted_with_text(xml);
     free_xml(xml);
     if (buffer == NULL) {
@@ -206,13 +238,43 @@ stonith__agent_is_rhcs(const char *agent
 
 int
 stonith__rhcs_validate(stonith_t *st, int call_options, const char *target,
-                       const char *agent, GHashTable *params, int timeout,
+                       const char *agent, GHashTable *params,
+                       const char * host_arg, int timeout,
                        char **output, char **error_output)
 {
     int rc = pcmk_ok;
-    stonith_action_t *action = stonith_action_create(agent, "validate-all",
-                                                     target, 0, timeout, params,
-                                                     NULL, NULL);
+    int remaining_timeout = timeout;
+    xmlNode *metadata = NULL;
+    stonith_action_t *action = NULL;
+
+    if (host_arg == NULL) {
+        time_t start_time = time(NULL);
+
+        rc = stonith__rhcs_get_metadata(agent, remaining_timeout, &metadata);
+
+        if (rc == pcmk_ok) {
+            long long device_flags = stonith__device_parameter_flags(metadata);
+
+            if (is_set(device_flags, st_device_supports_parameter_port)) {
+                host_arg = "port";
+
+            } else if (is_set(device_flags, st_device_supports_parameter_plug)) {
+                host_arg = "plug";
+            }
+        }
+
+        free_xml(metadata);
+
+        remaining_timeout -= time(NULL) - start_time;
+
+        if (rc == -ETIME || remaining_timeout <= 0 ) {
+            return -ETIME;
+        }
+    }
+
+    action = stonith_action_create(agent, "validate-all",
+                                   target, 0, remaining_timeout, params,
+                                   NULL, host_arg);
 
     rc = stonith__execute(action);
     if (rc == pcmk_ok) {
openSUSE Build Service is sponsored by