Blob Blame History Raw
From 5c2d8665773254ff8b9676ac359a1210e34640e3 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 1 Mar 2021 14:02:52 +0100
Subject: [PATCH] API: add pcmk__mainloop_timer_get_period() to internal API

---
 include/crm/common/internal.h |  1 +
 lib/common/mainloop.c         | 34 +++++++++++++++++++++++++---------
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/include/crm/common/internal.h b/include/crm/common/internal.h
index f69abe8..63bfd2c 100644
--- a/include/crm/common/internal.h
+++ b/include/crm/common/internal.h
@@ -96,6 +96,7 @@ pcmk__open_devnull(int flags)
 int pcmk__add_mainloop_ipc(crm_ipc_t *ipc, int priority, void *userdata,
                            struct ipc_client_callbacks *callbacks,
                            mainloop_io_t **source);
+guint pcmk__mainloop_timer_get_period(mainloop_timer_t *timer);
 
 
 /* internal messaging utilities (from messages.c) */
diff --git a/lib/common/mainloop.c b/lib/common/mainloop.c
index 2f00e31..75f24e2 100644
--- a/lib/common/mainloop.c
+++ b/lib/common/mainloop.c
@@ -49,6 +49,15 @@ struct trigger_s {
 
 };
 
+struct mainloop_timer_s {
+        guint id;
+        guint period_ms;
+        bool repeat;
+        char *name;
+        GSourceFunc cb;
+        void *userdata;
+};
+
 static gboolean
 crm_trigger_prepare(GSource * source, gint * timeout)
 {
@@ -875,6 +884,22 @@ pcmk__add_mainloop_ipc(crm_ipc_t *ipc, int priority, void *userdata,
     return pcmk_rc_ok;
 }
 
+/*!
+ * \brief Get period for mainloop timer
+ *
+ * \param[in]  timer      Timer
+ *
+ * \return Period in ms
+ */
+guint
+pcmk__mainloop_timer_get_period(mainloop_timer_t *timer)
+{
+    if (timer) {
+        return timer->period_ms;
+    }
+    return 0;
+}
+
 mainloop_io_t *
 mainloop_add_ipc_client(const char *name, int priority, size_t max_size,
                         void *userdata, struct ipc_client_callbacks *callbacks)
@@ -1252,15 +1277,6 @@ mainloop_child_add(pid_t pid, int timeout, const char *desc, void *privatedata,
     mainloop_child_add_with_flags(pid, timeout, desc, privatedata, 0, callback);
 }
 
-struct mainloop_timer_s {
-        guint id;
-        guint period_ms;
-        bool repeat;
-        char *name;
-        GSourceFunc cb;
-        void *userdata;
-};
-
 static gboolean
 mainloop_timer_cb(gpointer user_data)
 {
-- 
1.8.3.1

From 1d33712201e42f0e8ee108999cd4cb8fa0eeca95 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 19 Feb 2021 12:34:04 +0100
Subject: [PATCH] Feature: fenced: retry getting metadata until we get it

---
 daemons/fenced/fenced_commands.c  | 35 +++++++++++++++++++++++++++++++++++
 daemons/fenced/pacemaker-fenced.h |  1 +
 2 files changed, 36 insertions(+)

diff --git a/daemons/fenced/fenced_commands.c b/daemons/fenced/fenced_commands.c
index 41901e5..65b41c5 100644
--- a/daemons/fenced/fenced_commands.c
+++ b/daemons/fenced/fenced_commands.c
@@ -69,6 +69,9 @@ static void stonith_send_reply(xmlNode * reply, int call_options, const char *re
 static void search_devices_record_result(struct device_search_s *search, const char *device,
                                          gboolean can_fence);
 
+static xmlNode * get_agent_metadata(const char *agent);
+static void read_action_metadata(stonith_device_t *device);
+
 typedef struct async_command_s {
 
     int id;
@@ -323,6 +326,25 @@ fork_cb(GPid pid, gpointer user_data)
     cmd->activating_on = NULL;
 }
 
+static int
+get_agent_metadata_cb(gpointer data) {
+    stonith_device_t *device = data;
+
+    device->agent_metadata = get_agent_metadata(device->agent);
+    if (device->agent_metadata) {
+        read_action_metadata(device);
+        stonith__device_parameter_flags(&(device->flags), device->id,
+                                        device->agent_metadata);
+        return G_SOURCE_REMOVE;
+    } else {
+        guint period_ms = pcmk__mainloop_timer_get_period(device->timer);
+        if (period_ms < 160 * 1000) {
+            mainloop_timer_set_period(device->timer, 2 * period_ms);
+        }
+        return G_SOURCE_CONTINUE;
+    }
+}
+
 static gboolean
 stonith_device_execute(stonith_device_t * device)
 {
@@ -569,6 +591,11 @@ free_device(gpointer data)
 
     g_list_free_full(device->targets, free);
 
+    if (device->timer) {
+        mainloop_timer_stop(device->timer);
+        mainloop_timer_del(device->timer);
+    }
+
     mainloop_destroy_trigger(device->work);
 
     free_xml(device->agent_metadata);
@@ -916,6 +943,14 @@ build_device_from_xml(xmlNode * msg)
         read_action_metadata(device);
         stonith__device_parameter_flags(&(device->flags), device->id,
                                         device->agent_metadata);
+    } else {
+        if (device->timer == NULL) {
+            device->timer = mainloop_timer_add("get_agent_metadata", 10 * 1000,
+                                           TRUE, get_agent_metadata_cb, device);
+        }
+        if (!mainloop_timer_running(device->timer)) {
+            mainloop_timer_start(device->timer);
+        }
     }
 
     value = g_hash_table_lookup(device->params, "nodeid");
diff --git a/daemons/fenced/pacemaker-fenced.h b/daemons/fenced/pacemaker-fenced.h
index 13cf6dc..e342692 100644
--- a/daemons/fenced/pacemaker-fenced.h
+++ b/daemons/fenced/pacemaker-fenced.h
@@ -41,6 +41,7 @@ typedef struct stonith_device_s {
     GHashTable *params;
     GHashTable *aliases;
     GList *pending_ops;
+    mainloop_timer_t *timer;
     crm_trigger_t *work;
     xmlNode *agent_metadata;
 
-- 
1.8.3.1