Blame SOURCES/0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch

a1b388
From abd8e1ef71d093a3ab5c110aea5fa2012d59d5e2 Mon Sep 17 00:00:00 2001
a1b388
From: Ray Strode <rstrode@redhat.com>
a1b388
Date: Tue, 14 Aug 2018 10:21:17 -0400
a1b388
Subject: [PATCH 21/51] local-display-factory: ignore spurios SeatNew signal at
a1b388
 start up
a1b388
a1b388
Sometimes during startup, logind will send a `SeatNew` signal for
a1b388
seat0 after GDM has already called `ListSeats` and processed `seat0`.
a1b388
a1b388
That `SeatNew` signal leads to GDM calling `create_display` twice in
a1b388
quick succession.
a1b388
a1b388
This commit changes GDM to avoid such double processing, by ignoring
a1b388
the `create_display` requests for seats that already have a prepared
a1b388
display ("prepared" means "starting up").
a1b388
a1b388
Closes: https://gitlab.gnome.org/GNOME/gdm/issues/410
a1b388
---
a1b388
 daemon/gdm-local-display-factory.c | 33 +++++++++++++++++++++++-------
a1b388
 1 file changed, 26 insertions(+), 7 deletions(-)
a1b388
a1b388
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
a1b388
index 6f3a4c391..127127005 100644
a1b388
--- a/daemon/gdm-local-display-factory.c
a1b388
+++ b/daemon/gdm-local-display-factory.c
a1b388
@@ -353,107 +353,126 @@ on_display_status_changed (GdmDisplay             *display,
a1b388
         case GDM_DISPLAY_MANAGED:
a1b388
                 break;
a1b388
         default:
a1b388
                 g_assert_not_reached ();
a1b388
                 break;
a1b388
         }
a1b388
 
a1b388
         g_free (seat_id);
a1b388
         g_free (session_type);
a1b388
         g_free (session_class);
a1b388
 }
a1b388
 
a1b388
 static gboolean
a1b388
 lookup_by_seat_id (const char *id,
a1b388
                    GdmDisplay *display,
a1b388
                    gpointer    user_data)
a1b388
 {
a1b388
         const char *looking_for = user_data;
a1b388
         char *current;
a1b388
         gboolean res;
a1b388
 
a1b388
         g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
a1b388
 
a1b388
         res = g_strcmp0 (current, looking_for) == 0;
a1b388
 
a1b388
         g_free(current);
a1b388
 
a1b388
         return res;
a1b388
 }
a1b388
 
a1b388
+static gboolean
a1b388
+lookup_prepared_display_by_seat_id (const char *id,
a1b388
+                                    GdmDisplay *display,
a1b388
+                                    gpointer    user_data)
a1b388
+{
a1b388
+        int status;
a1b388
+
a1b388
+        status = gdm_display_get_status (display);
a1b388
+
a1b388
+        if (status != GDM_DISPLAY_PREPARED)
a1b388
+                return FALSE;
a1b388
+
a1b388
+        return lookup_by_seat_id (id, display, user_data);
a1b388
+}
a1b388
+
a1b388
 static GdmDisplay *
a1b388
 create_display (GdmLocalDisplayFactory *factory,
a1b388
                 const char             *seat_id,
a1b388
                 const char             *session_type,
a1b388
                 gboolean                initial)
a1b388
 {
a1b388
         GdmDisplayStore *store;
a1b388
         GdmDisplay      *display = NULL;
a1b388
         char            *active_session_id = NULL;
a1b388
         int              ret;
a1b388
 
a1b388
         g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
a1b388
                  session_type? : "X11", seat_id);
a1b388
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
a1b388
 
a1b388
+        if (sd_seat_can_multi_session (seat_id))
a1b388
+                display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
a1b388
+        else
a1b388
+                display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
a1b388
+
a1b388
+        /* Ensure we don't create the same display more than once */
a1b388
+        if (display != NULL) {
a1b388
+                g_debug ("GdmLocalDisplayFactory: display already created");
a1b388
+                return NULL;
a1b388
+        }
a1b388
+
a1b388
         ret = sd_seat_get_active (seat_id, &active_session_id, NULL);
a1b388
 
a1b388
         if (ret == 0) {
a1b388
                 char *login_session_id = NULL;
a1b388
 
a1b388
                 /* If we already have a login window, switch to it */
a1b388
                 if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
a1b388
                         GdmDisplay *display;
a1b388
 
a1b388
                         display = gdm_display_store_find (store,
a1b388
                                                           lookup_by_session_id,
a1b388
                                                           (gpointer) login_session_id);
a1b388
                         if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) {
a1b388
                                 if (g_strcmp0 (active_session_id, login_session_id) != 0) {
a1b388
                                         g_debug ("GdmLocalDisplayFactory: session %s found, activating.",
a1b388
                                                  login_session_id);
a1b388
                                         gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id);
a1b388
                                 }
a1b388
                                 g_clear_pointer (&login_session_id, g_free);
a1b388
                                 g_clear_pointer (&active_session_id, g_free);
a1b388
                                 return NULL;
a1b388
                         }
a1b388
                         g_clear_pointer (&login_session_id, g_free);
a1b388
                 }
a1b388
                 g_clear_pointer (&active_session_id, g_free);
a1b388
-        } else if (!sd_seat_can_multi_session (seat_id)) {
a1b388
-                /* Ensure we don't create the same display more than once */
a1b388
-                display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
a1b388
-
a1b388
-                if (display != NULL) {
a1b388
-                        return NULL;
a1b388
-                }
a1b388
         }
a1b388
 
a1b388
         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
a1b388
 
a1b388
 #ifdef ENABLE_USER_DISPLAY_SERVER
a1b388
         if (g_strcmp0 (seat_id, "seat0") == 0) {
a1b388
                 display = gdm_local_display_new ();
a1b388
                 if (session_type != NULL) {
a1b388
                         g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
a1b388
                 }
a1b388
         }
a1b388
 #endif
a1b388
 
a1b388
         if (display == NULL) {
a1b388
                 guint32 num;
a1b388
 
a1b388
                 num = take_next_display_number (factory);
a1b388
 
a1b388
                 display = gdm_legacy_display_new (num);
a1b388
         }
a1b388
 
a1b388
         g_object_set (display, "seat-id", seat_id, NULL);
a1b388
         g_object_set (display, "is-initial", initial, NULL);
a1b388
 
a1b388
         store_display (factory, display);
a1b388
 
a1b388
         /* let store own the ref */
a1b388
         g_object_unref (display);
a1b388
 
a1b388
         if (! gdm_display_manage (display)) {
a1b388
-- 
a1b388
2.27.0
a1b388