Blob Blame History Raw
From 0eada264dbce111730a8859152a7821a9df9c692 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 31 Aug 2018 14:33:58 -0400
Subject: [PATCH 27/48] manager: start initial setup right away

We no longer restart the greeter as soon as it dies, since we
start the greeter on demand.  This means, we no longer need to
defer starting initial setup until after the greeter respawns.

Furthermore, it doesn't work anymore since it relied on the
respawn to trigger.

This commit removes that code and scaffolding and just starts
initial setup directly.

https://gitlab.gnome.org/GNOME/gdm/issues/415
---
 daemon/gdm-manager.c | 66 +-------------------------------------------
 1 file changed, 1 insertion(+), 65 deletions(-)

diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index c8197a043..fb7b1ec4b 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -62,62 +62,60 @@
 #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
 
 #define INITIAL_SETUP_USERNAME "gnome-initial-setup"
 
 typedef struct
 {
         GdmManager *manager;
         GdmSession *session;
         char *service_name;
         guint idle_id;
 } StartUserSessionOperation;
 
 struct GdmManagerPrivate
 {
         GdmDisplayStore        *display_store;
         GdmLocalDisplayFactory *local_factory;
 #ifdef HAVE_LIBXDMCP
         GdmXdmcpDisplayFactory *xdmcp_factory;
 #endif
         GList                  *user_sessions;
         GHashTable             *transient_sessions;
         GHashTable             *open_reauthentication_requests;
         gboolean                xdmcp_enabled;
 
         gboolean                started;
         gboolean                show_local_greeter;
 
         GDBusConnection          *connection;
         GDBusObjectManagerServer *object_manager;
 
-        StartUserSessionOperation *initial_login_operation;
-
 #ifdef  WITH_PLYMOUTH
         guint                     plymouth_is_running : 1;
 #endif
         guint                     ran_once : 1;
 };
 
 enum {
         PROP_0,
         PROP_XDMCP_ENABLED,
         PROP_SHOW_LOCAL_GREETER
 };
 
 enum {
         DISPLAY_ADDED,
         DISPLAY_REMOVED,
         LAST_SIGNAL
 };
 
 typedef enum {
         SESSION_RECORD_LOGIN,
         SESSION_RECORD_LOGOUT,
         SESSION_RECORD_FAILED,
 } SessionRecord;
 
 static guint signals [LAST_SIGNAL] = { 0, };
 
 static void     gdm_manager_class_init  (GdmManagerClass *klass);
 static void     gdm_manager_init        (GdmManager      *manager);
 static void     gdm_manager_dispose     (GObject         *object);
 
@@ -1286,96 +1284,60 @@ get_automatic_login_details (GdmManager *manager,
         if (res && enabled) {
             res = gdm_settings_direct_get_string (GDM_KEY_AUTO_LOGIN_USER, &username);
         }
 
         if (enabled && res && username != NULL && username[0] != '\0') {
                 goto out;
         }
 
         g_free (username);
         username = NULL;
         enabled = FALSE;
 
  out:
         if (enabled) {
                 g_debug ("GdmDisplay: Got automatic login details for display: %d %s",
                          enabled,
                          username);
         } else {
                 g_debug ("GdmDisplay: Got automatic login details for display: 0");
         }
 
         if (usernamep != NULL) {
                 *usernamep = username;
         } else {
                 g_free (username);
         }
 
         return enabled;
 }
 
