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

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