summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2013-11-18 23:37:58 +0100
committerThomas Haller <thaller@redhat.com>2013-11-19 00:20:12 +0100
commit073cc01f52f8b2b6d5b20c63814dc1ed00699028 (patch)
treec60c868e2bed0a78b598d758950219dda017f46f
parentfbcabeb7f72b710a790ca8617f7406a1ba7cf5be (diff)
downloadNetworkManager-073cc01f52f8b2b6d5b20c63814dc1ed00699028.tar.gz
dispatcher: fix crash while logging from signal handler
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>
-rw-r--r--callouts/nm-dispatcher-action.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/callouts/nm-dispatcher-action.c b/callouts/nm-dispatcher-action.c
index 397f2bac3e..f48ff0a23a 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 ();