Fix user switching with PreferredDisplayServer=legacy-xorg

Related: RHEL-29845
This commit is contained in:
Ray Strode 2024-05-01 14:57:51 -04:00
parent a45c5a9e16
commit ce05592878
4 changed files with 401 additions and 12 deletions

View File

@ -1,7 +1,7 @@
From bcab8852cf7249a2220f6c737f7bb8a17b99249a Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 27 Nov 2023 15:29:09 -0500
Subject: [PATCH] gdm-session: Force reuse vt mode for legacy Xorg mode
Subject: [PATCH 1/2] gdm-session: Force reuse vt mode for legacy Xorg mode
In the legacy Xorg mode, the X session and user session are
supposed to use the same VT.

View File

@ -1,4 +1,4 @@
From e5b3467412874d27c311253e3d5d7e65a61d12a4 Mon Sep 17 00:00:00 2001
From e88779b0785fe781608b10478ae092e8fd79ae0b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 1 Mar 2022 13:25:02 -0500
Subject: [PATCH 1/4] local-display-factory: Stall startup until main graphics
@ -27,13 +27,13 @@ up and running before proceeding to start a login screen.
Closes: https://gitlab.gnome.org/GNOME/gdm/-/issues/763
---
daemon/gdm-local-display-factory.c | 164 ++++++++++++++++++++++++++---
daemon/gdm-local-display-factory.c | 168 ++++++++++++++++++++++++++---
daemon/meson.build | 4 +
meson.build | 2 +
4 files changed, 159 insertions(+), 12 deletions(-)
3 files changed, 162 insertions(+), 12 deletions(-)
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index c00e1c47..0b1d3482 100644
index ca14c31f5..56be1d9db 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -1,100 +1,112 @@
@ -398,7 +398,7 @@ index c00e1c47..0b1d3482 100644
}
g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
@@ -1138,113 +1240,151 @@ on_vt_changed (GIOChannel *source,
@@ -1138,113 +1244,151 @@ on_vt_changed (GIOChannel *source,
if (factory->wait_to_finish_timeout_id != 0) {
g_debug ("GdmLocalDisplayFactory: deferring previous login screen clean up operation");
g_source_remove (factory->wait_to_finish_timeout_id);
@ -551,7 +551,7 @@ index c00e1c47..0b1d3482 100644
on_display_added (GdmDisplayStore *display_store,
const char *id,
diff --git a/daemon/meson.build b/daemon/meson.build
index 2e61b644..41f30abe 100644
index 2e61b6447..41f30abef 100644
--- a/daemon/meson.build
+++ b/daemon/meson.build
@@ -177,37 +177,41 @@ gdm_daemon_sources = files(
@ -597,7 +597,7 @@ index 2e61b644..41f30abe 100644
install_dir: get_option('sbindir')
)
diff --git a/meson.build b/meson.build
index 02d609dc..05d8da41 100644
index 02d609dc0..05d8da412 100644
--- a/meson.build
+++ b/meson.build
@@ -11,60 +11,61 @@ i18n = import('i18n')
@ -725,5 +725,5 @@ index 02d609dc..05d8da41 100644
subdir('chooser')
endif
--
2.34.1
2.40.0

View File

@ -0,0 +1,384 @@
From 510566699c480226b189215c6222f7e72979baf8 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 22 May 2024 14:05:20 -0400
Subject: [PATCH 2/2] local-display-factory: Fix user switching with legacy
xorg
legacy-xorg sessions currently fail to completely user switch.
This is because the wrong session types are attached to the generated
login screen display.
This commit refactors the code so the same session types are used for
user switching as are used for the initial login.
---
daemon/gdm-local-display-factory.c | 78 +++++++++++++++++++++---------
1 file changed, 54 insertions(+), 24 deletions(-)
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 7447b985a..4efbf0a6d 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -331,118 +331,131 @@ gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory,
if (display_server_enabled (factory, fallback_display_server))
g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server));
if (session_types_array->len == 0)
return NULL;
g_ptr_array_add (session_types_array, NULL);
session_types = g_strdupv ((char **) session_types_array->pdata);
return session_types;
}
static void
on_display_disposed (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
{
g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
}
static void
store_display (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
{
GdmDisplayStore *store;
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
gdm_display_store_add (store, display);
}
+static GdmDisplay *
+create_legacy_xorg_display (GdmLocalDisplayFactory *factory)
+{
+ guint32 display_number;
+ const char *session_types[] = { "x11", NULL };
+ GdmDisplay *display;
+
+ display_number = take_next_display_number (factory);
+
+ g_debug ("GdmLocalDisplayFactory: Creating legacy Xorg display at :%d", display_number);
+
+ display = gdm_legacy_display_new (display_number);
+ g_object_set (G_OBJECT (display),
+ "session-type", session_types[0],
+ "supported-session-types", session_types,
+ NULL);
+
+ return display;
+}
+
/*
Example:
dbus-send --system --dest=org.gnome.DisplayManager \
--type=method_call --print-reply --reply-timeout=2000 \
/org/gnome/DisplayManager/Manager \
org.gnome.DisplayManager.Manager.GetDisplays
*/
gboolean
gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory,
char **id,
GError **error)
{
gboolean ret;
GdmDisplay *display = NULL;
gboolean is_initial = FALSE;
const char *session_type;
g_autofree gchar *preferred_display_server = NULL;
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
ret = FALSE;
g_debug ("GdmLocalDisplayFactory: Creating transient display");
preferred_display_server = get_preferred_display_server (factory);
#ifdef ENABLE_USER_DISPLAY_SERVER
if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
g_strcmp0 (preferred_display_server, "xorg") == 0) {
g_auto(GStrv) session_types = NULL;
session_types = gdm_local_display_factory_get_session_types (factory, FALSE);
if (session_types == NULL) {
g_set_error_literal (error,
GDM_DISPLAY_ERROR,
GDM_DISPLAY_ERROR_GENERAL,
"Both Wayland and Xorg are unavailable");
return FALSE;
}
display = gdm_local_display_new ();
g_object_set (G_OBJECT (display),
"session-type", session_types[0],
"supported-session-types", session_types,
NULL);
is_initial = TRUE;
}
#endif
- if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
- if (display == NULL) {
- guint32 num;
-
- num = take_next_display_number (factory);
-
- display = gdm_legacy_display_new (num);
- }
- }
+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
+ display = create_legacy_xorg_display (factory);
if (display == NULL) {
g_set_error_literal (error,
GDM_DISPLAY_ERROR,
GDM_DISPLAY_ERROR_GENERAL,
"Invalid preferred display server configured");
return FALSE;
}
g_object_set (display,
"seat-id", "seat0",
"allow-timed-login", FALSE,
"is-initial", is_initial,
NULL);
store_display (factory, display);
if (! gdm_display_manage (display)) {
display = NULL;
goto out;
}
if (! gdm_display_get_id (display, id, NULL)) {
display = NULL;
goto out;
}
ret = TRUE;
out:
/* ref either held by store or not at all */
@@ -591,70 +604,87 @@ on_display_status_changed (GdmDisplay *display,
case GDM_DISPLAY_WAITING_TO_FINISH:
break;
default:
g_assert_not_reached ();
break;
}
g_free (seat_id);
g_free (session_type);
g_free (session_class);
}
static gboolean
lookup_by_seat_id (const char *id,
GdmDisplay *display,
gpointer user_data)
{
const char *looking_for = user_data;
char *current;
gboolean res;
g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
res = g_strcmp0 (current, looking_for) == 0;
g_free(current);
return res;
}
+static gboolean
+lookup_initial_display (const char *id,
+ GdmDisplay *display)
+{
+ gboolean is_initial = FALSE;
+ int status;
+
+ status = gdm_display_get_status (display);
+
+ if (status != GDM_DISPLAY_PREPARED && status != GDM_DISPLAY_MANAGED)
+ return FALSE;
+
+ g_object_get (G_OBJECT (display), "is-initial", &is_initial, NULL);
+
+ return is_initial;
+}
+
static gboolean
lookup_prepared_display_by_seat_id (const char *id,
GdmDisplay *display,
gpointer user_data)
{
int status;
status = gdm_display_get_status (display);
- if (status != GDM_DISPLAY_PREPARED)
+ if (status != GDM_DISPLAY_PREPARED && status != GDM_DISPLAY_MANAGED)
return FALSE;
return lookup_by_seat_id (id, display, user_data);
}
#ifdef HAVE_UDEV
static gboolean
udev_is_settled (GdmLocalDisplayFactory *factory)
{
g_autoptr (GUdevEnumerator) enumerator = NULL;
GList *devices;
GList *node;
gboolean is_settled = FALSE;
if (factory->seat0_has_platform_graphics) {
g_debug ("GdmLocalDisplayFactory: udev settled, platform graphics enabled.");
return TRUE;
}
if (factory->seat0_has_boot_up_graphics) {
g_debug ("GdmLocalDisplayFactory: udev settled, boot up graphics available.");
return TRUE;
}
if (factory->seat0_graphics_check_timed_out) {
g_debug ("GdmLocalDisplayFactory: udev timed out, proceeding anyway.");
return TRUE;
}
@@ -834,115 +864,115 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
/* It is not yet time to force X11 fallback. */
g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout.");
}
return;
}
g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev.");
seat_supports_graphics = TRUE;
wayland_enabled = FALSE;
g_strfreev (session_types);
session_types = g_strdupv ((char **) legacy_session_types);
} else {
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
}
}
if (!seat_supports_graphics)
return;
if (session_types != NULL)
g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
session_types[0], seat_id);
else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested",
seat_id);
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
- if (is_seat0)
- display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
- else
+ if (is_seat0) {
+ display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
+ if (display != NULL && g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
+ GdmDisplay *initial_display = NULL;
+
+ initial_display = gdm_display_store_find (store, lookup_initial_display, (gpointer) NULL);
+
+ if (initial_display == NULL)
+ display = NULL;
+ }
+ } else {
display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
+ }
/* Ensure we don't create the same display more than once */
if (display != NULL) {
g_debug ("GdmLocalDisplayFactory: display already created");
return;
}
/* If we already have a login window, switch to it */
if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
GdmDisplay *display;
display = gdm_display_store_find (store,
lookup_by_session_id,
(gpointer) login_session_id);
if (display != NULL &&
(gdm_display_get_status (display) == GDM_DISPLAY_MANAGED ||
gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) {
g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL);
g_debug ("GdmLocalDisplayFactory: session %s found, activating.",
login_session_id);
gdm_activate_session_by_id (factory->connection, seat_id, login_session_id);
return;
}
}
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
#ifdef ENABLE_USER_DISPLAY_SERVER
if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
g_strcmp0 (preferred_display_server, "xorg") == 0) {
if (is_seat0) {
display = gdm_local_display_new ();
g_object_set (G_OBJECT (display),
"session-type", session_types[0],
"supported-session-types", session_types,
NULL);
}
}
#endif
- if (display == NULL) {
- guint32 num;
-
- num = take_next_display_number (factory);
-
- display = gdm_legacy_display_new (num);
- g_object_set (G_OBJECT (display),
- "session-type", legacy_session_types[0],
- "supported-session-types", legacy_session_types,
- NULL);
- }
+ if (display == NULL)
+ display = create_legacy_xorg_display (factory);
g_object_set (display, "seat-id", seat_id, NULL);
g_object_set (display, "is-initial", is_seat0, NULL);
store_display (factory, display);
/* let store own the ref */
g_object_unref (display);
if (! gdm_display_manage (display)) {
gdm_display_unmanage (display);
}
return;
}
static void
delete_display (GdmLocalDisplayFactory *factory,
const char *seat_id) {
GdmDisplayStore *store;
g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id);
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id);
}
static gboolean
gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
--
2.40.0

