import gdm-40.0-16.el8

This commit is contained in:
CentOS Sources 2021-09-22 10:19:20 +00:00 committed by root
parent 7f1a4ea61e
commit 7e699ea069
3 changed files with 460 additions and 3 deletions

View File

@ -0,0 +1,325 @@
From d8fd8d4d6ff6a119f6bd27eb07316384c4776d12 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 15 Sep 2021 11:23:17 -0400
Subject: [PATCH] local-display-factory: Don't try to respawn displays on
shutdown
At the moment in the shutdown path we may try to respawn displays
that just got killed.
The respawning happens when things are half torn down leading to
crashes.
This commit makes sure we turn off the respawn logic in the shutdown
path.
---
daemon/gdm-local-display-factory.c | 11 ++++++++++-
daemon/gdm-manager.c | 2 ++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 11dcda2c..a0884893 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -46,60 +46,62 @@
#define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory"
#define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory"
#define MAX_DISPLAY_FAILURES 5
#define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */
#define SEAT0_GRAPHICS_CHECK_TIMEOUT 10 /* seconds */
struct _GdmLocalDisplayFactory
{
GdmDisplayFactory parent;
GdmDBusLocalDisplayFactory *skeleton;
GDBusConnection *connection;
GHashTable *used_display_numbers;
/* FIXME: this needs to be per seat? */
guint num_failures;
guint seat_new_id;
guint seat_removed_id;
guint seat_properties_changed_id;
gboolean seat0_graphics_check_timed_out;
guint seat0_graphics_check_timeout_id;
#if defined(ENABLE_USER_DISPLAY_SERVER)
unsigned int active_vt;
guint active_vt_watch_id;
guint wait_to_finish_timeout_id;
#endif
+
+ gboolean is_started;
};
enum {
PROP_0,
};
static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass);
static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory);
static void gdm_local_display_factory_finalize (GObject *object);
static void ensure_display_for_seat (GdmLocalDisplayFactory *factory,
const char *seat_id);
static void on_display_status_changed (GdmDisplay *display,
GParamSpec *arg1,
GdmLocalDisplayFactory *factory);
static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory);
static gpointer local_display_factory_object = NULL;
static gboolean lookup_by_session_id (const char *id,
GdmDisplay *display,
gpointer user_data);
G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
GQuark
gdm_local_display_factory_error_quark (void)
{
static GQuark ret = 0;
if (ret == 0) {
@@ -478,60 +480,64 @@ on_session_registered_cb (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
GdmDisplay *display = GDM_DISPLAY (gobject);
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data);
gboolean registered;
g_object_get (display, "session-registered", &registered, NULL);
if (!registered)
return;
g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill");
finish_waiting_displays_on_seat (factory, "seat0");
}
static void
on_display_status_changed (GdmDisplay *display,
GParamSpec *arg1,
GdmLocalDisplayFactory *factory)
{
int status;
int num;
char *seat_id = NULL;
char *session_type = NULL;
char *session_class = NULL;
gboolean is_initial = TRUE;
gboolean is_local = TRUE;
+
+ if (!factory->is_started)
+ return;
+
num = -1;
gdm_display_get_x11_display_number (display, &num, NULL);
g_object_get (display,
"seat-id", &seat_id,
"is-initial", &is_initial,
"is-local", &is_local,
"session-type", &session_type,
"session-class", &session_class,
NULL);
status = gdm_display_get_status (display);
g_debug ("GdmLocalDisplayFactory: display status changed: %d", status);
switch (status) {
case GDM_DISPLAY_FINISHED:
/* remove the display number from factory->used_display_numbers
so that it may be reused */
if (num != -1) {
g_hash_table_remove (factory->used_display_numbers, GUINT_TO_POINTER (num));
}
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
/* if this is a local display, do a full resync. Only
* seats without displays will get created anyway. This
* ensures we get a new login screen when the user logs out,
* if there isn't one.
*/
if (is_local && g_strcmp0 (session_class, "greeter") != 0) {
/* reset num failures */
@@ -1250,99 +1256,102 @@ on_display_added (GdmDisplayStore *display_store,
display = gdm_display_store_lookup (display_store, id);
if (display != NULL) {
g_signal_connect_object (display, "notify::status",
G_CALLBACK (on_display_status_changed),
factory,
0);
g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
}
}
static void
on_display_removed (GdmDisplayStore *display_store,
GdmDisplay *display,
GdmLocalDisplayFactory *factory)
{
g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory);
g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
}
static gboolean
gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
{
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
GdmDisplayStore *store;
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+ factory->is_started = TRUE;
+
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
g_signal_connect_object (G_OBJECT (store),
"display-added",
G_CALLBACK (on_display_added),
factory,
0);
g_signal_connect_object (G_OBJECT (store),
"display-removed",
G_CALLBACK (on_display_removed),
factory,
0);
gdm_local_display_factory_start_monitor (factory);
return gdm_local_display_factory_sync_seats (factory);
}
static gboolean
gdm_local_display_factory_stop (GdmDisplayFactory *base_factory)
{
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
GdmDisplayStore *store;
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
gdm_local_display_factory_stop_monitor (factory);
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
g_signal_handlers_disconnect_by_func (G_OBJECT (store),
G_CALLBACK (on_display_added),
factory);
g_signal_handlers_disconnect_by_func (G_OBJECT (store),
G_CALLBACK (on_display_removed),
factory);
-
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
+ factory->is_started = FALSE;
+
return TRUE;
}
static void
gdm_local_display_factory_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gdm_local_display_factory_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index b3d0a2b5..4b62b8b1 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -2774,60 +2774,62 @@ unexport_display (const char *id,
GdmDisplay *display,
GdmManager *manager)
{
if (!g_dbus_connection_is_closed (manager->priv->connection))
g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
}
static void
finish_display (const char *id,
GdmDisplay *display,
GdmManager *manager)
{
gdm_display_stop_greeter_session (display);
if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
gdm_display_unmanage (display);
gdm_display_finish (display);
}
static void
gdm_manager_dispose (GObject *object)
{
GdmManager *manager;
g_return_if_fail (object != NULL);
g_return_if_fail (GDM_IS_MANAGER (object));
manager = GDM_MANAGER (object);
g_return_if_fail (manager->priv != NULL);
+ gdm_manager_stop (manager);
+
g_clear_weak_pointer (&manager->priv->automatic_login_display);
#ifdef HAVE_LIBXDMCP
g_clear_object (&manager->priv->xdmcp_factory);
#endif
g_clear_object (&manager->priv->local_factory);
g_clear_pointer (&manager->priv->open_reauthentication_requests,
g_hash_table_unref);
g_clear_pointer (&manager->priv->transient_sessions,
g_hash_table_unref);
g_list_foreach (manager->priv->user_sessions,
(GFunc) gdm_session_close,
NULL);
g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
manager->priv->user_sessions = NULL;
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
G_CALLBACK (on_display_added),
manager);
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
G_CALLBACK (on_display_removed),
manager);
if (!g_dbus_connection_is_closed (manager->priv->connection)) {
gdm_display_store_foreach (manager->priv->display_store,
(GdmDisplayStoreFunc)unexport_display,
manager);
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
}
--
2.31.1

View File

@ -0,0 +1,122 @@
From e3a7ca44c0153ffa895786eabb020810b138eea2 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 14 Sep 2021 11:00:33 -0400
Subject: [PATCH 3/3] xdmcp-display-factory: Set supported session types for
XDMCP displays
The lower levels of GDM now expect the session types supported by a
display to be specified up front.
This commit makes sure XDMCP displays do that.
---
daemon/gdm-xdmcp-display-factory.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c
index ce8f026e1..558458f1c 100644
--- a/daemon/gdm-xdmcp-display-factory.c
+++ b/daemon/gdm-xdmcp-display-factory.c
@@ -2104,94 +2104,100 @@ on_display_status_changed (GdmDisplay *display,
break;
case GDM_DISPLAY_MANAGED:
if (session != NULL) {
g_signal_connect_object (G_OBJECT (session),
"client-disconnected",
G_CALLBACK (on_client_disconnected),
display, G_CONNECT_SWAPPED);
g_signal_connect_object (G_OBJECT (session),
"disconnected",
G_CALLBACK (on_client_disconnected),
display, G_CONNECT_SWAPPED);
}
break;
default:
g_assert_not_reached ();
break;
}
g_clear_object (&launch_environment);
}
static GdmDisplay *
gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory,
const char *hostname,
GdmAddress *address,
int displaynum)
{
GdmDisplay *display;
GdmDisplayStore *store;
gboolean use_chooser;
+ const char *session_types[] = { "x11", NULL };
g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d",
hostname ? hostname : "(null)", displaynum);
use_chooser = FALSE;
if (factory->honor_indirect) {
IndirectClient *ic;
ic = indirect_client_lookup (factory, address);
/* This was an indirect thingie and nothing was yet chosen,
* use a chooser */
if (ic != NULL && ic->chosen_address == NULL) {
use_chooser = TRUE;
}
}
if (use_chooser) {
display = gdm_xdmcp_chooser_display_new (hostname,
displaynum,
address,
get_next_session_serial (factory));
g_signal_connect (display, "hostname-selected", G_CALLBACK (on_hostname_selected), factory);
} else {
display = gdm_xdmcp_display_new (hostname,
displaynum,
address,
get_next_session_serial (factory));
}
if (display == NULL) {
goto out;
}
+ g_object_set (G_OBJECT (display),
+ "session-type", session_types[0],
+ "supported-session-types", session_types,
+ NULL);
+
if (! gdm_display_prepare (display)) {
gdm_display_unmanage (display);
g_object_unref (display);
display = NULL;
goto out;
}
g_signal_connect_after (display,
"notify::status",
G_CALLBACK (on_display_status_changed),
factory);
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
gdm_display_store_add (store, display);
factory->num_pending_sessions++;
out:
return display;
}
static void
gdm_xdmcp_send_accept (GdmXdmcpDisplayFactory *factory,
GdmAddress *address,
CARD32 session_id,
ARRAY8Ptr authentication_name,
ARRAY8Ptr authentication_data,
ARRAY8Ptr authorization_name,
ARRAY8Ptr authorization_data)
{
--
2.31.1

View File

@ -12,7 +12,7 @@
Name: gdm
Epoch: 1
Version: 40.0
Release: 13%{?dist}
Release: 16%{?dist}
Summary: The GNOME Display Manager
License: GPLv2+
@ -23,6 +23,7 @@ Source1: org.gnome.login-screen.gschema.override
# Lets customers using vendor nvidia driver pick wayland sessions from the login screen
Patch10001: 0001-local-display-factory-Provide-more-flexibility-for-c.patch
Patch10002: 0002-libgdm-Sort-session-list.patch
Patch10003: 0003-xdmcp-display-factory-Set-supported-session-types-fo.patch
# Race fix
Patch40001: 0001-display-Handle-failure-before-display-registration.patch
@ -38,6 +39,9 @@ Patch60003: 0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch
# Upstream change that's moderately risky so revert it
Patch70001: 0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch
# Crash fix
Patch80001: 0001-local-display-factory-Don-t-try-to-respawn-displays-.patch
# Non-upstreamable workarounds
Patch66610001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch
Patch66620001: 0001-data-reap-gdm-sessions-on-shutdown.patch
@ -360,10 +364,16 @@ fi
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
%changelog
* Wed Sep 01 2021 Ray Strode <rstrode@redhat.com> - 40.0-13
* Wed Sep 15 2021 Ray Strode <rstrode@redhat.com> - 40.0-16
- Fix XDMCP
Resolves: #2005011
- Fix crash at shutdown
Related: #2005011
* Wed Sep 01 2021 Ray Strode <rstrode@redhat.com> - 40.0-14
- Disable Wayland on HyperV
- Fix Xorg fallback
Related: #1998989
Related: #2000904
* Thu Aug 19 2021 Ray Strode <rstrode@redhat.com> - 40.0-12
- Redisable on server chips since rebase