From 838dd1459991af64d6230854ab1aef7dedd7f9c3 Mon Sep 17 00:00:00 2001 From: Jacek Tomasiak Date: Mon, 20 May 2019 14:29:13 +0200 Subject: [PATCH] Fix: sbd-cluster: stop dispatching cmap if disconnected If cmap socket is in HUP state, attempt to dispatch incoming events will trigger the callback again and cause infinite loop with high CPU load. Added check should solve this by destroying the cmap connection and removing it from the main loop. --- src/sbd-cluster.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/sbd-cluster.c b/src/sbd-cluster.c index 541212f..aa963fb 100644 --- a/src/sbd-cluster.c +++ b/src/sbd-cluster.c @@ -35,6 +35,18 @@ #if CHECK_TWO_NODE #include +// available since glib 2.58 +#ifndef G_SOURCE_FUNC +#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f)) +#endif +// available since glib 2.32 +#ifndef G_SOURCE_REMOVE +#define G_SOURCE_REMOVE FALSE +#endif +// available since glib 2.32 +#ifndef G_SOURCE_CONTINUE +#define G_SOURCE_CONTINUE TRUE +#endif #endif #include "sbd.h" @@ -58,6 +70,9 @@ static crm_cluster_t cluster; static gboolean sbd_remote_check(gpointer user_data); static long unsigned int find_pacemaker_remote(void); static void sbd_membership_destroy(gpointer user_data); +#if CHECK_TWO_NODE +static void cmap_destroy(void); +#endif #if SUPPORT_PLUGIN @@ -168,10 +183,19 @@ static void sbd_cmap_notify_fn( } static gboolean -cmap_dispatch_callback (gpointer user_data) +cmap_dispatch_callback (gint cmap_fd, + GIOCondition condition, + gpointer user_data) { + /* CMAP connection lost */ + if (condition & G_IO_HUP) { + cl_log(LOG_WARNING, "CMAP service connection lost\n"); + cmap_destroy(); + /* remove the source from the main loop */ + return G_SOURCE_REMOVE; + } cmap_dispatch(cmap_handle, CS_DISPATCH_ALL); - return TRUE; + return G_SOURCE_CONTINUE; } static void @@ -222,7 +246,7 @@ sbd_get_two_node(void) cl_log(LOG_WARNING, "Couldn't create source for cmap\n"); goto out; } - g_source_set_callback(cmap_source, cmap_dispatch_callback, NULL, NULL); + g_source_set_callback(cmap_source, G_SOURCE_FUNC(cmap_dispatch_callback), NULL, NULL); g_source_attach(cmap_source, NULL); }