Blame SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch

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