From d2365fe1ebf19f45bab04a0011f662e52c61b43d Mon Sep 17 00:00:00 2001 From: Kai Lueke Date: Thu, 23 Oct 2025 23:38:56 +0900 Subject: [PATCH] initrd-setup-root: Use systemd-confext instead of custom overlay mount So far we had a custom overlay mount for /etc that provided the A/B updated files from /usr in a lowerdir. Since then we upstreamed a mutable mode for sysext and confext. We can now switch over to it and provide a default confext by using the mutable mode. Because there is no atomic remount yet and also because we want to avoid daemon reloads during boot, this relies on a new skip logic in systemd-sysext/confext to only refresh in the final system boot when changes are found. Through only using verity images we know that no changes can be there because they get compared by hash and not mtime. When we would hit a refresh during boot then /etc contents are shortly gone and services sometimes fail during boot. A bit specific to Flatcar/Ignition is that we load confext twice in the initrd, once because we have a default confext that provides /etc contents for Ignition and a second time for loading user confexts for the final system (when users added new ones through Ignition). Signed-off-by: Kai Lueke --- dracut/99setup-root/initrd-setup-root | 22 ++++++++++++++----- .../initrd-setup-root-after-ignition | 12 ++++++++++ dracut/99setup-root/module-setup.sh | 2 ++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/dracut/99setup-root/initrd-setup-root b/dracut/99setup-root/initrd-setup-root index 0a726b6..e37c8c7 100755 --- a/dracut/99setup-root/initrd-setup-root +++ b/dracut/99setup-root/initrd-setup-root @@ -32,8 +32,8 @@ COREOS_BLANK_MACHINE_ID="42000000000000000000000000000042" MACHINE_ID_FILE="/sysroot/etc/machine-id" # Allow to rerun the script -if usrbin mountpoint -q /sysroot/etc; then - umount /sysroot/etc +if SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot status | grep flatcar-default; then + SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot unmerge fi function selectiveosreset() { @@ -159,9 +159,21 @@ if [ ! -e "/sysroot/etc/.no-dup-update" ]; then walksysroot /etc overlaycleanup fi -# Set up overlay mount for /etc (as long as we can't use syscfg for that) -mkdir -p /sysroot/.etc-work -mount -t overlay overlay -o lowerdir=/sysroot/usr/share/flatcar/etc,upperdir=/sysroot/etc,workdir=/sysroot/.etc-work,redirect_dir=on,metacopy=off,noatime /sysroot/etc +# Set up overlay mount for /etc (done here until we have an upstream systemd unit doing it) +# This is done early here so that Ignition and the Flatcar extension fetching and A/B setup can use /etc +mkdir -p /sysroot/var/lib/extensions.mutable/ +if [ ! -L /sysroot/var/lib/extensions.mutable/etc ] && [ ! -e /sysroot/var/lib/extensions.mutable/etc ]; then + ln -s /etc /sysroot/var/lib/extensions.mutable/etc +fi +# Workaround until 259: Set SYSTEMD_IN_INITRD because even with --root= +# this would otherwise look for initrd extension metadata. +SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot merge +SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot status | grep flatcar-default || { echo "error: flatcar-default confext not loaded" ; exit 1 ; } +# Even when the planned sysext/confext .services units are there +# the above call should stay because we first need confext for Ignition +# to have default files but then we need to reload for any user confexts +# to be applied and we can later rely on the confext/sysext .services +# for that while the above call is specific to Flatcar/Ignition. # PXE initrds may provide OEM. Despite OEM partition being moved to # /oem in general, we keep checking /usr/share/oem in initrds to avoid diff --git a/dracut/99setup-root/initrd-setup-root-after-ignition b/dracut/99setup-root/initrd-setup-root-after-ignition index 38f6915..6c6af0e 100755 --- a/dracut/99setup-root/initrd-setup-root-after-ignition +++ b/dracut/99setup-root/initrd-setup-root-after-ignition @@ -166,3 +166,15 @@ for NAME in $(grep -h -o '^[^#]*' /sysroot/etc/flatcar/enabled-sysext.conf /sysr rm -f "/sysroot/etc/extensions/flatcar-${NAME}.raw" fi done + +# Here we load a second time so that any user-supplied configuration extensions are present at boot +SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot refresh +# Then for the first time we can also apply system extensions so that the final system has them at boot +# (done here until we have an upstream systemd unit doing it). +if [ $(readlink -f /sysroot/etc/systemd/system/systemd-sysext.service 2>/dev/null) != "/dev/null" ]; then + if ! SYSTEMD_IN_INITRD=0 systemd-sysext --root=/sysroot merge ; then + echo "ERROR: systemd-sysext failed to set up extensions in initrd, continuing boot" >&2 + fi +fi +# Once the planned sysext/confext .services units are there we can remove the two calls above and +# order them to start after initrd-setup-root-after-ignition.service (sysext after confext) diff --git a/dracut/99setup-root/module-setup.sh b/dracut/99setup-root/module-setup.sh index 57c27a8..00c83b9 100755 --- a/dracut/99setup-root/module-setup.sh +++ b/dracut/99setup-root/module-setup.sh @@ -21,4 +21,6 @@ install() { "${systemdsystemunitdir}/initrd-setup-root-after-ignition.service" inst_script "$moddir/gpg-agent-wrapper" \ "/usr/bin/gpg-agent" + + inst_multiple systemd-sysext systemd-confext }