]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Don't create all shared user dirs on startup; rather create them on demand as the...
authorMichael Terry <michael.terry@canonical.com>
Tue, 18 Feb 2014 19:49:01 +0000 (14:49 -0500)
committerMichael Terry <michael.terry@canonical.com>
Tue, 18 Feb 2014 19:49:01 +0000 (14:49 -0500)
src/lightdm.c
src/seat.c
src/shared-data-manager.c
src/shared-data-manager.h
tests/scripts/shared-data-dirs.conf

index a45713dd01efb882bf67b4bb7714df36f71f09a4..faa4a66b307e1946499bdbcfaee472eef33e81af 100644 (file)
@@ -990,7 +990,6 @@ main (int argc, char **argv)
     gchar *default_cache_dir = g_strdup (CACHE_DIR);
     gboolean show_version = FALSE;
     GList *link, *messages = NULL;
-    SharedDataManager *shared_data_manager = NULL;
     GOptionEntry options[] =
     {
         { "config", 'c', 0, G_OPTION_ARG_STRING, &config_path,
@@ -1247,7 +1246,7 @@ main (int argc, char **argv)
     g_signal_connect (display_manager, "stopped", G_CALLBACK (display_manager_stopped_cb), NULL);
     g_signal_connect (display_manager, "seat-removed", G_CALLBACK (display_manager_seat_removed_cb), NULL);
 
-    shared_data_manager = shared_data_manager_new ();
+    shared_data_manager_start (shared_data_manager_get_instance ());
 
     /* Load the static display entries */
     groups = config_get_groups (config_get_instance ());
@@ -1325,8 +1324,7 @@ main (int argc, char **argv)
     g_main_loop_run (loop);
 
     /* Clean up shared data manager */
-    g_object_unref (shared_data_manager);
-    shared_data_manager = NULL;
+    shared_data_manager_cleanup ();
 
     /* Clean up user list */
     common_user_list_cleanup ();
index 7347d1ce87b00b268374cb5e0cd04e6879a0717b..11307036a6939d85d3c485d82c977e237e27982e 100644 (file)
@@ -18,6 +18,7 @@
 #include "guest-account.h"
 #include "greeter.h"
 #include "session-config.h"
+#include "shared-data-manager.h"
 
 enum {
     SESSION_ADDED,
@@ -1039,6 +1040,9 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
         g_object_unref (session_config);
     }
 
+    /* Make sure shared user directory for this user exists */
+    shared_data_manager_ensure_user_dir (shared_data_manager_get_instance (), session_get_username (session));
+
     /* Switch to this session when it is ready */
     if (seat->priv->session_to_activate)
         g_object_unref (seat->priv->session_to_activate);
index dbdc30101c46acc8f8de7f30427e8881aea8d0d9..fe803dc017d2b154fb718ac2bad431ec0a1d3a05 100644 (file)
@@ -25,7 +25,6 @@ struct SharedDataManagerPrivate
 {
     guint32 greeter_uid;
     guint32 greeter_gid;
-    guint num_setup_users;
     GHashTable *starting_dirs;
 };
 
@@ -37,10 +36,24 @@ struct OwnerInfo
 
 G_DEFINE_TYPE (SharedDataManager, shared_data_manager, G_TYPE_OBJECT);
 
+static SharedDataManager *singleton = NULL;
+
 SharedDataManager *
-shared_data_manager_new (void)
+shared_data_manager_get_instance (void)
+{
+    if (!singleton)
+        singleton = g_object_new (SHARED_DATA_MANAGER_TYPE, NULL);
+    return singleton;
+}
+
+void
+shared_data_manager_cleanup (void)
 {
-    return g_object_new (SHARED_DATA_MANAGER_TYPE, NULL);
+    if (singleton)
+    {
+        g_object_unref (singleton);
+        singleton = NULL;
+    }
 }
 
 static void
@@ -105,7 +118,6 @@ make_user_dir_cb (GObject *object, GAsyncResult *res, gpointer user_data)
                        path, error->message);
             g_free (path);
             g_error_free (error);
-            owner->manager->priv->num_setup_users--;
             g_object_unref (owner->manager);
             g_free (owner);
             return;
@@ -126,17 +138,6 @@ make_user_dir_cb (GObject *object, GAsyncResult *res, gpointer user_data)
                                  G_PRIORITY_DEFAULT, NULL,
                                  chown_user_dir_cb, NULL);
 
