to properly terminate plymouth. Resolves: https://redhat.atlassian.net/browse/RHEL-178659
438 lines
20 KiB
Diff
438 lines
20 KiB
Diff
From ecc9ab663cd698faa2eef596789f43df50976534 Mon Sep 17 00:00:00 2001
|
|
From: Joan Torres Lopez <joantolo@redhat.com>
|
|
Date: Tue, 3 Feb 2026 14:29:18 +0100
|
|
Subject: [PATCH 1/2] manager: Add RegisterDisplay again
|
|
|
|
1. RegisterSession is used to record a session login. It should be
|
|
called when the new session is started.
|
|
2. RegisterDisplay is used to terminate pending greeters and plymouth
|
|
to reach graphical.target. It should be called once the new session
|
|
completes its graphics startup.
|
|
|
|
RegisterSession was trying to do both before new session startup was completed.
|
|
This had a potential issue: the new session is setting up while the greeter
|
|
session is tearing down leading to configuration conflicts.
|
|
|
|
Fixes: deeb4b8aba46e37a1f6dcb85252ed713183cb170 ("manager: Combine register
|
|
display with register session")
|
|
---
|
|
daemon/gdm-local-display-factory.c | 8 +------
|
|
daemon/gdm-manager.c | 38 +++++++++++++++++++++++++++---
|
|
daemon/gdm-manager.xml | 2 ++
|
|
3 files changed, 38 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
|
|
index ef2ff7c..789afe7 100644
|
|
--- a/daemon/gdm-local-display-factory.c
|
|
+++ b/daemon/gdm-local-display-factory.c
|
|
@@ -518,7 +518,6 @@ on_display_status_changed (GdmDisplay *display,
|
|
char *session_class = NULL;
|
|
gboolean is_initial = TRUE;
|
|
gboolean is_local = TRUE;
|
|
- gboolean registered = FALSE;
|
|
|
|
|
|
if (!factory->is_started)
|
|
@@ -584,11 +583,7 @@ on_display_status_changed (GdmDisplay *display,
|
|
break;
|
|
case GDM_DISPLAY_MANAGED:
|
|
#if defined(ENABLE_USER_DISPLAY_SERVER)
|
|
- g_object_get (display, "session-registered", ®istered, NULL);
|
|
- if (registered) {
|
|
- g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill");
|
|
- finish_waiting_displays_on_seat (factory, "seat0");
|
|
- }
|
|
+ finish_waiting_displays_on_seat (factory, "seat0");
|
|
#endif
|
|
break;
|
|
case GDM_DISPLAY_WAITING_TO_FINISH:
|
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
index 9af9de0..b67d2e5 100644
|
|
--- a/daemon/gdm-manager.c
|
|
+++ b/daemon/gdm-manager.c
|
|
@@ -746,6 +746,39 @@ find_user_session_for_display (GdmManager *self,
|
|
return NULL;
|
|
}
|
|
|
|
+static gboolean
|
|
+gdm_manager_handle_register_display (GdmDBusManager *manager,
|
|
+ GDBusMethodInvocation *invocation,
|
|
+ GVariant *details)
|
|
+{
|
|
+ GdmManager *self = GDM_MANAGER (manager);
|
|
+ const char *sender;
|
|
+ GDBusConnection *connection;
|
|
+ GdmDisplay *display = NULL;
|
|
+
|
|
+ sender = g_dbus_method_invocation_get_sender (invocation);
|
|
+ connection = g_dbus_method_invocation_get_connection (invocation);
|
|
+ get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
+
|
|
+ if (display == NULL) {
|
|
+ g_dbus_method_invocation_return_error_literal (invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_ACCESS_DENIED,
|
|
+ _("No display available"));
|
|
+
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ g_object_set (G_OBJECT (display),
|
|
+ "status", GDM_DISPLAY_MANAGED,
|
|
+ NULL);
|
|
+
|
|
+ gdm_dbus_manager_complete_register_display (GDM_DBUS_MANAGER (manager),
|
|
+ invocation);
|
|
+
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+}
|
|
+
|
|
static gboolean
|
|
gdm_manager_handle_register_session (GdmDBusManager *manager,
|
|
GDBusMethodInvocation *invocation,
|
|
@@ -774,7 +807,7 @@ gdm_manager_handle_register_session (GdmDBusManager *manager,
|
|
G_DBUS_ERROR_ACCESS_DENIED,
|
|
_("No display available"));
|
|
|
|
- return TRUE;
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
}
|
|
|
|
g_variant_iter_init (&iter, details);
|
|
@@ -808,14 +841,13 @@ gdm_manager_handle_register_session (GdmDBusManager *manager,
|
|
}
|
|
|
|
g_object_set (G_OBJECT (display),
|
|
- "status", GDM_DISPLAY_MANAGED,
|
|
"session-registered", TRUE,
|
|
NULL);
|
|
|
|
gdm_dbus_manager_complete_register_session (GDM_DBUS_MANAGER (manager),
|
|
invocation);
|
|
|
|
- return TRUE;
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -1264,6 +1296,7 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
|
|
static void
|
|
manager_interface_init (GdmDBusManagerIface *interface)
|
|
{
|
|
+ interface->handle_register_display = gdm_manager_handle_register_display;
|
|
interface->handle_register_session = gdm_manager_handle_register_session;
|
|
interface->handle_open_session = gdm_manager_handle_open_session;
|
|
interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
|
|
diff --git a/daemon/gdm-manager.xml b/daemon/gdm-manager.xml
|
|
index aba079a..92ef1d0 100644
|
|
--- a/daemon/gdm-manager.xml
|
|
+++ b/daemon/gdm-manager.xml
|
|
@@ -1,6 +1,9 @@
|
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
<node name="/org/gnome/DisplayManager/Manager">
|
|
<interface name="org.gnome.DisplayManager.Manager">
|
|
+ <method name="RegisterDisplay">
|
|
+ <arg name="details" direction="in" type="a{ss}"/>
|
|
+ </method>
|
|
<method name="RegisterSession">
|
|
<arg name="details" direction="in" type="a{sv}"/>
|
|
</method>
|
|
From d8e9406bfd6ebe3b395476ba0460f08d1db536c1 Mon Sep 17 00:00:00 2001
|
|
From: Joan Torres Lopez <joantolo@redhat.com>
|
|
Date: Tue, 3 Feb 2026 14:31:39 +0100
|
|
Subject: [PATCH 2/2] session: Call RegisterSession and RegisterDisplay from
|
|
session launchers
|
|
|
|
RegisterSession is called when the session starts to record the login.
|
|
RegisterDisplay is called after a delay to terminate pending greeters
|
|
and plymouth once graphics have settled.
|
|
|
|
This follows the workflow established in the previous commit where
|
|
RegisterSession and RegisterDisplay serve distinct purposes.
|
|
---
|
|
common/gdm-common.h | 2 +-
|
|
daemon/gdm-session.c | 4 +--
|
|
daemon/gdm-wayland-session.c | 63 ++++++++++++++++++++++--------------
|
|
daemon/gdm-x-session.c | 47 +++++++++++++++++----------
|
|
4 files changed, 71 insertions(+), 45 deletions(-)
|
|
|
|
diff --git a/common/gdm-common.h b/common/gdm-common.h
|
|
index ea012dc..96fda83 100644
|
|
--- a/common/gdm-common.h
|
|
+++ b/common/gdm-common.h
|
|
@@ -27,7 +27,7 @@
|
|
#include <pwd.h>
|
|
#include <errno.h>
|
|
|
|
-#define REGISTER_SESSION_TIMEOUT 10
|
|
+#define REGISTER_DISPLAY_TIMEOUT 10
|
|
|
|
#define VE_IGNORE_EINTR(expr) \
|
|
do { \
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index 9a332d7..6b37ab7 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -2930,7 +2930,7 @@ gdm_session_start_session (GdmSession *self,
|
|
gboolean allow_remote_connections = FALSE;
|
|
char *command;
|
|
char *program;
|
|
- gboolean register_session;
|
|
+ gboolean needs_registration;
|
|
|
|
g_return_if_fail (GDM_IS_SESSION (self));
|
|
g_return_if_fail (self->session_conversation == NULL);
|
|
@@ -2956,7 +2956,7 @@ gdm_session_start_session (GdmSession *self,
|
|
run_launcher = TRUE;
|
|
}
|
|
|
|
- register_session = !gdm_session_session_registers (self);
|
|
+ needs_registration = !gdm_session_session_registers (self);
|
|
|
|
if (self->selected_program == NULL) {
|
|
gboolean run_xsession_script;
|
|
@@ -2976,13 +2976,13 @@ gdm_session_start_session (GdmSession *self,
|
|
if (run_launcher) {
|
|
if (is_x11) {
|
|
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"",
|
|
- register_session ? "--register-session " : "",
|
|
+ needs_registration ? "--handle-registration " : "",
|
|
run_xsession_script? "--run-script " : "",
|
|
allow_remote_connections? "--allow-remote-connections " : "",
|
|
command);
|
|
} else {
|
|
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
|
|
- register_session ? "--register-session " : "",
|
|
+ needs_registration ? "--handle-registration " : "",
|
|
command);
|
|
}
|
|
} else if (run_xsession_script) {
|
|
@@ -3010,11 +3010,11 @@ gdm_session_start_session (GdmSession *self,
|
|
if (run_launcher) {
|
|
if (is_x11) {
|
|
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"",
|
|
- register_session ? "--register-session " : "",
|
|
+ needs_registration ? "--handle-registration " : "",
|
|
self->selected_program);
|
|
} else {
|
|
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"",
|
|
- register_session ? "--register-session " : "",
|
|
+ needs_registration ? "--handle-registration " : "",
|
|
self->selected_program);
|
|
}
|
|
} else {
|
|
diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
|
|
index d4d1edd..73d245c 100644
|
|
--- a/daemon/gdm-wayland-session.c
|
|
+++ b/daemon/gdm-wayland-session.c
|
|
@@ -54,7 +54,7 @@ typedef struct
|
|
char *session_command;
|
|
int session_exit_status;
|
|
|
|
- guint register_session_id;
|
|
+ guint register_display_id;
|
|
|
|
GMainLoop *main_loop;
|
|
|
|
@@ -404,6 +404,22 @@ wait_on_subprocesses (State *state)
|
|
}
|
|
}
|
|
|
|
+static gboolean
|
|
+register_session (State *state)
|
|
+{
|
|
+ g_autoptr(GError) error = NULL;
|
|
+
|
|
+ if (!gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
|
|
+ g_variant_new ("a{sv}", NULL),
|
|
+ state->cancellable,
|
|
+ &error)) {
|
|
+ g_warning ("Could not register session: %s", error->message);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
static void
|
|
init_state (State **state)
|
|
{
|
|
@@ -422,7 +438,7 @@ clear_state (State **out_state)
|
|
g_clear_object (&state->session_subprocess);
|
|
g_clear_pointer (&state->environment, g_strfreev);
|
|
g_clear_pointer (&state->main_loop, g_main_loop_unref);
|
|
- g_clear_handle_id (&state->register_session_id, g_source_remove);
|
|
+ g_clear_handle_id (&state->register_display_id, g_source_remove);
|
|
*out_state = NULL;
|
|
}
|
|
|
|
@@ -439,22 +455,16 @@ on_sigterm (State *state)
|
|
}
|
|
|
|
static gboolean
|
|
-register_session_timeout_cb (gpointer user_data)
|
|
+register_display_timeout_cb (gpointer user_data)
|
|
{
|
|
- State *state;
|
|
- GError *error = NULL;
|
|
-
|
|
- state = (State *) user_data;
|
|
+ State *state = (State *) user_data;
|
|
+ g_autoptr(GError) error = NULL;
|
|
|
|
- gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
|
|
- g_variant_new ("a{sv}", NULL),
|
|
- state->cancellable,
|
|
- &error);
|
|
-
|
|
- if (error != NULL) {
|
|
- g_warning ("Could not register session: %s", error->message);
|
|
- g_error_free (error);
|
|
- }
|
|
+ if (!gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy,
|
|
+ g_variant_new ("a{ss}", NULL),
|
|
+ state->cancellable,
|
|
+ &error))
|
|
+ g_warning ("Could not display session: %s", error->message);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
@@ -491,10 +501,10 @@ main (int argc,
|
|
gboolean debug = FALSE;
|
|
gboolean ret;
|
|
int exit_status = EX_OK;
|
|
- static gboolean register_session = FALSE;
|
|
+ static gboolean handle_registration = FALSE;
|
|
|
|
static GOptionEntry entries [] = {
|
|
- { "register-session", 0, 0, G_OPTION_ARG_NONE, ®ister_session, "Register session after a delay", NULL },
|
|
+ { "handle-registration", 0, 0, G_OPTION_ARG_NONE, &handle_registration, "Handle session and display registration (fallback for non-GNOME sessions)", NULL },
|
|
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
|
|
{ NULL }
|
|
};
|
|
@@ -561,10 +571,16 @@ main (int argc,
|
|
if (!connect_to_display_manager (state))
|
|
goto out;
|
|
|
|
- if (register_session) {
|
|
- g_debug ("gdm-wayland-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT);
|
|
- state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT,
|
|
- register_session_timeout_cb,
|
|
+ if (handle_registration) {
|
|
+ if (!register_session (state)) {
|
|
+ g_printerr ("Unable to register session with display manager\n");
|
|
+ exit_status = EX_SOFTWARE;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_debug ("gdm-wayland-session: Will register display in %d seconds", REGISTER_DISPLAY_TIMEOUT);
|
|
+ state->register_display_id = g_timeout_add_seconds (REGISTER_DISPLAY_TIMEOUT,
|
|
+ register_display_timeout_cb,
|
|
state);
|
|
} else {
|
|
g_debug ("gdm-wayland-session: Session will register itself");
|
|
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
|
|
index 36b3975..be65f07 100644
|
|
--- a/daemon/gdm-x-session.c
|
|
+++ b/daemon/gdm-x-session.c
|
|
@@ -60,7 +60,7 @@ typedef struct
|
|
char *session_command;
|
|
int session_exit_status;
|
|
|
|
- guint register_session_id;
|
|
+ guint register_display_id;
|
|
|
|
GMainLoop *main_loop;
|
|
|
|
@@ -778,7 +778,7 @@ clear_state (State **out_state)
|
|
g_clear_pointer (&state->auth_file, g_free);
|
|
g_clear_pointer (&state->display_name, g_free);
|
|
g_clear_pointer (&state->main_loop, g_main_loop_unref);
|
|
- g_clear_handle_id (&state->register_session_id, g_source_remove);
|
|
+ g_clear_handle_id (&state->register_display_id, g_source_remove);
|
|
*out_state = NULL;
|
|
}
|
|
|
|
@@ -795,24 +795,34 @@ on_sigterm (State *state)
|
|
}
|
|
|
|
static gboolean
|
|
-register_session_timeout_cb (gpointer user_data)
|
|
+register_display_timeout_cb (gpointer user_data)
|
|
{
|
|
- State *state;
|
|
- GError *error = NULL;
|
|
+ State *state = (State *) user_data;
|
|
+ g_autoptr(GError) error = NULL;
|
|
|
|
- state = (State *) user_data;
|
|
+ if (!gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy,
|
|
+ g_variant_new ("a{ss}", NULL),
|
|
+ state->cancellable,
|
|
+ &error))
|
|
+ g_warning ("Could not register display: %s", error->message);
|
|
|
|
- gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
|
|
- g_variant_new ("a{sv}", NULL),
|
|
- state->cancellable,
|
|
- &error);
|
|
+ return G_SOURCE_REMOVE;
|
|
+}
|
|
|
|
- if (error != NULL) {
|
|
+static gboolean
|
|
+register_session (State *state)
|
|
+{
|
|
+ g_autoptr(GError) error = NULL;
|
|
+
|
|
+ if (!gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
|
|
+ g_variant_new ("a{sv}", NULL),
|
|
+ state->cancellable,
|
|
+ &error)) {
|
|
g_warning ("Could not register session: %s", error->message);
|
|
- g_error_free (error);
|
|
+ return FALSE;
|
|
}
|
|
|
|
- return G_SOURCE_REMOVE;
|
|
+ return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -849,12 +859,12 @@ main (int argc,
|
|
gboolean debug = FALSE;
|
|
gboolean ret;
|
|
int exit_status = EX_OK;
|
|
- static gboolean register_session = FALSE;
|
|
+ static gboolean handle_registration = FALSE;
|
|
|
|
static GOptionEntry entries [] = {
|
|
{ "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL },
|
|
{ "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL },
|
|
- { "register-session", 0, 0, G_OPTION_ARG_NONE, ®ister_session, "Register session after a delay", NULL },
|
|
+ { "handle-registration", 0, 0, G_OPTION_ARG_NONE, &handle_registration, "Handle session and display registration (fallback for non-GNOME sessions)", NULL },
|
|
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
|
|
{ NULL }
|
|
};
|
|
@@ -937,10 +947,16 @@ main (int argc,
|
|
goto out;
|
|
}
|
|
|
|
- if (register_session) {
|
|
- g_debug ("gdm-x-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT);
|
|
- state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT,
|
|
- register_session_timeout_cb,
|
|
+ if (handle_registration) {
|
|
+ if (!register_session (state)) {
|
|
+ g_printerr ("Unable to register session with display manager\n");
|
|
+ exit_status = EX_SOFTWARE;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_debug ("gdm-x-session: Will register display in %d seconds", REGISTER_DISPLAY_TIMEOUT);
|
|
+ state->register_display_id = g_timeout_add_seconds (REGISTER_DISPLAY_TIMEOUT,
|
|
+ register_display_timeout_cb,
|
|
state);
|
|
} else {
|
|
g_debug ("gdm-x-session: Session will register itself");
|