From: Yu Watanabe Date: Sat, 14 May 2022 21:31:17 +0000 (+0900) Subject: core/mount: make device deps from /proc/self/mountinfo and .mount unit file exclusive X-Git-Tag: v252-rc1~512^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=49267b1b147047c294e882b7ae741f8732d36d05;p=thirdparty%2Fsystemd.git core/mount: make device deps from /proc/self/mountinfo and .mount unit file exclusive Before this commit, when a .mount unit file is loaded, the device dependencies from the unit file are automatically added. If a device that is different from which specified in .mount unit file is mounted on the path, then the device dependencies about the device are also added. Hence, the unit has device dependencies about two (or more) different devices. Hence, if one of the devices are unplugged, even if another one is mounted on the path, then the path is unmounted. This commit makes device dependencies from two different sources exclusive, and always regenerate the dependencies when one of the information is updated. Fixes #19983 and #23552. --- diff --git a/src/core/mount.c b/src/core/mount.c index 71da69cbb5f..9dc04cd07e9 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -347,7 +347,6 @@ static int mount_add_mount_dependencies(Mount *m) { } static int mount_add_device_dependencies(Mount *m) { - UnitDependencyMask mask; MountParameters *p; UnitDependency dep; int r; @@ -396,17 +395,14 @@ static int mount_add_device_dependencies(Mount *m) { * suddenly. */ dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES; - /* We always use 'what' from /proc/self/mountinfo if mounted */ - mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT : UNIT_DEPENDENCY_FILE; - - r = unit_add_node_dependency(UNIT(m), p->what, dep, mask); + r = unit_add_node_dependency(UNIT(m), p->what, dep, UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; if (r > 0) log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(dep), p->what); if (mount_propagate_stop(m)) { - r = unit_add_node_dependency(UNIT(m), p->what, UNIT_STOP_PROPAGATED_FROM, mask); + r = unit_add_node_dependency(UNIT(m), p->what, UNIT_STOP_PROPAGATED_FROM, UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; if (r > 0) @@ -414,11 +410,11 @@ static int mount_add_device_dependencies(Mount *m) { unit_dependency_to_string(UNIT_STOP_PROPAGATED_FROM), p->what); } - r = unit_add_blockdev_dependency(UNIT(m), p->what, mask); + r = unit_add_blockdev_dependency(UNIT(m), p->what, UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r > 0) log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(UNIT_AFTER), p->what); - return r; + return 0; } static int mount_add_quota_dependencies(Mount *m) { @@ -474,8 +470,7 @@ static bool mount_is_extrinsic(Unit *u) { static int mount_add_default_ordering_dependencies( Mount *m, - MountParameters *p, - UnitDependencyMask mask) { + MountParameters *p) { const char *after, *before, *e; int r; @@ -501,23 +496,25 @@ static int mount_add_default_ordering_dependencies( } if (!mount_is_nofail(m)) { - r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, mask); + r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; } if (after) { - r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, mask); + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; } return unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, - SPECIAL_UMOUNT_TARGET, true, mask); + SPECIAL_UMOUNT_TARGET, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); } static int mount_add_default_dependencies(Mount *m) { - UnitDependencyMask mask; MountParameters *p; int r; @@ -537,9 +534,7 @@ static int mount_add_default_dependencies(Mount *m) { if (!p) return 0; - mask = m->from_fragment ? UNIT_DEPENDENCY_FILE : UNIT_DEPENDENCY_MOUNTINFO_DEFAULT; - - r = mount_add_default_ordering_dependencies(m, p, mask); + r = mount_add_default_ordering_dependencies(m, p); if (r < 0) return r; @@ -549,7 +544,8 @@ static int mount_add_default_dependencies(Mount *m) { * network.target, so that they are shut down only after this mount unit is * stopped. */ - r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, mask); + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; @@ -558,14 +554,17 @@ static int mount_add_default_dependencies(Mount *m) { * mounting network file systems, and whose purpose it is to delay this until the * network is "up". */ - r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, true, mask); + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, + SPECIAL_NETWORK_ONLINE_TARGET, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; } /* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */ if (streq_ptr(p->fstype, "tmpfs")) { - r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, mask); + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET, true, + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); if (r < 0) return r; } @@ -607,8 +606,18 @@ static int mount_verify(Mount *m) { static int mount_add_non_exec_dependencies(Mount *m) { int r; + assert(m); + /* Any dependencies based on /proc/self/mountinfo may be now stale. */ + unit_remove_dependencies(UNIT(m), + UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT | + UNIT_DEPENDENCY_MOUNTINFO_DEFAULT | + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE); + + if (!m->where) + return 0; + /* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies * resulting from the ExecContext and such. */ @@ -908,8 +917,9 @@ static void mount_enter_dead(Mount *m, MountResult f) { dynamic_creds_destroy(&m->dynamic_creds); - /* Any dependencies based on /proc/self/mountinfo are now stale */ - unit_remove_dependencies(UNIT(m), UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT | UNIT_DEPENDENCY_MOUNTINFO_DEFAULT); + /* Any dependencies based on /proc/self/mountinfo are now stale. Let's re-generate dependencies from + * .mount unit. */ + (void) mount_add_non_exec_dependencies(m); } static void mount_enter_mounted(Mount *m, MountResult f) { @@ -1674,9 +1684,6 @@ static int mount_setup_existing_unit( if (FLAGS_SET(flags, MOUNT_PROC_JUST_CHANGED)) { /* If things changed, then make sure that all deps are regenerated. Let's * first remove all automatic deps, and then add in the new ones. */ - - unit_remove_dependencies(u, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT | UNIT_DEPENDENCY_MOUNTINFO_DEFAULT); - r = mount_add_non_exec_dependencies(MOUNT(u)); if (r < 0) return r; diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c index 3897bdee7c4..797bf6c5ce9 100644 --- a/src/core/unit-serialize.c +++ b/src/core/unit-serialize.c @@ -592,6 +592,7 @@ static void print_unit_dependency_mask(FILE *f, const char *kind, UnitDependency { UNIT_DEPENDENCY_PATH, "path" }, { UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT, "mountinfo-implicit" }, { UNIT_DEPENDENCY_MOUNTINFO_DEFAULT, "mountinfo-default" }, + { UNIT_DEPENDENCY_MOUNTINFO_OR_FILE, "mountinfo-or-file" }, { UNIT_DEPENDENCY_PROC_SWAP, "proc-swap" }, { UNIT_DEPENDENCY_SLICE_PROPERTY, "slice-property" }, }; diff --git a/src/core/unit.h b/src/core/unit.h index 33884fc9916..4dabbb9a3c9 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -86,13 +86,17 @@ typedef enum UnitDependencyMask { * DefaultDependencies= and thus also involving configuration from UNIT_DEPENDENCY_FILE sources */ UNIT_DEPENDENCY_MOUNTINFO_DEFAULT = 1 << 6, + /* A dependency created because of data read from /proc/self/mountinfo, but fallback to unit configuration + * sources */ + UNIT_DEPENDENCY_MOUNTINFO_OR_FILE = 1 << 7, + /* A dependency created because of data read from /proc/swaps and no other configuration source */ - UNIT_DEPENDENCY_PROC_SWAP = 1 << 7, + UNIT_DEPENDENCY_PROC_SWAP = 1 << 8, /* A dependency for units in slices assigned by directly setting Slice= */ - UNIT_DEPENDENCY_SLICE_PROPERTY = 1 << 8, + UNIT_DEPENDENCY_SLICE_PROPERTY = 1 << 9, - _UNIT_DEPENDENCY_MASK_FULL = (1 << 9) - 1, + _UNIT_DEPENDENCY_MASK_FULL = (1 << 10) - 1, } UnitDependencyMask; /* The Unit's dependencies[] hashmaps use this structure as value. It has the same size as a void pointer, and thus can