summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.exec.xml42
-rw-r--r--src/core/load-fragment.c10
-rw-r--r--src/core/namespace.c40
-rw-r--r--units/systemd-udevd.service.in1
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