]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: add a RequiresMountsFor= dependency from the session scope unit to the home...
authorLennart Poettering <lennart@poettering.net>
Wed, 8 Aug 2018 13:27:49 +0000 (15:27 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 13 Oct 2018 10:59:29 +0000 (12:59 +0200)
This is useful so that during shutdown scope units are always terminated
before the mounts necessary for the home directory.

(Ideally we'd also add a similar dependency from the user@.service
instance to the home directory, but this isn't as easy as that service
is defined statically and not dynamically, and hence not easy to modify
dynamically, in particular when it comes to deps)

src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-session.c
src/login/logind-user.c
src/login/logind-user.h
src/login/logind.h

index bd98ba9b26bf0655990e5efbc3dfb41da9e06134..6354dfe6e648ee5ca1326feb6b5942a1585949bf 100644 (file)
@@ -134,7 +134,14 @@ int manager_add_session(Manager *m, const char *id, Session **_session) {
         return 0;
 }
 
-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
+int manager_add_user(
+                Manager *m,
+                uid_t uid,
+                gid_t gid,
+                const char *name,
+                const char *home,
+                User **_user) {
+
         User *u;
         int r;
 
@@ -143,7 +150,7 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
 
         u = hashmap_get(m->users, UID_TO_PTR(uid));
         if (!u) {
-                r = user_new(&u, m, uid, gid, name);
+                r = user_new(&u, m, uid, gid, name, home);
                 if (r < 0)
                         return r;
         }
@@ -154,7 +161,12 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
         return 0;
 }
 
-int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
+int manager_add_user_by_name(
+                Manager *m,
+                const char *name,
+                User **_user) {
+
+        const char *home = NULL;
         uid_t uid;
         gid_t gid;
         int r;
@@ -162,11 +174,11 @@ int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
         assert(m);
         assert(name);
 
-        r = get_user_creds(&name, &uid, &gid, NULL, NULL, 0);
+        r = get_user_creds(&name, &uid, &gid, &home, NULL, 0);
         if (r < 0)
                 return r;
 
-        return manager_add_user(m, uid, gid, name, _user);
+        return manager_add_user(m, uid, gid, name, home, _user);
 }
 
 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
@@ -179,7 +191,7 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
         if (!p)
                 return errno > 0 ? -errno : -ENOENT;
 
-        return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
+        return manager_add_user(m, uid, p->pw_gid, p->pw_name, p->pw_dir, _user);
 }
 
 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
index 818341db4b29b7d1e1bad612f8e679090792d42b..032504e63a9a734d43970472905018f0d0e30e14 100644 (file)
@@ -2935,6 +2935,7 @@ int manager_start_scope(
                 const char *description,
                 char **wants,
                 char **after,
+                const char *requires_mounts_for,
                 sd_bus_message *more_properties,
                 sd_bus_error *error,
                 char **job) {
@@ -2990,6 +2991,12 @@ int manager_start_scope(
                         return r;
         }
 
+        if (!empty_or_root(requires_mounts_for)) {
+                r = sd_bus_message_append(m, "(sv)", "RequiresMountsFor", "as", 1, requires_mounts_for);
+                if (r < 0)
+                        return r;
+        }
+
         /* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore
          * SIGTERM */
         r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
index 6a70c9bced467c0d7f0e76c76fa4be91e1d3974f..a1c0a08fda8900c8f236f08eacc2c029811b1688 100644 (file)
@@ -642,6 +642,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
                                 description,
                                 STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */
                                 STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */
+                                s->user->home,
                                 properties,
                                 error,
                                 &s->scope_job);
index 4b0dfc7e0a3319ee7ec14573e25f24c6928882d4..e92f2a5243f04debdf93737ba61988b73a744c27 100644 (file)
 #include "user-util.h"
 #include "util.h"
 
-int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
+int user_new(User **ret,
+             Manager *m,
+             uid_t uid,
+             gid_t gid,
+             const char *name,
+             const char *home) {
+
         _cleanup_(user_freep) User *u = NULL;
         char lu[DECIMAL_STR_MAX(uid_t) + 1];
         int r;
@@ -54,6 +60,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
         if (!u->name)
                 return -ENOMEM;
 
+        u->home = strdup(home);
+        if (!u->home)
+                return -ENOMEM;
+
         if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0)
                 return -ENOMEM;
 
@@ -124,6 +134,7 @@ User *user_free(User *u) {
         u->runtime_path = mfree(u->runtime_path);
         u->state_file = mfree(u->state_file);
         u->name = mfree(u->name);
+        u->home = mfree(u->home);
 
         return mfree(u);
 }
index e05646adc99755333d8c9b1c107d901e53cc11b2..c41973e27dc01d8e64eed83991ff95b2fee24c1b 100644 (file)
@@ -23,6 +23,7 @@ struct User {
         uid_t uid;
         gid_t gid;
         char *name;
+        char *home;
         char *state_file;
         char *runtime_path;
 
@@ -49,7 +50,7 @@ struct User {
         LIST_FIELDS(User, gc_queue);
 };
 
-int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name);
+int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name, const char *home);
 User *user_free(User *u);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(User *, user_free);
index 0cccecb5ed427892ed5b71ed647c134cd0da15e4..b1a7b932eb91f21e8aacdc01407479a7cc785986 100644 (file)
@@ -134,7 +134,7 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev
 int manager_add_button(Manager *m, const char *name, Button **_button);
 int manager_add_seat(Manager *m, const char *id, Seat **_seat);
 int manager_add_session(Manager *m, const char *id, Session **_session);
-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user);
+int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, const char *home, User **_user);
 int manager_add_user_by_name(Manager *m, const char *name, User **_user);
 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user);
 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor);
@@ -171,7 +171,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name
 
 int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
 
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, sd_bus_message *more_properties, sd_bus_error *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);