summaryrefslogtreecommitdiff
path: root/src/shared/generator.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-04-07 10:57:19 +0200
committerLennart Poettering <lennart@poettering.net>2021-04-21 18:32:29 +0200
commit2b66f48e4ed86c65113730a4433acdb8b888b470 (patch)
tree8bdf4072921ce524adc18c82f865c721be86b07d /src/shared/generator.c
parent1f2a7ca7aca6f2775069b20afee19d786aff6ddf (diff)
downloadsystemd-2b66f48e4ed86c65113730a4433acdb8b888b470.tar.gz
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 'src/shared/generator.c')
-rw-r--r--src/shared/generator.c45
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