]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: hook up MountFlags= to the transient unit logic
authorLennart Poettering <lennart@poettering.net>
Tue, 22 Nov 2016 19:19:08 +0000 (20:19 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 13 Dec 2016 20:22:13 +0000 (21:22 +0100)
This makes "systemd-run -p MountFlags=shared -t /bin/sh" work, by making
MountFlags= to the list of properties that may be accessed transiently.

.gitignore
Makefile.am
src/basic/mount-util.c
src/basic/mount-util.h
src/core/dbus-execute.c
src/core/load-fragment.c
src/shared/bus-unit-util.c
src/test/test-mount-util.c [new file with mode: 0644]

index 016ba625e36f58fc7db18945c719f1627dda532a..ec4b7bd6729b2a20eadd5d3239ae74fdc62c9922 100644 (file)
 /test-loopback
 /test-machine-tables
 /test-mmap-cache
+/test-mount-util
 /test-namespace
 /test-ndisc-rs
 /test-netlink
index 3bd8c29dd37a81fd754735b5db475987ee902a4e..8f7b83f0ab73d645527790e71e97835804c6d712 100644 (file)
@@ -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
 
index 352c3505fb34e2045f88be4f43b5642fe8f718b0..8970050408f547e154fafd72f973123d9ecbcbdb 100644 (file)
@@ -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;
+}
index b840956d63003a377097ea4e16b2845c67b38c76..c8049198d448cd29751a1a4c0a5602f2b5f8302b 100644 (file)
@@ -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);
index 23c1b4457315d2f987c12611b15e69f6436c7b81..78b177e1075bb8af9c35804cff75f7a9d08199c7 100644 (file)
@@ -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");
index 687cd1dd317499ed8cb3c062caa11f215a7b9138..a2e7097de0b412acb8e233cc7fcd64ade58a418d 100644 (file)
@@ -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;
index 3114275c85fbceb59c562a77ce02a94de5460f85..6dd9f2ccd4580943538f7db015056e73103202c7 100644 (file)
@@ -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 (file)
index 0000000..da7f356
--- /dev/null
@@ -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;
+}