core: Add RootDirectoryFileDescriptor=

RootDirectory= but via a open_tree() file descriptor. This allows
setting up the execution environment for a service by the client in
a mount namespace and then starting a transient unit in that execution
environment using the new property.

We also add --root-directory= and --same-root-dir= to systemd-run to
have it run services within the given root directory. As systemd-run
might be invoked from a different mount namespace than what systemd is
running in, systemd-run opens the given path with open_tree() and then
sends it to systemd using the new RootDirectoryFileDescriptor= property.
This commit is contained in:
Daan De Meyer
2025-10-31 13:09:51 +01:00
parent 456ee3c5f9
commit 9e26ced980
15 changed files with 162 additions and 10 deletions
+23
View File
@@ -1177,6 +1177,10 @@ static int exec_parameters_serialize(const ExecParameters *p, const ExecContext
if (r < 0)
return r;
r = serialize_fd(f, fds, "exec-parameters-root-directory-fd", p->root_directory_fd);
if (r < 0)
return r;
r = serialize_fd(f, fds, "exec-parameters-exec-fd", p->exec_fd);
if (r < 0)
return r;
@@ -1422,6 +1426,16 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
continue;
close_and_replace(p->stderr_fd, fd);
} else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
int fd;
fd = deserialize_fd(fds, val);
if (fd < 0)
continue;
close_and_replace(p->root_directory_fd, fd);
} else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
int fd;
@@ -1994,6 +2008,10 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
if (r < 0)
return r;
r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
if (r < 0)
return r;
switch (c->std_input) {
case EXEC_INPUT_NAMED_FD:
r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
@@ -3000,6 +3018,11 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
if (r < 0)
return r;
c->stdio_as_fds = r;
} else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
r = parse_boolean(val);
if (r < 0)
return r;
c->root_directory_as_fd = r;
} else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
if (r < 0)