251 lines
9.1 KiB
Diff
251 lines
9.1 KiB
Diff
From 844c7bec9d5e27c1bef1399ca3116a65f3b80848 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 21 Feb 2024 10:01:00 -0500
|
|
Subject: [PATCH 1/4] main: handle SIGHUP like SIGINT and SIGTERM from leader
|
|
|
|
loginctl terminate-session actually sends a SIGHUP before
|
|
SIGTERM. We should handle that the same way as SIGTERM.
|
|
|
|
Part-of<https://gitlab.gnome.org/GNOME/gnome-session/-/merge_requests/105>
|
|
---
|
|
gnome-session/main.c | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/gnome-session/main.c b/gnome-session/main.c
|
|
index a460a849..107886d1 100644
|
|
--- a/gnome-session/main.c
|
|
+++ b/gnome-session/main.c
|
|
@@ -376,6 +376,7 @@ systemd_leader_run(void)
|
|
g_warning ("Unable to watch systemd session: Opening FIFO failed with %m");
|
|
}
|
|
|
|
+ g_unix_signal_add (SIGHUP, leader_term_or_int_signal_cb, GINT_TO_POINTER (fifo_fd));
|
|
g_unix_signal_add (SIGTERM, leader_term_or_int_signal_cb, GINT_TO_POINTER (fifo_fd));
|
|
g_unix_signal_add (SIGINT, leader_term_or_int_signal_cb, GINT_TO_POINTER (fifo_fd));
|
|
|
|
--
|
|
2.49.0
|
|
|
|
|
|
From e5fa3bbde2194b8e6964bd93816d23a0e60a191f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 21 Feb 2024 10:01:54 -0500
|
|
Subject: [PATCH 2/4] gnome-session-ctl: Fix bitwise logic error
|
|
|
|
The code confused & and |. This commit fixes that.
|
|
|
|
Part-of<https://gitlab.gnome.org/GNOME/gnome-session/-/merge_requests/105>
|
|
---
|
|
tools/gnome-session-ctl.c | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tools/gnome-session-ctl.c b/tools/gnome-session-ctl.c
|
|
index eb9d6b5f..bf4d1130 100644
|
|
--- a/tools/gnome-session-ctl.c
|
|
+++ b/tools/gnome-session-ctl.c
|
|
@@ -164,11 +164,13 @@ leader_fifo_io_cb (gint fd,
|
|
|
|
sd_notify (0, "STOPPING=1");
|
|
|
|
- if (condition | G_IO_IN) {
|
|
+ if (condition & G_IO_IN) {
|
|
char buf[1];
|
|
read (data->fifo_fd, buf, 1);
|
|
+ g_main_loop_quit (data->loop);
|
|
}
|
|
- if (condition | G_IO_HUP) {
|
|
+
|
|
+ if (condition & G_IO_HUP) {
|
|
g_main_loop_quit (data->loop);
|
|
}
|
|
|
|
--
|
|
2.49.0
|
|
|
|
|
|
From 42aeb5e2ab2160b0f712809ac6c3bc53f862ecab Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 21 Feb 2024 10:19:15 -0500
|
|
Subject: [PATCH 3/4] main: Don't exit until graphical-session.target is gone
|
|
|
|
The gnome-session leader process exits when gnome-session-ctl exits.
|
|
|
|
In order for shutdown to happen in an orderly fashion, we need to make
|
|
sure it hangs on a little longer until the graphical-session-pre.target
|
|
finishes stopping.
|
|
|
|
This commit adds some code to do that.
|
|
|
|
Part-of<https://gitlab.gnome.org/GNOME/gnome-session/-/merge_requests/105>
|
|
---
|
|
gnome-session/main.c | 103 ++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 102 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/gnome-session/main.c b/gnome-session/main.c
|
|
index 107886d1..4e54d768 100644
|
|
--- a/gnome-session/main.c
|
|
+++ b/gnome-session/main.c
|
|
@@ -285,6 +285,8 @@ leader_term_or_int_signal_cb (gpointer data)
|
|
{
|
|
gint fifo_fd = GPOINTER_TO_INT (data);
|
|
|
|
+ g_debug ("Session termination requested");
|
|
+
|
|
/* Start a shutdown explicitly. */
|
|
gsm_util_start_systemd_unit ("gnome-session-shutdown.target", "replace-irreversibly", NULL);
|
|
|
|
@@ -305,6 +307,105 @@ leader_term_or_int_signal_cb (gpointer data)
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
+static void
|
|
+graphical_session_pre_state_changed_cb (GDBusProxy *proxy,
|
|
+ GVariant *changed_properties)
|
|
+{
|
|
+ const char *state;
|
|
+ g_autoptr (GVariant) value = NULL;
|
|
+
|
|
+ value = g_variant_lookup_value (changed_properties, "ActiveState", NULL);
|
|
+
|
|
+ if (value == NULL)
|
|
+ return;
|
|
+
|
|
+ g_variant_get (value, "&s", &state);
|
|
+ if (g_strcmp0 (state, "inactive") == 0) {
|
|
+ g_debug ("Session services now inactive, quitting");
|
|
+ gsm_quit ();
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+monitor_hangup_cb (int fd,
|
|
+ GIOCondition condition,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ g_autoptr (GDBusConnection) connection = NULL;
|
|
+ g_autoptr (GVariant) unit = NULL;
|
|
+ g_autoptr (GVariant) value = NULL;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+ GDBusProxy *proxy = NULL;
|
|
+ const char *unit_path = NULL;
|
|
+
|
|
+ g_debug ("Services have begun stopping, waiting for them to finish stopping");
|
|
+
|
|
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
|
+
|
|
+ if (!connection) {
|
|
+ g_debug ("Could not get bus connection: %s", error->message);
|
|
+ gsm_quit ();
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+
|
|
+ unit = g_dbus_connection_call_sync (connection,
|
|
+ "org.freedesktop.systemd1",
|
|
+ "/org/freedesktop/systemd1",
|
|
+ "org.freedesktop.systemd1.Manager",
|
|
+ "GetUnit",
|
|
+ g_variant_new ("(s)", "graphical-session-pre.target"),
|
|
+ G_VARIANT_TYPE ("(o)"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ &error);
|
|
+ if (!unit) {
|
|
+ g_debug ("Could not get unit for graphical-session-pre.target: %s", error->message);
|
|
+ gsm_quit ();
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+
|
|
+ g_variant_get (unit, "(&o)", &unit_path);
|
|
+
|
|
+ proxy = g_dbus_proxy_new_sync (connection,
|
|
+ G_DBUS_PROXY_FLAGS_NONE,
|
|
+ NULL,
|
|
+ "org.freedesktop.systemd1",
|
|
+ unit_path,
|
|
+ "org.freedesktop.systemd1.Unit",
|
|
+ NULL,
|
|
+ &error);
|
|
+ if (!proxy) {
|
|
+ g_debug ("Could not get proxy for graphical-session-pre.target unit: %s", error->message);
|
|
+ gsm_quit ();
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+
|
|
+ value = g_dbus_proxy_get_cached_property (proxy, "ActiveState");
|
|
+
|
|
+ if (value) {
|
|
+ const char *state;
|
|
+
|
|
+ g_variant_get (value, "&s", &state);
|
|
+
|
|
+ if (g_strcmp0 (state, "inactive") == 0) {
|
|
+ g_debug ("State of graphical-session-pre.target unit already inactive quitting");
|
|
+ gsm_quit ();
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+ g_debug ("State of graphical-session-pre.target unit is '%s', waiting for it to go inactive", state);
|
|
+ } else {
|
|
+ g_debug ("State of graphical-session-pre.target unit is unknown, waiting for it to go inactive");
|
|
+ }
|
|
+ g_signal_connect (proxy,
|
|
+ "g-properties-changed",
|
|
+ G_CALLBACK (graphical_session_pre_state_changed_cb),
|
|
+ NULL);
|
|
+
|
|
+ return G_SOURCE_REMOVE;
|
|
+}
|
|
+
|
|
/**
|
|
* systemd_leader_run:
|
|
*
|
|
@@ -370,7 +471,7 @@ systemd_leader_run(void)
|
|
close (fifo_fd);
|
|
fifo_fd = -1;
|
|
} else {
|
|
- g_unix_fd_add (fifo_fd, G_IO_HUP, (GUnixFDSourceFunc) gsm_quit, NULL);
|
|
+ g_unix_fd_add (fifo_fd, G_IO_HUP, (GUnixFDSourceFunc) monitor_hangup_cb, NULL);
|
|
}
|
|
} else {
|
|
g_warning ("Unable to watch systemd session: Opening FIFO failed with %m");
|
|
--
|
|
2.49.0
|
|
|
|
|
|
From 3c9554ceb3a9fd71f5a32fb0212f4096d05520a7 Mon Sep 17 00:00:00 2001
|
|
From: Joan Torres <joantolo@redhat.com>
|
|
Date: Thu, 8 May 2025 21:18:18 +0200
|
|
Subject: [PATCH 4/4] manager: Fix race on clients disconnecting
|
|
|
|
A client could be disconnected by an external source on
|
|
QUERY_END_SESSION phase.
|
|
Processing its disconnection can trigger a phase change,
|
|
if the client hasn't been removed from the store by the time this new
|
|
phase is processed, it will still be taken into account, resulting in a
|
|
race condition.
|
|
|
|
Ensure the client is removed from store before handling its disconnection
|
|
which might process a new phase.
|
|
---
|
|
gnome-session/gsm-manager.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
|
|
index 1b88b266..73b9ac54 100644
|
|
--- a/gnome-session/gsm-manager.c
|
|
+++ b/gnome-session/gsm-manager.c
|
|
@@ -1823,8 +1823,8 @@ on_client_disconnected (GsmClient *client,
|
|
GsmManager *manager)
|
|
{
|
|
g_debug ("GsmManager: disconnect client");
|
|
- _disconnect_client (manager, client);
|
|
gsm_store_remove (manager->priv->clients, gsm_client_peek_id (client));
|
|
+ _disconnect_client (manager, client);
|
|
if (manager->priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION
|
|
&& gsm_store_size (manager->priv->clients) == 0) {
|
|
g_debug ("GsmManager: last client disconnected - exiting");
|
|
--
|
|
2.49.0
|
|
|