Blob Blame History Raw
From 073cc01f52f8b2b6d5b20c63814dc1ed00699028 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 18 Nov 2013 23:37:58 +0100
Subject: [PATCH] dispatcher: fix crash while logging from signal handler
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Bug rh#1017884 describes a crash, where dbus_init() failed, which causes
a g_warning(). While writing the warning, a SIGTERM hit, and the
signal_handler() tries to call again g_message().

The logging functions of glib are not reentrant and call abort() when
invoked recursivly. The solution, is to use g_unix_signal_add, which
will dispatch the handler on the mainloop asynchronously.

This bug is not that serious, because the dispatcher was about to
terminate anyway. However, it gets registered as a crash by the system
(ABRT).

https://bugzilla.redhat.com/show_bug.cgi?id=1017884

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
---
 callouts/nm-dispatcher-action.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/callouts/nm-dispatcher-action.c b/callouts/nm-dispatcher-action.c
index 397f2ba..f48ff0a 100644
--- a/callouts/nm-dispatcher-action.c
+++ b/callouts/nm-dispatcher-action.c
@@ -31,6 +31,7 @@
 #include <arpa/inet.h>
 
 #include <glib.h>
+#include <glib-unix.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
@@ -597,27 +598,15 @@ logging_shutdown (void)
 	closelog ();
 }
 
-static void
-signal_handler (int signo)
+static gboolean
+signal_handler (gpointer user_data)
 {
-	if (signo == SIGINT || signo == SIGTERM) {
-		g_message ("Caught signal %d, shutting down...", signo);
-		g_main_loop_quit (loop);
-	}
-}
+	int signo = GPOINTER_TO_INT (user_data);
 
-static void
-setup_signals (void)
-{
-	struct sigaction action;
-	sigset_t mask;
-
-	sigemptyset (&mask);
-	action.sa_handler = signal_handler;
-	action.sa_mask = mask;
-	action.sa_flags = 0;
-	sigaction (SIGTERM,  &action, NULL);
-	sigaction (SIGINT,  &action, NULL);
+	g_message ("Caught signal %d, shutting down...", signo);
+	g_main_loop_quit (loop);
+
+	return G_SOURCE_REMOVE;
 }
 
 int
@@ -648,7 +637,8 @@ main (int argc, char **argv)
 	g_option_context_free (opt_ctx);
 
 	g_type_init ();
-	setup_signals ();
+	g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM));
+	g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT));
 
 	if (!debug)
 		logging_setup ();
-- 
1.7.11.7