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

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