summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-11-22 20:19:08 +0100
committerLennart Poettering <lennart@poettering.net>2016-12-13 21:22:13 +0100
commit835552511ef5edec94b567441251ada2a37ea333 (patch)
tree120f0cd18708151cbdfe34e74792e6d24c3da42e
parent9ef4e1e5a2d0a9cc50406f1cae05f3918d6f0c2a (diff)
core: hook up MountFlags= to the transient unit logic
This makes "systemd-run -p MountFlags=shared -t /bin/sh" work, by making MountFlags= to the list of properties that may be accessed transiently.
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am7
-rw-r--r--src/basic/mount-util.c32
-rw-r--r--src/basic/mount-util.h3
-rw-r--r--src/core/dbus-execute.c18
-rw-r--r--src/core/load-fragment.c39
-rw-r--r--src/shared/bus-unit-util.c17
-rw-r--r--src/test/test-mount-util.c45
8 files changed, 141 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore
index 016ba625e3..ec4b7bd672 100644
--- a/.gitignore
+++ b/.gitignore
@@ -239,6 +239,7 @@
/test-loopback
/test-machine-tables
/test-mmap-cache
+/test-mount-util
/test-namespace
/test-ndisc-rs
/test-netlink
diff --git a/Makefile.am b/Makefile.am
index 3bd8c29dd3..8f7b83f0ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1512,6 +1512,7 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-mount-util \
test-cpu-set-util \
test-hexdecoct \
test-escape \
@@ -1890,6 +1891,12 @@ test_util_SOURCES = \
test_util_LDADD = \
libsystemd-shared.la
+test_mount_util_SOURCES = \
+ src/test/test-mount-util.c
+
+test_mount_util_LDADD = \
+ libsystemd-shared.la
+
test_hexdecoct_SOURCES = \
src/test/test-hexdecoct.c
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 352c3505fb..8970050408 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -689,3 +689,35 @@ int umount_verbose(const char *what) {
return log_error_errno(errno, "Failed to unmount %s: %m", what);
return 0;
}
+
+const char *mount_propagation_flags_to_string(unsigned long flags) {
+
+ switch (flags & (MS_SHARED|MS_SLAVE|MS_PRIVATE)) {
+
+ case MS_SHARED:
+ return "shared";
+
+ case MS_SLAVE:
+ return "slave";
+
+ case MS_PRIVATE:
+ return "private";
+ }
+
+ return NULL;
+}
+
+unsigned long mount_propagation_flags_from_string(const char *name) {
+
+ if (isempty(name))
+ return 0;
+
+ if (streq(name, "shared"))
+ return MS_SHARED;
+ if (streq(name, "slave"))
+ return MS_SLAVE;
+ if (streq(name, "private"))
+ return MS_PRIVATE;
+
+ return 0;
+}
diff --git a/src/basic/mount-util.h b/src/basic/mount-util.h
index b840956d63..c8049198d4 100644
--- a/src/basic/mount-util.h
+++ b/src/basic/mount-util.h
@@ -61,3 +61,6 @@ int mount_verbose(
unsigned long flags,
const char *options);
int umount_verbose(const char *where);
+
+const char *mount_propagation_flags_to_string(unsigned long flags);
+unsigned long mount_propagation_flags_from_string(const char *name);
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 23c1b44573..78b177e107 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -34,6 +34,7 @@
#include "fileio.h"
#include "ioprio.h"
#include "missing.h"
+#include "mount-util.h"
#include "namespace.h"
#include "parse-util.h"
#include "path-util.h"
@@ -1613,8 +1614,23 @@ int bus_exec_context_set_transient_property(
}
return 1;
- }
+ } else if (streq(name, "MountFlags")) {
+ uint64_t flags;
+
+ r = sd_bus_message_read(message, "t", &flags);
+ if (r < 0)
+ return r;
+ if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags");
+ if (mode != UNIT_CHECK) {
+ c->mount_flags = flags;
+
+ unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(mount_propagation_flags_to_string(flags)));
+ }
+
+ return 1;
+ }
ri = rlimit_from_string(name);
if (ri < 0) {
soft = endswith(name, "Soft");
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 687cd1dd31..a2e7097de0 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -49,6 +49,7 @@
#include "load-fragment.h"
#include "log.h"
#include "missing.h"
+#include "mount-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
@@ -1264,19 +1265,20 @@ int config_parse_sysv_priority(const char *unit,
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode");
DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode");
-int config_parse_exec_mount_flags(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_exec_mount_flags(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
- unsigned long flags = 0;
+ unsigned long flags;
ExecContext *c = data;
assert(filename);
@@ -1284,15 +1286,14 @@ int config_parse_exec_mount_flags(const char *unit,
assert(rvalue);
assert(data);
- if (streq(rvalue, "shared"))
- flags = MS_SHARED;
- else if (streq(rvalue, "slave"))
- flags = MS_SLAVE;
- else if (streq(rvalue, "private"))
- flags = MS_PRIVATE;
+ if (isempty(rvalue))
+ flags = 0;
else {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse mount flag %s, ignoring.", rvalue);
- return 0;
+ flags = mount_propagation_flags_from_string(rvalue);
+ if (flags == 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse mount flag %s, ignoring.", rvalue);
+ return 0;
+ }
}
c->mount_flags = flags;
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 3114275c85..6dd9f2ccd4 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -27,6 +27,7 @@
#include "hashmap.h"
#include "list.h"
#include "locale-util.h"
+#include "mount-util.h"
#include "nsflags.h"
#include "parse-util.h"
#include "path-util.h"
@@ -575,7 +576,21 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "t", flags);
} else if ((dep = unit_dependency_from_string(field)) >= 0)
r = sd_bus_message_append(m, "v", "as", 1, eq);
- else {
+ else if (streq(field, "MountFlags")) {
+ unsigned long f;
+
+ if (isempty(eq))
+ f = 0;
+ else {
+ f = mount_propagation_flags_from_string(eq);
+ if (f == 0) {
+ log_error("Failed to parse mount propagation type: %s", eq);
+ return -EINVAL;
+ }
+ }
+
+ r = sd_bus_message_append(m, "v", "t", f);
+ } else {
log_error("Unknown assignment %s.", assignment);
return -EINVAL;
}
diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c
new file mode 100644
index 0000000000..da7f35623b
--- /dev/null
+++ b/src/test/test-mount-util.c
@@ -0,0 +1,45 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mount.h>
+
+#include "log.h"
+#include "mount-util.h"
+#include "string-util.h"
+
+static void test_mount_propagation_flags(const char *name, unsigned long f) {
+ assert(mount_propagation_flags_from_string(name) == f);
+
+ if (f != 0)
+ assert_se(streq_ptr(mount_propagation_flags_to_string(f), name));
+}
+
+int main(int argc, char *argv[]) {
+
+ log_set_max_level(LOG_DEBUG);
+
+ test_mount_propagation_flags("shared", MS_SHARED);
+ test_mount_propagation_flags("slave", MS_SLAVE);
+ test_mount_propagation_flags("private", MS_PRIVATE);
+ test_mount_propagation_flags(NULL, 0);
+ test_mount_propagation_flags("", 0);
+ test_mount_propagation_flags("xxxx", 0);
+
+ return 0;
+}