From 22e54dd6de4d0be41ab70e0a94d7bd273e47c60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 15 Jul 2022 20:46:04 +0200 Subject: [PATCH 1/8] booctl: do not say uuids differ if one of the uuids is unset We allow ESP autodetection to fail, e.g. if it is not mounted, but then we'd say that the detected one is different than the one reported by the bootloader, which is rather confusing. While at it, if we actually detect a mismatch, print the two uuids. --- src/boot/bootctl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index c09c305b3f3..4907b3ce3de 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -1784,8 +1784,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); From 4e9102417725621b813b866131178b132cfef195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 16 Jul 2022 10:20:34 +0200 Subject: [PATCH 2/8] gpt-auto-generator: include device name in error --- src/gpt-auto-generator/gpt-auto-generator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 33e1a20de6f..fa56a8322d4 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); From 8e34fdbd91265bb8e2d57365ec10b77bb2b604e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 20 Jul 2022 11:55:00 +0200 Subject: [PATCH 3/8] various: reword message --- src/fsck/fsck.c | 2 +- src/initctl/initctl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index b7fe729836e..f5f8a10c570 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/initctl/initctl.c b/src/initctl/initctl.c index a48a8570c47..52b1ba199a1 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, From 6ce4de290fe4add778ef6cc778b8abd6af21471f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 15 Jul 2022 09:04:41 +0200 Subject: [PATCH 4/8] man: make bootup charts narrower docbook already indents diagrams, so there is no need to leave whitespace on the left. Also, make the charts a bit narrower to fit better on a terminal. --- man/bootup.xml | 213 +++++++++++++++++++++++++------------------------ 1 file changed, 110 insertions(+), 103 deletions(-) diff --git a/man/bootup.xml b/man/bootup.xml index b29e494ee99..6c69c8a9bd9 100644 --- a/man/bootup.xml +++ b/man/bootup.xml @@ -174,30 +174,30 @@ emergency.service | | | available to the user. - (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 - default.target graphical-session.target + (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 + default.target graphical-session.target - + Bootup in the Initial RAM Disk (initrd) @@ -239,59 +239,59 @@ emergency.service | | | /sysroot. - : (beginning identical to above) - : - v - basic.target - | emergency.service - ______________________/| | - / | v - | initrd-root-device.target emergency.target - | | - | 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 + : (beginning identical to above) + : + v + basic.target + | emergency.service + ______________________/| | + / | v + | initrd-root-device.target emergency.target + | | + | 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 @@ -300,33 +300,40 @@ emergency.service | | | System shutdown with systemd also consists of various target units with some minimal ordering structure applied: - (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 - reboot.target poweroff.target halt.target kexec.target + (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 | + reboot.target | systemd-halt.service | + v | v + poweroff.target | systemd-kexec.service + v | + halt.target | + v + kexec.target Commonly used system shutdown targets are emphasized. From 5df2a4a6e0b3e8574e067d0252b954a5e002e751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Jul 2022 22:29:00 +0200 Subject: [PATCH 5/8] Use a common define for the reload timeout --- src/basic/def.h | 5 +++++ src/portable/portablectl.c | 2 +- src/sulogin-shell/sulogin-shell.c | 7 ++----- src/systemctl/systemctl-daemon-reload.c | 8 ++------ 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/basic/def.h b/src/basic/def.h index 0a1ae023a37..2b4de29021a 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/portable/portablectl.c b/src/portable/portablectl.c index 0fc3a64d71c..4005a5c796d 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 148e8acd73e..718cf37607f 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -34,11 +34,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 33de7d161e2..4f025ac4d2e 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) From 028a981c005e90c36c269e28709bf25032c2e8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 14 Jul 2022 14:36:52 +0200 Subject: [PATCH 6/8] fstab-generator: add mode to check /sysroot/etc/fstab and maybe do daemon-reload The idea is that we can peek into /sysroot/etc/fstab and figure out if there's anything interesting there. We could use a separate binary for this, but we'd need to duplicate most of the logic that in systemd-fstab-generator. Thus I think it's nicer to make systemd-fstab-generator work as a multi-call binary. If called as systemd-sysroot-fstab-check, we look for units that we'd mount and call daemon-reload and initrd-fs.target/restart, similarly to what we did before, but in the process itself. --- meson.build | 4 + src/fstab-generator/fstab-generator.c | 118 ++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 8 deletions(-) diff --git a/meson.build b/meson.build index 5d7c8699fe0..e6e32050902 100644 --- a/meson.build +++ b/meson.build @@ -2298,6 +2298,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/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index da7ea627f15..e76de45a0fa 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -5,6 +5,8 @@ #include #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); From 45bcfcb36cec9bf810686ed956ff215ac1db07d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 14 Jul 2022 18:05:55 +0200 Subject: [PATCH 7/8] units/initrd-parse-etc.service: only start units that are required This makes use of the option switch that was added in the previous commit. We used a pretty big hammer on a relatively small nail: we would do daemon-reload and (in principle) allow any configuration to be changed. But in fact we only made use of this in systemd-fstab-generator. systemd-fstab-generator filters out all mountpoints except /usr and those marked with x-initrd.mount, i.e. on a big majority of systems it wouldn't do anything. Also, since systemd-fstab-generator first parses /proc/cmdline, and then initrd's /etc/fstab, and only then /sysroot/etc/fstab, configuration in the host would only matter if it the same mountpoint wasn't configured "earlier". So the config in the host could be used for new mountpoints, but it couldn't be used to amend configuration for existing mountpoints. And we wouldn't actually remount anything, so mountpoints that were already mounted wouldn't be affected, even if did change some config. In the new scheme, we will parse /sysroot/etc/fstab and explicitly start sysroot-usr.mount and other units that we just wrote. In most cases (as written above), this will actually result in no units being created or started. If the generator is invoked on a system with /sysroot/etc/fstab present, behaviour is not changed and we'll create units as before. This is needed so that if daemon-reload is later at some points, we don't "lose" those units. There's a minor bugfix here: we honour x-initrd.mount for swaps, but we wouldn't restart swap.target, i.e. the new swaps wouldn't necessarilly be pulled in immediately. --- TODO | 4 ---- ...-etc.service => initrd-parse-etc.service.in} | 17 ++++++++++++----- units/meson.build | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) rename units/{initrd-parse-etc.service => initrd-parse-etc.service.in} (56%) diff --git a/TODO b/TODO index 2ef618dda91..a09db24912f 100644 --- a/TODO +++ b/TODO @@ -1225,10 +1225,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/units/initrd-parse-etc.service b/units/initrd-parse-etc.service.in similarity index 56% rename from units/initrd-parse-etc.service rename to units/initrd-parse-etc.service.in index 38df7283558..5ac7a24bb01 100644 --- a/units/initrd-parse-etc.service +++ b/units/initrd-parse-etc.service.in @@ -8,17 +8,24 @@ # (at your option) any later version. [Unit] -Description=Reload Configuration from the Real Root +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 -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={{ROOTLIBEXECDIR}}/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 40f784ec683..2010a5566f0 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'], From db5276215ae496074c163fca4014baf1bcd05984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Aug 2022 15:51:14 +0200 Subject: [PATCH 8/8] initrd-parse-etc: override argv[0] to avoid dracut issue Quoting https://github.com/systemd/systemd/pull/24054#issuecomment-1210501631: > this would need a patch in dracut, specifically adding the > systemd-sysroot-fstab-check to the list of installed stuff: > https://github.com/dracutdevs/dracut/blob/fe8fa2b0cadbb33e27c8dd8b5851548dcd65835c/modules.d/00systemd/module-setup.sh#L47. > > I could do this manually in the CI (and I guess I'd have to do it anyway even > if the patch lands in upstream, since it won't be available in C8S), but it > should get there first before merging this PR, otherwise it's going to break > Rawhide. --- units/initrd-parse-etc.service.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/units/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in index 5ac7a24bb01..fe0e860150c 100644 --- a/units/initrd-parse-etc.service.in +++ b/units/initrd-parse-etc.service.in @@ -21,7 +21,9 @@ OnFailureJobMode=replace-irreversibly [Service] Type=oneshot -ExecStart={{ROOTLIBEXECDIR}}/systemd-sysroot-fstab-check +# 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