-static void
-maybe_start_pending_initial_login (GdmManager *manager,
-                                   GdmDisplay *greeter_display)
-{
-        StartUserSessionOperation *operation;
-        char *greeter_seat_id = NULL;
-        char *user_session_seat_id = NULL;
-
-        /* There may be a user session waiting to be started.
-         * This would happen if we couldn't start it earlier because
-         * the login screen X server was coming up and two X servers
-         * can't be started on the same seat at the same time.
-         */
-
-        if (manager->priv->initial_login_operation == NULL) {
-                return;
-        }
-
-        operation = manager->priv->initial_login_operation;
-
-        g_object_get (G_OBJECT (greeter_display),
-                      "seat-id", &greeter_seat_id,
-                      NULL);
-        g_object_get (G_OBJECT (operation->session),
-                      "display-seat-id", &user_session_seat_id,
-                      NULL);
-
-        if (g_strcmp0 (greeter_seat_id, user_session_seat_id) == 0) {
-                start_user_session (manager, operation);
-                manager->priv->initial_login_operation = NULL;
-        }
-
-        g_free (greeter_seat_id);
-        g_free (user_session_seat_id);
-}
-
 static const char *
 get_username_for_greeter_display (GdmManager *manager,
                                   GdmDisplay *display)
 {
         gboolean doing_initial_setup = FALSE;
 
         g_object_get (G_OBJECT (display),
                       "doing-initial-setup", &doing_initial_setup,
                       NULL);
 
         if (doing_initial_setup) {
                 return INITIAL_SETUP_USERNAME;
         } else {
                 return GDM_USERNAME;
         }
 }
 
 static void
 set_up_automatic_login_session (GdmManager *manager,
                                 GdmDisplay *display)
 {
         GdmSession *session;
         char       *display_session_type = NULL;
         gboolean is_initial;
 
         /* 0 is root user; since the daemon talks to the session object
          * directly, itself, for automatic login
          */
         session = create_user_session_for_display (manager, display, 0);
 
@@ -1498,131 +1460,115 @@ set_up_session (GdmManager *manager,
                         return;
                 }
 #endif
 
                 set_up_greeter_session (manager, display);
                 return;
         }
 
         /* Check whether the user really exists before committing to autologin. */
         user_manager = act_user_manager_get_default ();
         user = act_user_manager_get_user (user_manager, username);
         g_object_get (user_manager, "is-loaded", &loaded, NULL);
 
         if (loaded) {
                 set_up_automatic_login_session_if_user_exists (manager, display, user);
         } else {
                 UsernameLookupOperation *operation;
 
                 operation = g_new (UsernameLookupOperation, 1);
                 operation->manager = g_object_ref (manager);
                 operation->display = g_object_ref (display);
                 operation->username = username;
 
                 g_signal_connect (user,
                                   "notify::is-loaded",
                                   G_CALLBACK (on_user_is_loaded_changed),
                                   operation);
         }
 }
 
-static void
-greeter_display_started (GdmManager *manager,
-                         GdmDisplay *display)
-{
-        if (manager->priv->ran_once) {
-                return;
-        }
-
-        maybe_start_pending_initial_login (manager, display);
-}
-
 static void
 on_display_status_changed (GdmDisplay *display,
                            GParamSpec *arg1,
                            GdmManager *manager)
 {
         int         status;
         int         display_number = -1;
         char       *session_type = NULL;
 #ifdef WITH_PLYMOUTH
         gboolean    display_is_local = FALSE;
         gboolean    doing_initial_setup = FALSE;
         gboolean    quit_plymouth = FALSE;
 
         g_object_get (display,
                       "is-local", &display_is_local,
                       "doing-initial-setup", &doing_initial_setup,
                       NULL);
         quit_plymouth = display_is_local && manager->priv->plymouth_is_running;
 #endif
 
         g_object_get (display,
                       "x11-display-number", &display_number,
                       "session-type", &session_type,
                       NULL);
 
         status = gdm_display_get_status (display);
 
         switch (status) {
                 case GDM_DISPLAY_PREPARED:
                 case GDM_DISPLAY_MANAGED:
                         if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) ||
                             (display_number != -1 && status == GDM_DISPLAY_MANAGED)) {
                                 char *session_class;
 
                                 g_object_get (display,
                                               "session-class", &session_class,
                                               NULL);
                                 if (g_strcmp0 (session_class, "greeter") == 0)
                                         set_up_session (manager, display);
                                 g_free (session_class);
                         }
-
-                        if (status == GDM_DISPLAY_MANAGED) {
-                                greeter_display_started (manager, display);
-                        }
                         break;
                 case GDM_DISPLAY_FAILED:
                 case GDM_DISPLAY_UNMANAGED:
                 case GDM_DISPLAY_FINISHED:
 #ifdef WITH_PLYMOUTH
                         if (quit_plymouth) {
                                 plymouth_quit_without_transition ();
                                 manager->priv->plymouth_is_running = FALSE;
                         }
 #endif
 
                         if (!doing_initial_setup && (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0)) {
                                 manager->priv->ran_once = TRUE;
                         }
