Fix user switching with PreferredDisplayServer=legacy-xorg
Related: RHEL-29845
This commit is contained in:
parent
a45c5a9e16
commit
ce05592878
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
384
0002-local-display-factory-Fix-user-switching-with-legacy.patch
Normal file
384
0002-local-display-factory-Fix-user-switching-with-legacy.patch
Normal 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", ¤t, 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
|
||||
|
11
gdm.spec
11
gdm.spec
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user