-    /* If we're the last user dir to be set up, delete unused user dirs */
-    owner->manager->priv->num_setup_users--;
-    if (owner->manager->priv->starting_dirs != NULL &&
-        owner->manager->priv->num_setup_users == 0)
-    {
-        g_hash_table_foreach (owner->manager->priv->starting_dirs,
-                              delete_unused_user, owner->manager);
-        g_hash_table_destroy (owner->manager->priv->starting_dirs);
-        owner->manager->priv->starting_dirs = NULL;
-    }
-
     g_object_unref (owner->manager);
     g_free (owner);
 }
@@ -152,10 +153,6 @@ setup_user_dir (SharedDataManager *manager, guint32 uid)
     gchar *path = g_build_filename (USERS_DIR, uidstr, NULL);
     GFile *file = g_file_new_for_path (path);
     g_free (path);
-
-    manager->priv->num_setup_users++;
-    if (manager->priv->starting_dirs != NULL)
-        g_hash_table_remove (manager->priv->starting_dirs, uidstr);
     g_free (uidstr);
 
     g_file_make_directory_async (file, G_PRIORITY_DEFAULT, NULL,
@@ -164,6 +161,15 @@ setup_user_dir (SharedDataManager *manager, guint32 uid)
     g_object_unref (file);
 }
 
+void
+shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user)
+{
+    struct passwd *entry;
+    entry = getpwnam (user);
+    if (entry)
+        setup_user_dir (manager, entry->pw_uid);
+}
+
 static void
 next_user_dirs_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 {
@@ -200,15 +206,21 @@ next_user_dirs_cb (GObject *object, GAsyncResult *res, gpointer user_data)
     else
     {
         // We've finally assembled all the initial directories.  Now let's
-        // iterate the current users and set them each up.  As we go, we'll
-        // remove the users from the starting_dirs hash and thus see which
-        // users are obsolete.
+        // iterate the current users and as we go, remove the users from the
+        // starting_dirs hash and thus see which users are obsolete.
         GList *users = common_user_list_get_users (common_user_list_get_instance ());
         for (link = users; link; link = link->next)
         {
             CommonUser *user = link->data;
-            setup_user_dir (manager, common_user_get_uid (user));
+            gchar *uidstr = g_strdup_printf ("%u", common_user_get_uid (user));
+            g_hash_table_remove (manager->priv->starting_dirs, uidstr);
+            g_free (uidstr);
         }
+        g_hash_table_foreach (manager->priv->starting_dirs,
+                              delete_unused_user, manager);
+        g_hash_table_destroy (manager->priv->starting_dirs);
+        manager->priv->starting_dirs = NULL;
+
         // Also set up our own greeter dir, so it has a place to dump its own files
         // (imagine it holding some large files temporarily before shunting them
         // to the next user to log in's specific directory).
@@ -243,13 +255,6 @@ list_user_dirs_cb (GObject *object, GAsyncResult *res, gpointer user_data)
                                         next_user_dirs_cb, manager);
 }
 
-static void
-user_added_cb (CommonUserList *list, CommonUser *user,
-               SharedDataManager *manager)
-{
-    setup_user_dir (manager, common_user_get_uid (user));
-}
-
 static void
 user_removed_cb (CommonUserList *list, CommonUser *user,
                  SharedDataManager *manager)
@@ -259,6 +264,23 @@ user_removed_cb (CommonUserList *list, CommonUser *user,
     g_free (uid);
 }
 
+void
+shared_data_manager_start (SharedDataManager *manager)
+{
+    /* Grab list of all current directories, so we know if any exist that we
+       no longer need. */
+    GFile *file = g_file_new_for_path (USERS_DIR);
+    g_file_enumerate_children_async (file, G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                     G_FILE_QUERY_INFO_NONE,
+                                     G_PRIORITY_DEFAULT, NULL,
+                                     list_user_dirs_cb, g_object_ref (manager));
+    g_object_unref (file);
+
+    /* And listen for user removals. */
+    g_signal_connect (common_user_list_get_instance (), "user-removed",
+                      G_CALLBACK (user_removed_cb), manager);
+}
+
 static void
 shared_data_manager_init (SharedDataManager *manager)
 {
@@ -275,22 +297,6 @@ shared_data_manager_init (SharedDataManager *manager)
         manager->priv->greeter_gid = greeter_entry->pw_gid;
     }
     g_free (greeter_user);
