diff --git a/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch b/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch index c2f7806..4b71ddd 100644 --- a/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch +++ b/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch @@ -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. diff --git a/0001-local-display-factory-Stall-startup-until-main-graph.patch b/0001-local-display-factory-Stall-startup-until-main-graph.patch index 33a411c..d88da45 100644 --- a/0001-local-display-factory-Stall-startup-until-main-graph.patch +++ b/0001-local-display-factory-Stall-startup-until-main-graph.patch @@ -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 diff --git a/0002-local-display-factory-Fix-user-switching-with-legacy.patch b/0002-local-display-factory-Fix-user-switching-with-legacy.patch new file mode 100644 index 0000000..42465d5 --- /dev/null +++ b/0002-local-display-factory-Fix-user-switching-with-legacy.patch @@ -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 + diff --git a/gdm.spec b/gdm.spec index d8bf536..3a58c2a 100644 --- a/gdm.spec +++ b/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