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.
This commit is contained in:
2025-12-13 16:57:59 +01:00
parent bf46d15783
commit 15d18f930e

View File

@@ -936,8 +936,49 @@ function add_zfs_hook_to_initramfs () {
'/mnt/etc/mkinitcpio.conf' '/mnt/etc/mkinitcpio.conf'
} }
function set_initramfs_build_list () { function replace_systemd_initramfs_with_udev () {
#1.17 #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 # No need to build fallback initramfs, our new fallback is ZFS snapshots
sed -ri \ sed -ri \
-e '/^#/d' \ -e '/^#/d' \
@@ -951,7 +992,7 @@ function set_initramfs_build_list () {
} }
function add_zfs_files_to_new_os () { 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 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}" rsync -av --itemize-changes {'','/mnt'}"${zfs_file}"
done done
@@ -1579,8 +1620,9 @@ function main () {
set_hostname #1.14 set_hostname #1.14
set_locale #1.15 set_locale #1.15
add_zfs_hook_to_initramfs #1.16 add_zfs_hook_to_initramfs #1.16
set_initramfs_build_list #1.17 replace_systemd_initramfs_with_udev #1.17
add_zfs_files_to_new_os #1.18 set_initramfs_build_list #1.18
add_zfs_files_to_new_os #1.19
enter_chroot #2.1 enter_chroot #2.1
# We're done in chroot # We're done in chroot
finalize_os_setup #3.1 finalize_os_setup #3.1