diff --git a/src/core/mount.c b/src/core/mount.c index 0964eb1864..1c4aefd734 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -350,11 +350,10 @@ static int mount_add_device_dependencies(Mount *m) { if (path_equal(m->where, "/")) 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 suddenly. */ + /* 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 + * suddenly. */ dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES; /* We always use 'what' from /proc/self/mountinfo if mounted */ @@ -364,7 +363,7 @@ static int mount_add_device_dependencies(Mount *m) { if (r < 0) return r; - return 0; + return unit_add_blockdev_dependency(UNIT(m), p->what, mask); } static int mount_add_quota_dependencies(Mount *m) { diff --git a/src/core/swap.c b/src/core/swap.c index 713d785618..fd2fa557db 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -199,6 +199,7 @@ static SwapParameters* swap_get_parameters(Swap *s) { static int swap_add_device_dependencies(Swap *s) { UnitDependencyMask mask; SwapParameters *p; + int r; assert(s); @@ -211,8 +212,13 @@ static int swap_add_device_dependencies(Swap *s) { mask = s->from_proc_swaps ? UNIT_DEPENDENCY_PROC_SWAP : UNIT_DEPENDENCY_FILE; - if (is_device_path(p->what)) - return unit_add_node_dependency(UNIT(s), p->what, UNIT_REQUIRES, mask); + if (is_device_path(p->what)) { + r = unit_add_node_dependency(UNIT(s), p->what, UNIT_REQUIRES, mask); + if (r < 0) + return r; + + return unit_add_blockdev_dependency(UNIT(s), p->what, mask); + } /* File based swap devices need to be ordered after systemd-remount-fs.service, since they might need * a writable file system. */ diff --git a/src/core/unit.c b/src/core/unit.c index c629a1a9ce..9e95857d9a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3846,8 +3846,8 @@ int unit_deserialize_skip(FILE *f) { } int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, UnitDependencyMask mask) { - Unit *device; _cleanup_free_ char *e = NULL; + Unit *device; int r; assert(u); @@ -3859,8 +3859,7 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit if (!is_device_path(what)) return 0; - /* When device units aren't supported (such as in a - * container), don't create dependencies on them. */ + /* When device units aren't supported (such as in a container), don't create dependencies on them. */ if (!unit_type_supported(UNIT_DEVICE)) return 0; @@ -3880,6 +3879,33 @@ int unit_add_node_dependency(Unit *u, const char *what, UnitDependency dep, Unit device, true, mask); } +int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask mask) { + _cleanup_free_ char *escaped = NULL, *target = NULL; + int r; + + assert(u); + + if (isempty(what)) + return 0; + + if (!path_startswith(what, "/dev/")) + return 0; + + /* If we don't support devices, then also don't bother with blockdev@.target */ + if (!unit_type_supported(UNIT_DEVICE)) + return 0; + + r = unit_name_path_escape(what, &escaped); + if (r < 0) + return r; + + r = unit_name_build("blockdev", escaped, ".target", &target); + if (r < 0) + return r; + + return unit_add_dependency_by_name(u, UNIT_AFTER, target, true, mask); +} + int unit_coldplug(Unit *u) { int r = 0, q; char **i; diff --git a/src/core/unit.h b/src/core/unit.h index 68de900b0d..38d681dfb8 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -743,6 +743,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds); int unit_deserialize_skip(FILE *f); int unit_add_node_dependency(Unit *u, const char *what, UnitDependency d, UnitDependencyMask mask); +int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask mask); int unit_coldplug(Unit *u); void unit_catchup(Unit *u);