diff options
author | Xiaoguang Wang <xwang@suse.com> | 2019-05-16 13:26:16 +0800 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2019-06-27 15:55:25 -0400 |
commit | 039e3422f4764dbdf105244a174da061d4e38344 (patch) | |
tree | ea13871b1d7923a3fc9274ef268511c8bab3b76c /daemon/session-worker-main.c | |
parent | 6a8f7bc50e8d03977b5b371f64921d1194b11ae3 (diff) | |
download | gdm-039e3422f4764dbdf105244a174da061d4e38344.tar.gz |
session-worker: kill user sessions when stopping gdm service
At the moment the session worker exits as soon as it gets SIGTERM.
That means it may fail to stop the user session (which only happens
in the orderly shutdown path).
This commit sets up a SIGTERM handler that integrates with and
quits the main loop after the session is started.
It still retains the _exit-on-SIGTERM behavior before the session
is started, to ensure a stuck pam module doesn't prevent the
process from dying.
Some small changes to commit by Ray Strode.
Closes #400
Diffstat (limited to 'daemon/session-worker-main.c')
-rw-r--r-- | daemon/session-worker-main.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/daemon/session-worker-main.c b/daemon/session-worker-main.c index 4a3a8ebb..d96844d2 100644 --- a/daemon/session-worker-main.c +++ b/daemon/session-worker-main.c @@ -64,6 +64,31 @@ is_debug_set (void) return debug; } +static gboolean +on_shutdown_signal_cb (gpointer user_data) +{ + GMainLoop *mainloop = user_data; + + g_main_loop_quit (mainloop); + + return FALSE; +} + +static void +on_state_changed (GdmSessionWorker *worker, + GParamSpec *pspec, + GMainLoop *main_loop) +{ + GdmSessionWorkerState state; + + g_object_get (G_OBJECT (worker), "state", &state, NULL); + + if (state != GDM_SESSION_WORKER_STATE_SESSION_STARTED) + return; + + g_unix_signal_add (SIGTERM, on_shutdown_signal_cb, main_loop); +} + static void on_sigterm_cb (int signal_number) { @@ -124,11 +149,19 @@ main (int argc, main_loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (G_OBJECT (worker), + "notify::state", + G_CALLBACK (on_state_changed), + main_loop); + g_unix_signal_add (SIGUSR1, on_sigusr1_cb, NULL); g_main_loop_run (main_loop); if (worker != NULL) { + g_signal_handlers_disconnect_by_func (worker, + G_CALLBACK (on_state_changed), + main_loop); g_object_unref (worker); } |