From: Lennart Poettering Date: Wed, 14 Apr 2021 09:22:44 +0000 (+0200) Subject: core: use StopPropagatedFrom= as default for .mount → .device unit dependencies X-Git-Tag: v249-rc1~155^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47cd17ead4bd773691708f3e81a7d047b5692e51;p=thirdparty%2Fsystemd.git core: use StopPropagatedFrom= as default for .mount → .device unit dependencies Let's make use of the new dependency type for .mount/.device units, after all we added it for this purpose. Fixes: #9869 --- diff --git a/src/core/mount.c b/src/core/mount.c index ca5d0939a18..b4962681645 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -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); }