diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-04-07 10:57:19 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-04-21 18:32:29 +0200 |
commit | 2b66f48e4ed86c65113730a4433acdb8b888b470 (patch) | |
tree | 8bdf4072921ce524adc18c82f865c721be86b07d /src/shared/generator.c | |
parent | Merge pull request #19362 from yuwata/network-dhcp6-pd-log-19354 (diff) | |
download | systemd-2b66f48e4ed86c65113730a4433acdb8b888b470.tar.xz systemd-2b66f48e4ed86c65113730a4433acdb8b888b470.zip |
generator: write out special systemd-fsck-usr.service
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.
Diffstat (limited to '')
-rw-r--r-- | src/shared/generator.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/src/shared/generator.c b/src/shared/generator.c index 5b9c432527..ef1188d013 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -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 |