From 15d18f930e152cc59b6c4ca30ed848e9d414ab08 Mon Sep 17 00:00:00 2001 From: hygienic-books Date: Sat, 13 Dec 2025 16:57:59 +0100 Subject: [PATCH] fix(base): Load udev initramfs hook (#28) This replaces the modern Arch Linux default hook of 'systemd' with 'udev' which allows a clean boot of a boot environment via ZFSBootMenu. --- setup.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/setup.sh b/setup.sh index 9764f5e..bb9fff3 100644 --- a/setup.sh +++ b/setup.sh @@ -936,8 +936,49 @@ function add_zfs_hook_to_initramfs () { '/mnt/etc/mkinitcpio.conf' } -function set_initramfs_build_list () { +function replace_systemd_initramfs_with_udev () { #1.17 + # Replace systemd-boot hooks with udev hooks in initramfs. For some odd + # reason we have not yet understood the modern default on a fresh Arch + # Linux installation ('systemd' and 'sd-vconsole' hooks) doesn't cleanly + # boot into a boot environment via ZFSBootMenu. + # + # 1. If we left both hooks in place we'd see an error related + # to '/dev/gpt-auto-root'; that can be worked around by loading the 'vfat' + # module via the 'MODULES=(...)' array in '/etc/mkinitcpio.conf'. + # + # 2. On next try we see the system failing into an emergency shell at a + # later point in initramfs execution due to a failure with + # 'initrd-switch-root.service'. Since the 'systemd' hook disables the + # 'root' account we enter a non-functional emergency shell. See + # https://wiki.archlinux.org/title/Mkinitcpio section 6.7 "Cannot open + # access to console, the root account is locked" where we learn that we can + # install AUR package initcpio-hook-shadowcopy and load the 'shadowcopy' + # hook right after the 'systemd' hook in order to get a fully functional + # emergency shell. + # + # 3. On next try 'initrd-switch-root.service' fails into a functional + # emergency shell which allows us to check systemd status of + # 'initrd-switch-root.service'. This seems to tell us that '/sysroot' is + # wanted but missing which appears to be true. + # + # At this point in December 2025 we stopped investigating how to properly + # pair 'systemd' and 'sd-vconsole' hooks with ZFSBootMenu. We're instead + # replacing both as follows: + # + # systemd <--> udev + # sd-vconsole <--> consolefont + # + # This cleanly boots a boot environment. Further investigation may be + # warranted at a later date. For now this workaround is good enough. + in_file_in_array_insert_n_before_m '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'udev' 'systemd' + in_file_in_array_remove_n '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'systemd' + in_file_in_array_insert_n_before_m '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'consolefont' 'sd-vconsole' + in_file_in_array_remove_n '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'sd-vconsole' +} + +function set_initramfs_build_list () { + #1.18 # No need to build fallback initramfs, our new fallback is ZFS snapshots sed -ri \ -e '/^#/d' \ @@ -951,7 +992,7 @@ function set_initramfs_build_list () { } function add_zfs_files_to_new_os () { - #1.18 + #1.19 for zfs_file in '/etc/hostid' '/etc/zfs/zpool.cache' $([[ ! "${ARCHZBM_ZFSPROPS_NO_ENCRYPTION}" ]] && printf -- '%s' '/etc/zfs/'"${zpool_name}"'.key'); do rsync -av --itemize-changes {'','/mnt'}"${zfs_file}" done @@ -1579,8 +1620,9 @@ function main () { set_hostname #1.14 set_locale #1.15 add_zfs_hook_to_initramfs #1.16 - set_initramfs_build_list #1.17 - add_zfs_files_to_new_os #1.18 + replace_systemd_initramfs_with_udev #1.17 + set_initramfs_build_list #1.18 + add_zfs_files_to_new_os #1.19 enter_chroot #2.1 # We're done in chroot finalize_os_setup #3.1