You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
8.7 KiB
211 lines
8.7 KiB
From e9a187ea6abf1e7034ee3113355b282743a98f39 Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Wed, 8 Aug 2018 15:27:49 +0200
|
|
Subject: [PATCH] logind: add a RequiresMountsFor= dependency from the session
|
|
scope unit to the home directory of the user
|
|
|
|
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)
|
|
|
|
(cherry picked from commit d5ac9d060267820aabdf9af509a54a1830b27b7d)
|
|
|
|
Related: #1642460
|
|
---
|
|
src/login/logind-core.c | 24 ++++++++++++++++++------
|
|
src/login/logind-dbus.c | 7 +++++++
|
|
src/login/logind-session.c | 1 +
|
|
src/login/logind-user.c | 13 ++++++++++++-
|
|
src/login/logind-user.h | 3 ++-
|
|
src/login/logind.h | 4 ++--
|
|
6 files changed, 42 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
|
|
index 678c708df1..0ed812a2c8 100644
|
|
--- a/src/login/logind-core.c
|
|
+++ b/src/login/logind-core.c
|
|
@@ -128,7 +128,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;
|
|
|
|
@@ -137,7 +144,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;
|
|
}
|
|
@@ -148,7 +155,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;
|
|
@@ -156,11 +168,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);
|
|
+ r = get_user_creds(&name, &uid, &gid, &home, NULL);
|
|
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) {
|
|
@@ -173,7 +185,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) {
|
|
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
|
|
index 6586280269..1bb152bc20 100644
|
|
--- a/src/login/logind-dbus.c
|
|
+++ b/src/login/logind-dbus.c
|
|
@@ -3313,6 +3313,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) {
|
|
@@ -3368,6 +3369,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);
|
|
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
|
|
index dd4ac9482a..e4c8bb36f6 100644
|
|
--- a/src/login/logind-session.c
|
|
+++ b/src/login/logind-session.c
|
|
@@ -591,6 +591,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);
|
|
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
|
|
index f23fcbe674..70f5eb9d59 100644
|
|
--- a/src/login/logind-user.c
|
|
+++ b/src/login/logind-user.c
|
|
@@ -30,7 +30,13 @@
|
|
#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);
|
|
}
|
|
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
|
|
index e05646adc9..c41973e27d 100644
|
|
--- a/src/login/logind-user.h
|
|
+++ b/src/login/logind-user.h
|
|
@@ -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);
|
|
diff --git a/src/login/logind.h b/src/login/logind.h
|
|
index 7288dd7445..d29b01c75b 100644
|
|
--- a/src/login/logind.h
|
|
+++ b/src/login/logind.h
|
|
@@ -129,7 +129,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);
|
|
@@ -162,7 +162,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);
|