/test-loopback
/test-machine-tables
/test-mmap-cache
+/test-mount-util
/test-namespace
/test-ndisc-rs
/test-netlink
test-utf8 \
test-ellipsize \
test-util \
+ test-mount-util \
test-cpu-set-util \
test-hexdecoct \
test-escape \
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
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;
+}
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);
#include "fileio.h"
#include "ioprio.h"
#include "missing.h"
+#include "mount-util.h"
#include "namespace.h"
#include "parse-util.h"
#include "path-util.h"
}
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");
#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"
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);
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;
#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"
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;
}
--- /dev/null
+/***
+ 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;
+}