From 206f59eaa6b87a2e6a0228f92bd77812feab51d6 Mon Sep 17 00:00:00 2001 From: Tao Liu Date: Wed, 31 May 2023 15:11:31 +0800 Subject: [PATCH] kdumpctl: Add basic UKI support Resolves: bz2169720 Upstream: src.fedoraproject.org/rpms/kexec-tools.git Conflicts: Small context difference in kexec-tools.spec commit ea7be0608ed719cc1cb134ecf6ef51a4b7e9f104 Author: Philipp Rudo Date: Fri May 5 17:14:42 2023 +0200 kdumpctl: Add basic UKI support A Unified Kernel Image (UKI) is a single EFI PE executable combining an EFI stub, a kernel image, an initrd image, and the kernel command line. They are defined in the Boot Loader Specification [1] as type #2 entries. UKIs have the advantage that all code as well as meta data that is required to boot the system, not only the kernel image, is combined in a single PE file and can be signed for EFI SecureBoot. This extends the coverage of SecureBoot extensively. For RHEL support for UKI were included into kernel-ark with 16c7e3ee836e ("redhat: Add sub-RPM with a EFI unified kernel image for virtual machines"). There are two problems with UKIs from the kdump point of view at the moment. First, they cannot be directly loaded via kexec_file_load and second, the initrd included isn't suitable for kdump. In order to enable kdump on systems with UKIs build the kdump initrd as usual and extract the kernel image before loading the crash kernel. [1] https://uapi-group.org/specifications/specs/boot_loader_specification/ Signed-off-by: Philipp Rudo Reviewed-by: Pingfan Liu Reviewed-by: Coiby Xu Signed-off-by: Philipp Rudo Signed-off-by: Tao Liu --- kdump-lib.sh | 26 ++++++++++++++++++++++++-- kdumpctl | 12 +++++++++++- kexec-tools.spec | 1 + 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/kdump-lib.sh b/kdump-lib.sh index dce3239..5b58953 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -7,6 +7,17 @@ FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled" +is_uki() +{ + local img + + img="$1" + + [[ -f "$img" ]] || return + [[ "$(file -b --mime-type "$img")" == application/x-dosexec ]] || return + objdump -h -j .linux "$img" &> /dev/null +} + is_fadump_capable() { # Check if firmware-assisted dump is enabled @@ -612,7 +623,9 @@ prepare_kdump_kernel() read -r machine_id < /etc/machine-id boot_dirlist=${KDUMP_BOOTDIR:-"/boot /boot/efi /efi /"} - boot_imglist="$KDUMP_IMG-$kdump_kernelver$KDUMP_IMG_EXT $machine_id/$kdump_kernelver/$KDUMP_IMG" + boot_imglist="$KDUMP_IMG-$kdump_kernelver$KDUMP_IMG_EXT \ + $machine_id/$kdump_kernelver/$KDUMP_IMG \ + EFI/Linux/$machine_id-$kdump_kernelver.efi" # The kernel of OSTree based systems is not in the standard locations. if is_ostree; then @@ -686,7 +699,11 @@ prepare_kdump_bootinfo() fi # Set KDUMP_BOOTDIR to where kernel image is stored - KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL") + if is_uki "$KDUMP_KERNEL"; then + KDUMP_BOOTDIR=/boot + else + KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL") + fi # Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd" @@ -835,6 +852,11 @@ prepare_cmdline() fi done + # Always disable gpt-auto-generator as it hangs during boot of the + # crash kernel. Furthermore we know which disk will be used for dumping + # (if at all) and add it explicitly. + is_uki "$KDUMP_KERNEL" && out+="rd.systemd.gpt_auto=no " + # Trim unnecessary whitespaces echo "$out" | sed -e "s/^ *//g" -e "s/ *$//g" -e "s/ \+/ /g" } diff --git a/kdumpctl b/kdumpctl index 4fd8bbe..61cdfe0 100755 --- a/kdumpctl +++ b/kdumpctl @@ -662,7 +662,7 @@ function remove_kdump_kernel_key() # as the currently running kernel. load_kdump() { - local ret + local ret uki KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") @@ -676,6 +676,16 @@ load_kdump() load_kdump_kernel_key fi + if is_uki "$KDUMP_KERNEL"; then + uki=$KDUMP_KERNEL + KDUMP_KERNEL=$KDUMP_TMPDIR/vmlinuz + objcopy -O binary --only-section .linux "$uki" "$KDUMP_KERNEL" + sync -f "$KDUMP_KERNEL" + # Make sure the temp file has the correct SELinux label. + # Otherwise starting the kdump.service will fail. + chcon -t boot_t "$KDUMP_KERNEL" + fi + ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE --initrd=$TARGET_INITRD $KDUMP_KERNEL" # The '12' represents an intermediate temporary file descriptor diff --git a/kexec-tools.spec b/kexec-tools.spec index c5ce86e..a73d9a4 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -72,6 +72,7 @@ Requires: dracut >= 050 Requires: dracut-network >= 050 Requires: dracut-squash >= 050 Requires: ethtool +Requires: binutils Recommends: grubby Recommends: hostname BuildRequires: make