]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
generator: write out special systemd-fsck-usr.service
authorLennart Poettering <lennart@poettering.net>
Wed, 7 Apr 2021 08:57:19 +0000 (10:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Apr 2021 16:32:29 +0000 (18:32 +0200)
So far all file systems where checked by instances of
systemd-fsck@.service, with the exception of the root fs which was
covered by systemd-fsck-root.service. The special handling is necessary
to deal with ordering issues: we typically want the root fs to be
checked before all others, and — weirdly — allow mounting it before the
fsck done (for compat with initrd-less boots).

This adds similar special handling for /usr: if the hierarchy is placed
on a separate file system check it with a special
systemd-fsck-usr.service instead of a regular sysemd-fsck@.service
instance. Reason is again ordering: we want to allow mounting of /usr
without the root fs already being around in the initrd, to cover for
cases where the root fs is created on first boot and thus cannot be
mounted/checked before /usr.

src/basic/special.h
src/shared/generator.c

index 841e8ad132355326127c385b3f3be9ea67dc269b..78f22f1ac918d4ef844a2230d5b85911ff1b0751 100644 (file)
@@ -80,6 +80,7 @@
 /* Magic early boot services */
 #define SPECIAL_FSCK_SERVICE "systemd-fsck@.service"
 #define SPECIAL_FSCK_ROOT_SERVICE "systemd-fsck-root.service"
+#define SPECIAL_FSCK_USR_SERVICE "systemd-fsck-usr.service"
 #define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service"
 #define SPECIAL_QUOTAON_SERVICE "quotaon.service"
 #define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"
index 5b9c43252714b7b891f88b823af9d82c5f75bd65..ef1188d0133b34d6ea3246fc531856768416eadb 100644 (file)
@@ -71,12 +71,22 @@ int generator_add_symlink(const char *dir, const char *dst, const char *dep_type
         return 0;
 }
 
-static int write_fsck_sysroot_service(const char *dir, const char *what) {
+static int write_fsck_sysroot_service(
+                const char *unit, /* Either SPECIAL_FSCK_ROOT_SERVICE or SPECIAL_FSCK_USR_SERVICE */
+                const char *dir,
+                const char *what,
+                const char *extra_after) {
+
         _cleanup_free_ char *device = NULL, *escaped = NULL, *escaped2 = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        const char *unit;
+        const char *fn;
         int r;
 
+        /* Writes out special versions of systemd-root-fsck.service and systemd-usr-fsck.service for use in
+         * the initrd. The regular statically shipped versions of these unit files use / and /usr for as
+         * paths, which doesn't match what we need for the initrd (where the dirs are /sysroot +
+         * /sysusr/usr), hence we overwrite those versions here. */
+
         escaped = specifier_escape(what);
         if (!escaped)
                 return log_oom();
@@ -85,41 +95,44 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
         if (!escaped2)
                 return log_oom();
 
-        unit = strjoina(dir, "/"SPECIAL_FSCK_ROOT_SERVICE);
-        log_debug("Creating %s", unit);
+        fn = strjoina(dir, "/", unit);
+        log_debug("Creating %s", fn);
 
         r = unit_name_from_path(what, ".device", &device);
         if (r < 0)
                 return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what);
 
-        f = fopen(unit, "wxe");
+        f = fopen(fn, "wxe");
         if (!f)
-                return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
+                return log_error_errno(errno, "Failed to create unit file %s: %m", fn);
 
         fprintf(f,
                 "# Automatically generated by %1$s\n\n"
                 "[Unit]\n"
                 "Description=File System Check on %2$s\n"
-                "Documentation=man:systemd-fsck-root.service(8)\n"
+                "Documentation=man:%3$s(8)\n"
                 "DefaultDependencies=no\n"
-                "BindsTo=%3$s\n"
+                "BindsTo=%4$s\n"
                 "Conflicts=shutdown.target\n"
-                "After=initrd-root-device.target local-fs-pre.target %3$s\n"
+                "After=%5$s%6$slocal-fs-pre.target %4$s\n"
                 "Before=shutdown.target\n"
                 "\n"
                 "[Service]\n"
                 "Type=oneshot\n"
                 "RemainAfterExit=yes\n"
-                "ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n"
+                "ExecStart=" SYSTEMD_FSCK_PATH " %7$s\n"
                 "TimeoutSec=0\n",
                 program_invocation_short_name,
                 escaped,
+                unit,
                 device,
+                strempty(extra_after),
+                isempty(extra_after) ? "" : " ",
                 escaped2);
 
         r = fflush_and_check(f);
         if (r < 0)
-                return log_error_errno(r, "Failed to write unit file %s: %m", unit);
+                return log_error_errno(r, "Failed to write unit file %s: %m", fn);
 
         return 0;
 }
@@ -168,12 +181,20 @@ int generator_write_fsck_deps(
                 const char *fsck, *dep;
 
                 if (in_initrd() && path_equal(where, "/sysroot")) {
-                        r = write_fsck_sysroot_service(dir, what);
+                        r = write_fsck_sysroot_service(SPECIAL_FSCK_ROOT_SERVICE, dir, what, SPECIAL_INITRD_ROOT_DEVICE_TARGET);
                         if (r < 0)
                                 return r;
 
                         fsck = SPECIAL_FSCK_ROOT_SERVICE;
                         dep = "Requires";
+
+                } else if (in_initrd() && path_equal(where, "/sysusr/usr")) {
+                        r = write_fsck_sysroot_service(SPECIAL_FSCK_USR_SERVICE, dir, what, NULL);
+                        if (r < 0)
+                                return r;
+
+                        fsck = SPECIAL_FSCK_USR_SERVICE;
+                        dep = "Requires";
                 } else {
                         /* When this is /usr, then let's add a Wants= dependency, otherwise a Requires=
                          * dependency. Why? We can't possibly unmount /usr during shutdown, but if we have a