-                        maybe_start_pending_initial_login (manager, display);
                         break;
                 default:
                         break;
         }
 
 }
 
 static void
 on_display_removed (GdmDisplayStore *display_store,
                     GdmDisplay      *display,
                     GdmManager      *manager)
 {
         char    *id;
 
         gdm_display_get_id (display, &id, NULL);
         g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
         g_free (id);
 
         g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager);
 
         g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, display);
 }
 
 static void
 destroy_start_user_session_operation (StartUserSessionOperation *operation)
 {
         g_object_set_data (G_OBJECT (operation->session),
                            "start-user-session-operation",
                            NULL);
         g_object_unref (operation->session);
@@ -1723,97 +1669,87 @@ on_start_user_session (StartUserSessionOperation *operation)
                 gdm_session_reset (operation->session);
                 destroy_start_user_session_operation (operation);
                 goto out;
         }
 
         display = get_display_for_user_session (operation->session);
 
         g_object_get (G_OBJECT (display), "doing-initial-setup", &doing_initial_setup, NULL);
 
         session_id = gdm_session_get_conversation_session_id (operation->session,
                                                               operation->service_name);
 
         if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) {
                 /* In this case, the greeter's display is morphing into
                  * the user session display. Kill the greeter on this session
                  * and let the user session follow the same display. */
                 gdm_display_stop_greeter_session (display);
                 g_object_set (G_OBJECT (display),
                                 "session-class", "user",
                                 "session-id", session_id,
                                 NULL);
         } else {
                 uid_t allowed_uid;
 
                 g_object_ref (display);
                 if (doing_initial_setup) {
                         g_debug ("GdmManager: closing down initial setup display");
                         gdm_display_stop_greeter_session (display);
                         gdm_display_unmanage (display);
                         gdm_display_finish (display);
-
-                        /* We can't start the user session until the finished display
-                         * starts to respawn (since starting an X server and bringing
-                         * one down at the same time is a no go)
-                         */
-                        g_assert (self->priv->initial_login_operation == NULL);
-                        self->priv->initial_login_operation = operation;
-                        starting_user_session_right_away = FALSE;
                 } else {
                         g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
                 }
 
                 /* The user session is going to follow the session worker
                  * into the new display. Untie it from this display and
                  * create a new session for a future user login. */
                 allowed_uid = gdm_session_get_allowed_user (operation->session);
                 g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
                 g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL);
                 create_user_session_for_display (operation->manager, display, allowed_uid);
 
                 if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) &&
                     !gdm_session_client_is_connected (operation->session)) {
                         /* remove the unused prepared greeter display since we're not going
                          * to have a greeter */
                         gdm_display_store_remove (self->priv->display_store, display);
                         g_object_unref (display);
                 }
 
                 /* Give the user session a new display object for bookkeeping purposes */
                 create_display_for_user_session (operation->manager,
                                                  operation->session,
                                                  session_id);
         }
 
-        if (starting_user_session_right_away) {
-                start_user_session (operation->manager, operation);
-        }
+        start_user_session (operation->manager, operation);
 
  out:
         return G_SOURCE_REMOVE;
 }
 
 static void
 queue_start_user_session (GdmManager *manager,
                           GdmSession *session,
                           const char *service_name)
 {
         StartUserSessionOperation *operation;
 
         operation = g_slice_new0 (StartUserSessionOperation);
         operation->manager = manager;
         operation->session = g_object_ref (session);
         operation->service_name = g_strdup (service_name);
 
         operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation);
         g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation);
 }
 
 static void
 start_user_session_if_ready (GdmManager *manager,
                              GdmSession *session,
                              const char *service_name)
 {
         gboolean start_when_ready;
 
         start_when_ready = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), "start-when-ready"));
         if (start_when_ready) {
-- 
2.26.0