]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: use StopPropagatedFrom= as default for .mount → .device unit dependencies
authorLennart Poettering <lennart@poettering.net>
Wed, 14 Apr 2021 09:22:44 +0000 (11:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 25 May 2021 14:03:03 +0000 (16:03 +0200)
Let's make use of the new dependency type for .mount/.device units,
after all we added it for this purpose.

Fixes: #9869
src/core/mount.c

index ca5d0939a18f36a5338f284c9876fdad361454a2..b496268164510ae64889e6371b6abce7b1617831 100644 (file)
@@ -66,6 +66,24 @@ static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
                       MOUNT_CLEANING);
 }
 
+static MountParameters* get_mount_parameters_fragment(Mount *m) {
+        assert(m);
+
+        if (m->from_fragment)
+                return &m->parameters_fragment;
+
+        return NULL;
+}
+
+static MountParameters* get_mount_parameters(Mount *m) {
+        assert(m);
+
+        if (m->from_proc_self_mountinfo)
+                return &m->parameters_proc_self_mountinfo;
+
+        return get_mount_parameters_fragment(m);
+}
+
 static bool mount_is_automount(const MountParameters *p) {
         assert(p);
 
@@ -116,16 +134,33 @@ static bool mount_is_bind(const MountParameters *p) {
         return false;
 }
 
-static bool mount_is_bound_to_device(const Mount *m) {
+static bool mount_is_bound_to_device(Mount *m) {
         const MountParameters *p;
 
-        if (m->from_fragment)
-                return true;
+        assert(m);
+
+        /* Determines whether to place a Requires= or BindsTo= dependency on the backing device unit. We do
+         * this by checking for the x-systemd.device-bound mount option. Iff it is set we use BindsTo=,
+         * otherwise Requires=. But note that we might combine the latter with StopPropagatedFrom=, see
+         * below. */
+
+        p = get_mount_parameters(m);
+        if (!p)
+                return false;
 
-        p = &m->parameters_proc_self_mountinfo;
         return fstab_test_option(p->options, "x-systemd.device-bound\0");
 }
 
+static bool mount_propagate_stop(Mount *m) {
+        assert(m);
+
+        if (mount_is_bound_to_device(m)) /* If we are using BindsTo= the stop propagation is implicit, no need to bother */
+                return false;
+
+        return m->from_fragment; /* let's propagate stop whenever this is an explicitly configured unit,
+                                  * otherwise let's not bother. */
+}
+
 static bool mount_needs_quota(const MountParameters *p) {
         assert(p);
 
@@ -234,24 +269,6 @@ static void mount_done(Unit *u) {
         m->timer_event_source = sd_event_source_unref(m->timer_event_source);
 }
 
-static MountParameters* get_mount_parameters_fragment(Mount *m) {
-        assert(m);
-
-        if (m->from_fragment)
-                return &m->parameters_fragment;
-
-        return NULL;
-}
-
-static MountParameters* get_mount_parameters(Mount *m) {
-        assert(m);
-
-        if (m->from_proc_self_mountinfo)
-                return &m->parameters_proc_self_mountinfo;
-
-        return get_mount_parameters_fragment(m);
-}
-
 static int update_parameters_proc_self_mountinfo(
                 Mount *m,
                 const char *what,
@@ -367,8 +384,9 @@ static int mount_add_device_dependencies(Mount *m) {
                 return 0;
 
         /* Mount units from /proc/self/mountinfo are not bound to devices by default since they're subject to
-         * races when devices are unplugged. But the user can still force this dep with an appropriate option
-         * (or udev property) so the mount units are automatically stopped when the device disappears
+         * races when mounts are established by other tools with different backing devices than what we
+         * maintain. The user can still force this to be a BindsTo= dependency with an appropriate option (or
+         * udev property) so the mount units are automatically stopped when the device disappears
          * suddenly. */
         dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES;
 
@@ -378,6 +396,11 @@ static int mount_add_device_dependencies(Mount *m) {
         r = unit_add_node_dependency(UNIT(m), p->what, dep, mask);
         if (r < 0)
                 return r;
+        if (mount_propagate_stop(m)) {
+                r = unit_add_node_dependency(UNIT(m), p->what, UNIT_STOP_PROPAGATED_FROM, mask);
+                if (r < 0)
+                        return r;
+        }
 
         return unit_add_blockdev_dependency(UNIT(m), p->what, mask);
 }