-
-    /* Grab list of all current directories, so we know if any exist that we
-       no longer need. */
-    GFile *file = g_file_new_for_path (USERS_DIR);
-    g_file_enumerate_children_async (file, G_FILE_ATTRIBUTE_STANDARD_NAME,
-                                     G_FILE_QUERY_INFO_NONE,
-                                     G_PRIORITY_DEFAULT, NULL,
-                                     list_user_dirs_cb, g_object_ref (manager));
-    g_object_unref (file);
-
-    /* And listen for user changes.  The chance of a race with the above
-       initial setup is so tiny, it's not worth worrying about. */
-    g_signal_connect (common_user_list_get_instance (), "user-added",
-                      G_CALLBACK (user_added_cb), manager);
-    g_signal_connect (common_user_list_get_instance (), "user-removed",
-                      G_CALLBACK (user_removed_cb), manager);
 }
 
 static void
index faa780ab1ccc350de2237652f5c571187ce2a8aa..737337af6b44d365c3c1dd2a72b96b77dc9f79dc 100644 (file)
@@ -38,7 +38,13 @@ typedef struct
 
 GType shared_data_manager_get_type (void);
 
-SharedDataManager *shared_data_manager_new (void);
+SharedDataManager *shared_data_manager_get_instance (void);
+
+void shared_data_manager_start (SharedDataManager *manager);
+
+void shared_data_manager_cleanup (void);
+
+void shared_data_manager_ensure_user_dir (SharedDataManager *manager, const gchar *user);
 
 G_END_DECLS
 
index 141dc6e4d61af2c1bb92da553282355311c0b4ab..2e8529988cef8945247da4c693e32d095f6f196c 100644 (file)
@@ -3,9 +3,8 @@
 #
 
 [test-runner-config]
-accounts-service-user-filter=have-password1 have-password2 have-password3
-# One normal, one with bad permissions, one to create, one to delete
-shared-data-dirs=1000:1000:100:0770 1001:1000:1000:0777 1004:1004:100:0770
+# One normal, one with bad permissions, one to delete
+shared-data-dirs=1000:1000:100:0770 1001:1000:1000:0777 99999:1004:100:0770
 
 #?RUNNER DAEMON-START
 
@@ -15,23 +14,45 @@ shared-data-dirs=1000:1000:100:0770 1001:1000:1000:0777 1004:1004:100:0770
 # Startup creation/deletion
 #?*WAIT
 #?*LIST-SHARED-DATA-DIRS
-#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1000:1000:100:0770,1001:1001:100:0770,1002:1002:100:0770
+#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1000:1000:100:0770,1001:1000:1000:0777
 
-# Delete one user
-#?*DELETE-USER USERNAME=have-password1
-#?RUNNER DELETE-USER USERNAME=have-password1
+# Daemon connects when X server is ready
+#?*XSERVER-0 INDICATE-READY
+#?XSERVER-0 INDICATE-READY
+#?XSERVER-0 ACCEPT-CONNECT
+
+# Greeter starts
+#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
+#?XSERVER-0 ACCEPT-CONNECT
+#?GREETER-X-0 CONNECT-XSERVER
+#?GREETER-X-0 CONNECT-TO-DAEMON
+#?GREETER-X-0 CONNECTED-TO-DAEMON
+
+# Log into account without a password
+#?*GREETER-X-0 AUTHENTICATE USERNAME=no-password1
+#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=no-password1 AUTHENTICATED=TRUE
+#?*GREETER-X-0 START-SESSION
+#?GREETER-X-0 TERMINATE SIGNAL=15
+
+# Session starts
+#?SESSION-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 DESKTOP_SESSION=default USER=no-password1
+#?XSERVER-0 ACCEPT-CONNECT
+#?SESSION-X-0 CONNECT-XSERVER
+
+# Make sure we created the directory as we started session
 #?*WAIT
 #?*LIST-SHARED-DATA-DIRS
-#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1001:1001:100:0770,1002:1002:100:0770
+#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1000:1000:100:0770,1001:1000:1000:0777,1005:1005:100:0770
 
-# Add one user
-#?*ADD-USER USERNAME=have-password4
-#?RUNNER ADD-USER USERNAME=have-password4
+# Delete one user
+#?*DELETE-USER USERNAME=have-password1
+#?RUNNER DELETE-USER USERNAME=have-password1
 #?*WAIT
 #?*LIST-SHARED-DATA-DIRS
-#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1001:1001:100:0770,1002:1002:100:0770,1003:1003:100:0770
+#?RUNNER LIST-SHARED-DATA-DIRS DIRS=100:100:100:0770,1001:1000:1000:0777,1005:1005:100:0770
 
 # Cleanup
 #?*STOP-DAEMON
 #?XSERVER-0 TERMINATE SIGNAL=15
+#?SESSION-X-0 TERMINATE SIGNAL=15
 #?RUNNER DAEMON-EXIT STATUS=0