1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-19 21:57:27 +03:00

mount: Include After=local-fs-pre.target by default in initrd

Although it may be true that /sysroot and its children don't belong in
local-fs.target, that doesn't mean they shouldn't come after
local-fs-pre.target. For instance, systemd-hibernate-resume@.service needs to
come before /sysroot and its children, but currently that only happens
coincidentally because of the ordering between systemd-fsck@.service and
local-fs-pre.target. As a result, mount units can be mistakenly started
simultaneously with systemd-hibernate-resume@.service, which can cause
corruption and data loss in the worst of cases.

(cherry picked from commit 6e017b19a804639101fc87b4b78c02f7639c6d0c)
(cherry picked from commit c7280b7c1f2bfeb4054c17eecd8a70f022115c32)
This commit is contained in:
Will Fancher 2023-02-07 22:00:38 -05:00 committed by Zbigniew Jędrzejewski-Szmek
parent 35f3b83cd6
commit ad061062eb

View File

@ -484,13 +484,16 @@ static int mount_add_default_ordering_dependencies(Mount *m, MountParameters *p,
if (e && in_initrd()) {
/* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW,
* it's not technically part of the basic initrd filesystem itself, and so
* shouldn't inherit the default Before=local-fs.target dependency. */
* shouldn't inherit the default Before=local-fs.target dependency. However,
* these mounts still need to start after local-fs-pre.target, as a sync point
* for things like systemd-hibernate-resume@.service that should start before
* any mounts. */
after = NULL;
after = SPECIAL_LOCAL_FS_PRE_TARGET;
before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
} else if (in_initrd() && path_startswith(m->where, "/sysusr/usr")) {
after = NULL;
after = SPECIAL_LOCAL_FS_PRE_TARGET;
before = SPECIAL_INITRD_USR_FS_TARGET;
} else if (mount_is_network(p)) {
@ -508,11 +511,9 @@ static int mount_add_default_ordering_dependencies(Mount *m, MountParameters *p,
return r;
}
if (after) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, /* add_reference= */ true, mask);
if (r < 0)
return r;
}
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, /* add_reference= */ true, mask);
if (r < 0)
return r;
return unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
/* add_reference= */ true, mask);