chiark / gitweb /
unit: turn off mount propagation for udevd
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Mar 2014 03:16:39 +0000 (04:16 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Mar 2014 03:16:39 +0000 (04:16 +0100)
Keep mounts done by udev rules private to udevd. Also, document how
MountFlags= may be used for this.

man/systemd.exec.xml
src/core/load-fragment.c
src/core/namespace.c
units/systemd-udevd.service.in

index 784b48f..f47826c 100644 (file)
                                 <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>
index 1c7ac75..fa4e931 100644 (file)
@@ -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;
                 }
         }
index 4cbb0a1..9f15211 100644 (file)
@@ -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;
 }
index 99f5130..ddee015 100644 (file)
@@ -21,3 +21,4 @@ Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
 Restart=always
 RestartSec=0
 ExecStart=@rootlibexecdir@/systemd-udevd
+MountFlags=slave