gnome-session/SOURCES/0001-Fix-multiple-races.patch

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