diff options
author | Thomas Haller <thaller@redhat.com> | 2013-11-18 23:37:58 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2013-11-19 00:20:12 +0100 |
commit | 073cc01f52f8b2b6d5b20c63814dc1ed00699028 (patch) | |
tree | c60c868e2bed0a78b598d758950219dda017f46f | |
parent | fbcabeb7f72b710a790ca8617f7406a1ba7cf5be (diff) | |
download | NetworkManager-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.c | 30 |
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 (); |