diff options
-rw-r--r-- | man/systemd.exec.xml | 42 | ||||
-rw-r--r-- | src/core/load-fragment.c | 10 | ||||
-rw-r--r-- | src/core/namespace.c | 40 | ||||
-rw-r--r-- | units/systemd-udevd.service.in | 1 |
4 files changed, 64 insertions, 29 deletions
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 784b48fff4..f47826ce4a 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -962,13 +962,43 @@ <option>shared</option>, <option>slave</option> or <option>private</option>, which - control whether the file system - namespace set up for this unit's - processes will receive or propagate - new mounts. See + control whether mounts in the file + system namespace set up for this + unit's processes will receive or + propagate mounts or unmounts. See <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry> - for details. Default to - <option>shared</option>.</para></listitem> + for details. Defaults to + <option>shared</option>. Use + <option>shared</option> to ensure that + mounts and unmounts are propagated + from the host to the container and + vice versa. Use <option>slave</option> + to run processes so that none of their + mounts and unmounts will propagate to + the host. Use <option>private</option> + to also ensure that no mounts and + unmounts from the host will propagate + into the unit processes' + namespace. Note that + <option>slave</option> means that file + systems mounted on the host might stay + mounted continously in the unit's + namespace, and thus keep the device + busy. Note that the file system + namespace related options + (<varname>PrivateTmp=</varname>, + <varname>PrivateDevices=</varname>, + <varname>ReadOnlyDirectories=</varname>, + <varname>InaccessibleDirectories=</varname> + and + <varname>ReadWriteDirectories=</varname>) + require that mount and unmount + propagation from the unit's file + system namespace is disabled, and + hence downgrade + <option>shared</option> to + <option>slave</option>. + </para></listitem> </varlistentry> <varlistentry> diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 1c7ac75dd8..fa4e931b23 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1125,15 +1125,13 @@ int config_parse_exec_mount_flags(const char *unit, return log_oom(); if (streq(t, "shared")) - flags |= MS_SHARED; + flags = MS_SHARED; else if (streq(t, "slave")) - flags |= MS_SLAVE; + flags = MS_SLAVE; else if (streq(w, "private")) - flags |= MS_PRIVATE; + flags = MS_PRIVATE; else { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Failed to parse mount flag %s, ignoring: %s", - t, rvalue); + log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse mount flag %s, ignoring: %s", t, rvalue); return 0; } } diff --git a/src/core/namespace.c b/src/core/namespace.c index 4cbb0a1565..9f15211cb6 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -387,24 +387,28 @@ int setup_namespace( drop_duplicates(mounts, &n); } - /* Remount / as SLAVE so that nothing now mounted in the namespace - shows up in the parent */ - if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) - return -errno; + if (n > 0) { + /* Remount / as SLAVE so that nothing now mounted in the namespace + shows up in the parent */ + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) + return -errno; - for (m = mounts; m < mounts + n; ++m) { - r = apply_mount(m, tmp_dir, var_tmp_dir); - if (r < 0) - goto fail; - } + for (m = mounts; m < mounts + n; ++m) { + r = apply_mount(m, tmp_dir, var_tmp_dir); + if (r < 0) + goto fail; + } - for (m = mounts; m < mounts + n; ++m) { - r = make_read_only(m); - if (r < 0) - goto fail; + for (m = mounts; m < mounts + n; ++m) { + r = make_read_only(m); + if (r < 0) + goto fail; + } } - /* Remount / as the desired mode */ + /* Remount / as the desired mode. Not that this will not + * reestablish propagation from our side to the host, since + * what's disconnected is disconnected. */ if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0) { r = -errno; goto fail; @@ -413,9 +417,11 @@ int setup_namespace( return 0; fail: - for (m = mounts; m < mounts + n; ++m) - if (m->done) - umount2(m->path, MNT_DETACH); + if (n > 0) { + for (m = mounts; m < mounts + n; ++m) + if (m->done) + umount2(m->path, MNT_DETACH); + } return r; } diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in index 99f51304e4..ddee01537a 100644 --- a/units/systemd-udevd.service.in +++ b/units/systemd-udevd.service.in @@ -21,3 +21,4 @@ Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket Restart=always RestartSec=0 ExecStart=@rootlibexecdir@/systemd-udevd +MountFlags=slave |