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

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