]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount: Include After=local-fs-pre.target by default in initrd
authorWill Fancher <elvishjerricco@gmail.com>
Wed, 8 Feb 2023 03:00:38 +0000 (22:00 -0500)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 10 Mar 2023 17:10:41 +0000 (02:10 +0900)
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.

src/core/mount.c

index a833adc1dedd7d67ebf2a4218401810a54531b83..bbe22269469ffe77e641e16632f8cf31b6388067 100644 (file)
@@ -485,13 +485,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)) {
@@ -509,11 +512,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);