summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2022-08-18 13:15:14 +0000
committerGitHub <noreply@github.com>2022-08-18 13:15:14 +0000
commitcd7ad0cbde507b9b43cf7e1797ce75e98345f4a0 (patch)
tree387b38db43b4acbbb91158a1bc59002e0f91bf66
parent0a152619aca5b6c16d022cc3e6ab2fc3786d0284 (diff)
parentdb5276215ae496074c163fca4014baf1bcd05984 (diff)
downloadsystemd-cd7ad0cbde507b9b43cf7e1797ce75e98345f4a0.tar.gz
Merge pull request #24054 from keszybz/initrd-no-reload
Don't do daemon-reload in the initrd
-rw-r--r--TODO4
-rw-r--r--man/bootup.xml215
-rw-r--r--meson.build4
-rw-r--r--src/basic/def.h5
-rw-r--r--src/boot/bootctl.c7
-rw-r--r--src/fsck/fsck.c2
-rw-r--r--src/fstab-generator/fstab-generator.c118
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c3
-rw-r--r--src/initctl/initctl.c2
-rw-r--r--src/portable/portablectl.c2
-rw-r--r--src/sulogin-shell/sulogin-shell.c7
-rw-r--r--src/systemctl/systemctl-daemon-reload.c8
-rw-r--r--units/initrd-parse-etc.service24
-rw-r--r--units/initrd-parse-etc.service.in33
-rw-r--r--units/meson.build2
15 files changed, 278 insertions, 158 deletions
diff --git a/TODO b/TODO
index 1d155910d0..6a04978b53 100644
--- a/TODO
+++ b/TODO
@@ -1306,10 +1306,6 @@ Features:
* fstab-generator: default to tmpfs-as-root if only usr= is specified on the kernel cmdline
-* initrd-parse-etc.service: can we skip daemon-reload if /sysroot/etc/fstab is missing?
- Note that we start initrd-fs.target and initrd-cleanup.target there, so a straightforward
- ConditionPathExists= is not enough.
-
* docs: bring https://www.freedesktop.org/wiki/Software/systemd/MyServiceCantGetRealtime up to date
* add a job mode that will fail if a transaction would mean stopping
diff --git a/man/bootup.xml b/man/bootup.xml
index b29e494ee9..6c69c8a9bd 100644
--- a/man/bootup.xml
+++ b/man/bootup.xml
@@ -174,30 +174,30 @@ emergency.service | | |
available to the user.</para>
<programlisting>
- (various (various (various
- timers...) paths...) sockets...) (sound devices)
- | | | |
- v v v v
- timers.target paths.target sockets.target sound.target
- | | |
- \______________ _|_________________/ (bluetooth devices)
- \ / |
- V v
- basic.target bluetooth.target
- |
- __________/ \_______ (smartcard devices)
- / \ |
- | | v
- | v smartcard.target
- v graphical-session-pre.target
- (various user services) | (printers)
- | v |
- | (services for the graphical session) v
- | | printer.target
- v v
- <emphasis>default.target</emphasis> graphical-session.target</programlisting>
-
- </refsect1>
+ (various (various (various
+ timers...) paths...) sockets...) (sound devices)
+ | | | |
+ v v v v
+ timers.target paths.target sockets.target sound.target
+ | | |
+ \______________ _|_________________/ (bluetooth devices)
+ \ / |
+ V v
+ basic.target bluetooth.target
+ |
+ __________/ \_______ (smartcard devices)
+ / \ |
+ | | v
+ | v smartcard.target
+ v graphical-session-pre.target
+(various user services) | (printers)
+ | v |
+ | (services for the graphical session) v
+ | | printer.target
+ v v
+ <emphasis>default.target</emphasis> graphical-session.target</programlisting>
+
+ </refsect1>
<refsect1>
<title>Bootup in the Initial RAM Disk (initrd)</title>
@@ -239,59 +239,59 @@ emergency.service | | |
<filename>/sysroot</filename>.
</para>
-<programlisting> : (beginning identical to above)
- :
- v
- basic.target
- | emergency.service
- ______________________/| |
- / | v
- | initrd-root-device.target <emphasis>emergency.target</emphasis>
- | |
- | v
- | sysroot.mount
- | |
- | v
- | initrd-root-fs.target
- | |
- | v
- v initrd-parse-etc.service
- (custom initrd |
- services...) v
- | (sysroot-usr.mount and
- | various mounts marked
- | with fstab option
- | x-initrd.mount...)
- | |
- | v
- | initrd-fs.target
- \______________________ |
- \|
- v
- initrd.target
- |
- v
- initrd-cleanup.service
- isolates to
- initrd-switch-root.target
- |
- v
- ______________________/|
- / v
- | initrd-udevadm-cleanup-db.service
- v |
- (custom initrd |
- services...) |
- \______________________ |
- \|
- v
- initrd-switch-root.target
- |
- v
- initrd-switch-root.service
- |
- v
- Transition to Host OS</programlisting>
+<programlisting> : (beginning identical to above)
+ :
+ v
+ basic.target
+ | emergency.service
+ ______________________/| |
+ / | v
+ | initrd-root-device.target <emphasis>emergency.target</emphasis>
+ | |
+ | v
+ | sysroot.mount
+ | |
+ | v
+ | initrd-root-fs.target
+ | |
+ | v
+ v initrd-parse-etc.service
+(custom initrd |
+ services...) v
+ | (sysroot-usr.mount and
+ | various mounts marked
+ | with fstab option
+ | x-initrd.mount...)
+ | |
+ | v
+ | initrd-fs.target
+ \______________________ |
+ \|
+ v
+ initrd.target
+ |
+ v
+ initrd-cleanup.service
+ isolates to
+ initrd-switch-root.target
+ |
+ v
+ ______________________/|
+ / v
+ | initrd-udevadm-cleanup-db.service
+ v |
+(custom initrd |
+ services...) |
+ \______________________ |
+ \|
+ v
+ initrd-switch-root.target
+ |
+ v
+ initrd-switch-root.service
+ |
+ v
+ Transition to Host OS</programlisting>
</refsect1>
<refsect1>
@@ -300,33 +300,40 @@ emergency.service | | |
<para>System shutdown with systemd also consists of various target
units with some minimal ordering structure applied:</para>
-<programlisting> (conflicts with (conflicts with
- all system all file system
- services) mounts, swaps,
- | cryptsetup/
- | veritysetup
- | devices, ...)
- | |
- v v
- shutdown.target umount.target
- | |
- \_______ ______/
- \ /
- v
- (various low-level
- services)
- |
- v
- final.target
- |
- _____________________________________/ \_________________________________
- / | | \
- | | | |
- v v v v
-systemd-reboot.service systemd-poweroff.service systemd-halt.service systemd-kexec.service
- | | | |
- v v v v
- <emphasis>reboot.target</emphasis> <emphasis>poweroff.target</emphasis> <emphasis>halt.target</emphasis> <emphasis>kexec.target</emphasis></programlisting>
+<programlisting> (conflicts with (conflicts with
+ all system all file system
+ services) mounts, swaps,
+ | cryptsetup/
+ | veritysetup
+ | devices, ...)
+ | |
+ v v
+ shutdown.target umount.target
+ | |
+ \_______ ______/
+ \ /
+ v
+ (various low-level
+ services)
+ |
+ v
+ final.target
+ |
+ ___________________________/ \_________________
+ / | | \
+ | | | |
+ v | | |
+systemd-reboot.service | | |
+ | v | |
+ | systemd-poweroff.service | |
+ v | v |
+ <emphasis>reboot.target</emphasis> | systemd-halt.service |
+ v | v
+ <emphasis>poweroff.target</emphasis> | systemd-kexec.service
+ v |
+ <emphasis>halt.target</emphasis> |
+ v
+ <emphasis>kexec.target</emphasis></programlisting>
<para>Commonly used system shutdown targets are <emphasis>emphasized</emphasis>.</para>
diff --git a/meson.build b/meson.build
index a7e3e87744..aa2ae27a93 100644
--- a/meson.build
+++ b/meson.build
@@ -2324,6 +2324,10 @@ exe = executable(
install : true,
install_dir : systemgeneratordir)
+meson.add_install_script(meson_make_symlink,
+ systemgeneratordir / 'systemd-fstab-generator',
+ rootlibexecdir / 'systemd-sysroot-fstab-check')
+
if want_tests != 'false'
test('test-fstab-generator',
test_fstab_generator_sh,
diff --git a/src/basic/def.h b/src/basic/def.h
index 0a1ae023a3..2b4de29021 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -5,6 +5,11 @@
#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
+/* We use an extra-long timeout for the reload. This is because a reload or reexec means generators are rerun
+ * which are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can
+ * have their timeout, and for everything else there's the same time budget in place. */
+#define DAEMON_RELOAD_TIMEOUT_SEC (DEFAULT_TIMEOUT_USEC * 2)
+
#define DEFAULT_START_LIMIT_INTERVAL (10*USEC_PER_SEC)
#define DEFAULT_START_LIMIT_BURST 5
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index f04463157a..10da1c8d7f 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -1838,8 +1838,11 @@ static int verb_status(int argc, char *argv[], void *userdata) {
bool have_bootloader_esp_uuid = efi_loader_get_device_part_uuid(&bootloader_esp_uuid) >= 0;
print_yes_no_line(false, have_bootloader_esp_uuid, "Boot loader sets ESP information");
- if (have_bootloader_esp_uuid && !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
- printf("WARNING: The boot loader reports a different ESP UUID than detected!\n");
+ if (have_bootloader_esp_uuid && !sd_id128_is_null(esp_uuid) &&
+ !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
+ printf("WARNING: The boot loader reports a different ESP UUID than detected ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
+ SD_ID128_FORMAT_VAL(bootloader_esp_uuid),
+ SD_ID128_FORMAT_VAL(esp_uuid));
if (stub) {
printf(" Stub: %s\n", stub);
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index b7fe729836..f5f8a10c57 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -52,7 +52,7 @@ static void start_target(const char *target, const char *mode) {
return;
}
- log_info("Running request %s/start/%s", target, mode);
+ log_info("Requesting %s/start/%s", target, mode);
/* Start this unit only if we can replace basic.target with it */
r = sd_bus_call_method(bus,
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index da7ea627f1..e76de45a0f 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -5,6 +5,8 @@
#include <unistd.h>
#include "alloc-util.h"
+#include "bus-error.h"
+#include "bus-locator.h"
#include "chase-symlinks.h"
#include "fd-util.h"
#include "fileio.h"
@@ -20,6 +22,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
+#include "process-util.h"
#include "special.h"
#include "specifier.h"
#include "stat-util.h"
@@ -39,6 +42,7 @@ typedef enum MountPointFlags {
MOUNT_RW_ONLY = 1 << 5,
} MountPointFlags;
+static bool arg_sysroot_check = false;
static const char *arg_dest = NULL;
static const char *arg_dest_late = NULL;
static bool arg_fstab_enabled = true;
@@ -119,6 +123,11 @@ static int add_swap(
return 0;
}
+ if (arg_sysroot_check) {
+ log_info("%s should be enabled in the initrd, will request daemon-reload.", what);
+ return true;
+ }
+
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@@ -175,7 +184,7 @@ static int add_swap(
return r;
}
- return 0;
+ return true;
}
static bool mount_is_network(struct mntent *me) {
@@ -378,6 +387,11 @@ static int add_mount(
mount_point_ignore(where))
return 0;
+ if (arg_sysroot_check) {
+ log_info("%s should be mounted in the initrd, will request daemon-reload.", where);
+ return true;
+ }
+
r = fstab_filter_options(opts, "x-systemd.wanted-by\0", NULL, NULL, &wanted_by, NULL);
if (r < 0)
return r;
@@ -567,7 +581,52 @@ static int add_mount(
return r;
}
- return 0;
+ return true;
+}
+
+static int do_daemon_reload(void) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r, k;
+
+ log_debug("Calling org.freedesktop.systemd1.Manager.Reload()...");
+
+ r = bus_connect_system_systemd(&bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get D-Bus connection: %m");
+
+ r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "Reload");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
+
+ /* We need to requeue the two targets so that any new units which previously were not part of the
+ * targets, and which we now added, will be started. */
+
+ r = 0;
+ FOREACH_STRING(unit, SPECIAL_INITRD_FS_TARGET, SPECIAL_SWAP_TARGET) {
+ log_info("Requesting %s/start/replace...", unit);
+
+ k = sd_bus_call_method(bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartUnit",
+ &error,
+ NULL,
+ "ss", unit, "replace");
+ if (k < 0) {
+ log_error_errno(k, "Failed to (re)start %s: %s", unit, bus_error_message(&error, r));
+ if (r == 0)
+ r = k;
+ }
+ }
+
+ return r;
}
static const char* sysroot_fstab_path(void) {
@@ -582,8 +641,10 @@ static int parse_fstab(bool initrd) {
if (initrd)
fstab = sysroot_fstab_path();
- else
+ else {
fstab = fstab_path();
+ assert(!arg_sysroot_check);
+ }
log_debug("Parsing %s...", fstab);
@@ -700,6 +761,8 @@ static int parse_fstab(bool initrd) {
target_unit);
}
+ if (arg_sysroot_check && k > 0)
+ return true; /* We found a mount or swap that would be started… */
if (r >= 0 && k < 0)
r = k;
}
@@ -1126,12 +1189,14 @@ static int determine_usr(void) {
return determine_device(&arg_usr_what, arg_usr_hash, "usr");
}
-static int run(const char *dest, const char *dest_early, const char *dest_late) {
+/* If arg_sysroot_check is false, run as generator in the usual fashion.
+ * If it is true, check /sysroot/etc/fstab for any units that we'd want to mount
+ * in the initrd, and call daemon-reload. We will get reinvoked as a generator,
+ * with /sysroot/etc/fstab available, and then we can write additional units based
+ * on that file. */
+static int run_generator(void) {
int r, r2 = 0, r3 = 0;
- assert_se(arg_dest = dest);
- assert_se(arg_dest_late = dest_late);
-
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -1139,6 +1204,15 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
(void) determine_root();
(void) determine_usr();
+ if (arg_sysroot_check) {
+ r = parse_fstab(true);
+ if (r == 0)
+ log_debug("Nothing interesting found, not doing daemon-reload.");
+ if (r > 0)
+ r = do_daemon_reload();
+ return r;
+ }
+
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
r = add_sysroot_mount();
@@ -1164,4 +1238,32 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
return r < 0 ? r : r2 < 0 ? r2 : r3;
}
-DEFINE_MAIN_GENERATOR_FUNCTION(run);
+static int run(int argc, char **argv) {
+ arg_sysroot_check = invoked_as(argv, "systemd-sysroot-fstab-check");
+
+ if (arg_sysroot_check) {
+ /* Run as in systemd-sysroot-fstab-check mode */
+ log_setup();
+
+ if (strv_length(argv) > 1)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "This program takes no arguments.");
+ if (!in_initrd())
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "This program is only useful in the initrd.");
+ } else {
+ /* Run in generator mode */
+ log_setup_generator();
+
+ if (!IN_SET(strv_length(argv), 2, 4))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "This program takes one or three arguments.");
+
+ arg_dest = ASSERT_PTR(argv[1]);
+ arg_dest_late = ASSERT_PTR(argv[argc > 3 ? 3 : 1]);
+ }
+
+ return run_generator();
+}
+
+DEFINE_MAIN_FUNCTION(run);
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 33e1a20de6..fa56a8322d 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -53,7 +53,8 @@ static int open_parent_block_device(dev_t devnum, int *ret_fd) {
r = sd_device_new_from_devnum(&d, 'b', devnum);
if (r < 0)
- return log_debug_errno(r, "Failed to open device: %m");
+ return log_debug_errno(r, "Failed to create device object for block device "DEVNUM_FORMAT_STR": %m",
+ DEVNUM_FORMAT_VAL(devnum));
if (sd_device_get_devname(d, &name) < 0) {
r = sd_device_get_syspath(d, &name);
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index a48a8570c4..52b1ba199a 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -103,7 +103,7 @@ static int change_runlevel(Server *s, int runlevel) {
else
mode = "replace-irreversibly";
- log_debug("Running request %s/start/%s", target, mode);
+ log_debug("Requesting %s/start/%s", target, mode);
r = sd_bus_call_method(
s->bus,
diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c
index f46260307a..c3c22220c2 100644
--- a/src/portable/portablectl.c
+++ b/src/portable/portablectl.c
@@ -249,7 +249,7 @@ static int maybe_reload(sd_bus **bus) {
return bus_log_create_error(r);
/* Reloading the daemon may take long, hence set a longer timeout here */
- r = sd_bus_call(*bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
+ r = sd_bus_call(*bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
if (r < 0)
return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c
index 06f17c6a8e..5648dfd83b 100644
--- a/src/sulogin-shell/sulogin-shell.c
+++ b/src/sulogin-shell/sulogin-shell.c
@@ -33,11 +33,8 @@ static int reload_manager(sd_bus *bus) {
if (r < 0)
return bus_log_create_error(r);
- /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
- * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
- * their timeout, and for everything else there's the same time budget in place. */
-
- r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
+ /* Reloading the daemon may take long, hence set a longer timeout here */
+ r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
if (r < 0)
return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
diff --git a/src/systemctl/systemctl-daemon-reload.c b/src/systemctl/systemctl-daemon-reload.c
index 33de7d161e..4f025ac4d2 100644
--- a/src/systemctl/systemctl-daemon-reload.c
+++ b/src/systemctl/systemctl-daemon-reload.c
@@ -37,12 +37,8 @@ int daemon_reload(enum action action, bool graceful) {
if (r < 0)
return bus_log_create_error(r);
- /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are
- * rerun which are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the
- * generators can have their timeout, and for everything else there's the same time budget in
- * place. */
-
- r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
+ /* Reloading the daemon may take long, hence set a longer timeout here */
+ r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
/* On reexecution, we expect a disconnect, not a reply */
if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && action == ACTION_REEXEC)
diff --git a/units/initrd-parse-etc.service b/units/initrd-parse-etc.service
deleted file mode 100644
index 38df728355..0000000000
--- a/units/initrd-parse-etc.service
+++ /dev/null
@@ -1,24 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-#
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Reload Configuration from the Real Root
-DefaultDependencies=no
-Requires=initrd-root-fs.target
-After=initrd-root-fs.target
-OnFailure=emergency.target
-OnFailureJobMode=replace-irreversibly
-AssertPathExists=/etc/initrd-release
-
-[Service]
-Type=oneshot
-ExecStartPre=-systemctl daemon-reload
-# we have to retrigger initrd-fs.target after daemon-reload
-ExecStart=-systemctl --no-block start initrd-fs.target
-ExecStart=systemctl --no-block start initrd-cleanup.service
diff --git a/units/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in
new file mode 100644
index 0000000000..fe0e860150
--- /dev/null
+++ b/units/initrd-parse-etc.service.in
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Mountpoints Configured in the Real Root
+AssertPathExists=/etc/initrd-release
+
+DefaultDependencies=no
+Requires=initrd-root-fs.target
+After=initrd-root-fs.target
+
+OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
+
+[Service]
+Type=oneshot
+
+# FIXME: once dracut is patched to install the symlink, change to:
+# ExecStart={{ROOTLIBEXECDIR}}/systemd-sysroot-fstab-check
+ExecStart=@{{SYSTEM_GENERATOR_DIR}}/systemd-fstab-generator systemd-sysroot-fstab-check
+
+# We want to enqueue initrd-cleanup.service/start after we finished the part
+# above. It can't be part of the initial transaction, because non-oneshot units
+# use Conflicts=initrd-cleanup.service to be terminated before we switch root.
+# Effectively, initrd-parse-etc.service acts as a synchronization point after
+# which cleanup of the initrd processes starts.
+ExecStart=systemctl --no-block start initrd-cleanup.service
diff --git a/units/meson.build b/units/meson.build
index 40f784ec68..2010a5566f 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -36,7 +36,6 @@ units = [
['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'],
['initrd-cleanup.service', 'ENABLE_INITRD'],
['initrd-fs.target', 'ENABLE_INITRD'],
- ['initrd-parse-etc.service', 'ENABLE_INITRD'],
['initrd-root-device.target', 'ENABLE_INITRD'],
['initrd-root-fs.target', 'ENABLE_INITRD'],
['initrd-switch-root.service', 'ENABLE_INITRD'],
@@ -179,6 +178,7 @@ in_units = [
['emergency.service', ''],
['getty@.service', '',
'autovt@.service'],
+ ['initrd-parse-etc.service', 'ENABLE_INITRD'],
['kmod-static-nodes.service', 'HAVE_KMOD ENABLE_TMPFILES',
'sysinit.target.wants/'],
['quotaon.service', 'ENABLE_QUOTACHECK'],