View File

@ -11,7 +11,7 @@
Name: gdm
Epoch: 1
Version: 40.1
Release: 24%{?dist}
Release: 25%{?dist}
Summary: The GNOME Display Manager
License: GPLv2+
@ -43,8 +43,6 @@ Patch60001: 0001-session-settings-Fetch-session-from-user-even-if-use.patch
Patch70001: 0001-manager-Fix-btmp-record-accounting.patch
Patch80001: 0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
Patch80002: 0001-session-settings-Explicitly-cache-remote-users.patch
# Latest udev rules and support code
@ -53,6 +51,9 @@ Patch90002: 0002-common-Add-API-to-reload-settings-from-disk.patch
Patch90003: 0003-common-Reload-settings-when-graphics-initialize.patch
Patch90004: 0004-data-Use-latest-upstream-udev-rules.patch
Patch100001: 0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
Patch100002: 0002-local-display-factory-Fix-user-switching-with-legacy.patch
# Non-upstreamable workarounds
Patch66610001: 0001-data-reap-gdm-sessions-on-shutdown.patch
@ -355,6 +356,10 @@ dconf update || :
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
%changelog
* Wed May 01 2024 Ray Strode <rstrode@redhat.com> - 40.1-25
- Fix user switching with PreferredDisplayServer=legacy-xorg
Related: RHEL-29845
* Tue Jan 16 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 40.1-24
- Explicitly cache remote users
Resolves: RHEL-21791