summaryrefslogtreecommitdiff
path: root/src/core/execute.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-12-23 14:26:05 +0100
committerLennart Poettering <lennart@poettering.net>2017-02-07 12:19:42 +0100
commit915e6d1676cf73c4f927f3bbfa21ee82640b1832 (patch)
tree7b12ef355276452ec4da4778e7b26c5ee58e8664 /src/core/execute.c
parent2eedfd2d8b3441e8cf6dae4bdc9afaefbda19c39 (diff)
core: add RootImage= setting for using a specific image file as root directory for a service
This is similar to RootDirectory= but mounts the root file system from a block device or loopback file instead of another directory. This reuses the image dissector code now used by nspawn and gpt-auto-discovery.
Diffstat (limited to 'src/core/execute.c')
-rw-r--r--src/core/execute.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index 54f6418c5a..f57eb26388 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1640,6 +1640,9 @@ static bool exec_needs_mount_namespace(
assert(context);
assert(params);
+ if (context->root_image)
+ return true;
+
if (!strv_isempty(context->read_write_paths) ||
!strv_isempty(context->read_only_paths) ||
!strv_isempty(context->inaccessible_paths))
@@ -1938,7 +1941,7 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
int r;
_cleanup_strv_free_ char **rw = NULL;
char *tmp = NULL, *var = NULL;
- const char *root_dir = NULL;
+ const char *root_dir = NULL, *root_image = NULL;
NameSpaceInfo ns_info = {
.ignore_protect_paths = false,
.private_dev = context->private_devices,
@@ -1965,8 +1968,12 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
if (r < 0)
return r;
- if (params->flags & EXEC_APPLY_CHROOT)
- root_dir = context->root_directory;
+ if (params->flags & EXEC_APPLY_CHROOT) {
+ root_image = context->root_image;
+
+ if (!root_image)
+ root_dir = context->root_directory;
+ }
/*
* If DynamicUser=no and RootDirectory= is set then lets pass a relaxed
@@ -1976,7 +1983,8 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
if (!context->dynamic_user && root_dir)
ns_info.ignore_protect_paths = true;
- r = setup_namespace(root_dir, &ns_info, rw,
+ r = setup_namespace(root_dir, root_image,
+ &ns_info, rw,
context->read_only_paths,
context->inaccessible_paths,
context->bind_mounts,
@@ -1985,7 +1993,8 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
var,
context->protect_home,
context->protect_system,
- context->mount_flags);
+ context->mount_flags,
+ DISSECT_IMAGE_DISCARD_ON_LOOP);
/* If we couldn't set up the namespace this is probably due to a
* missing capability. In this case, silently proceeed. */
@@ -1999,10 +2008,12 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context,
return r;
}
-static int apply_working_directory(const ExecContext *context,
- const ExecParameters *params,
- const char *home,
- const bool needs_mount_ns) {
+static int apply_working_directory(
+ const ExecContext *context,
+ const ExecParameters *params,
+ const char *home,
+ const bool needs_mount_ns) {
+
const char *d;
const char *wd;
@@ -2983,6 +2994,7 @@ void exec_context_done(ExecContext *c) {
c->working_directory = mfree(c->working_directory);
c->root_directory = mfree(c->root_directory);
+ c->root_image = mfree(c->root_image);
c->tty_path = mfree(c->tty_path);
c->syslog_identifier = mfree(c->syslog_identifier);
c->user = mfree(c->user);
@@ -3320,6 +3332,9 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
prefix, yes_no(c->memory_deny_write_execute),
prefix, yes_no(c->restrict_realtime));
+ if (c->root_image)
+ fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
+
STRV_FOREACH(e, c->environment)
fprintf(f, "%sEnvironment: %s\n", prefix, *e);