diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-11-23 22:21:40 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-12-14 00:54:10 +0100 |
commit | d2d6c096f6373a76f3b303a7a116e7cfe7139c4d (patch) | |
tree | 090a728bbf4f98d5758806f6c21f958a8d9e982c /src/shared | |
parent | 8fceda937f3a177d9e27b403fb5e1b34138b05f5 (diff) |
core: add ability to define arbitrary bind mounts for services
This adds two new settings BindPaths= and BindReadOnlyPaths=. They allow
defining arbitrary bind mounts specific to particular services. This is
particularly useful for services with RootDirectory= set as this permits making
specific bits of the host directory available to chrooted services.
The two new settings follow the concepts nspawn already possess in --bind= and
--bind-ro=, as well as the .nspawn settings Bind= and BindReadOnly= (and these
latter options should probably be renamed to BindPaths= and BindReadOnlyPaths=
too).
Fixes: #3439
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/bus-unit-util.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 6dd9f2ccd4..735b8effc9 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -590,6 +590,76 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen } r = sd_bus_message_append(m, "v", "t", f); + } else if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) { + const char *p = eq; + + r = sd_bus_message_open_container(m, 'v', "a(ssbt)"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'a', "(ssbt)"); + if (r < 0) + return r; + + for (;;) { + _cleanup_free_ char *source = NULL, *destination = NULL; + char *s = NULL, *d = NULL; + bool ignore_enoent = false; + uint64_t flags = MS_REC; + + r = extract_first_word(&p, &source, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return log_error_errno(r, "Failed to parse argument: %m"); + if (r == 0) + break; + + s = source; + if (s[0] == '-') { + ignore_enoent = true; + s++; + } + + if (p && p[-1] == ':') { + r = extract_first_word(&p, &destination, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS); + if (r < 0) + return log_error_errno(r, "Failed to parse argument: %m"); + if (r == 0) { + log_error("Missing argument after ':': %s", eq); + return -EINVAL; + } + + d = destination; + + if (p && p[-1] == ':') { + _cleanup_free_ char *options = NULL; + + r = extract_first_word(&p, &options, NULL, EXTRACT_QUOTES); + if (r < 0) + return log_error_errno(r, "Failed to parse argument: %m"); + + if (isempty(options) || streq(options, "rbind")) + flags = MS_REC; + else if (streq(options, "norbind")) + flags = 0; + else { + log_error("Unknown options: %s", eq); + return -EINVAL; + } + } + } else + d = s; + + + r = sd_bus_message_append(m, "(ssbt)", s, d, ignore_enoent, flags); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(m); + if (r < 0) + return r; + + r = sd_bus_message_close_container(m); } else { log_error("Unknown assignment %s.", assignment); return -EINVAL; |