diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index 342a45a..aa2dfd6 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -692,6 +692,34 @@ prepare_kexec_args() echo $kexec_args } +# prepare_kdump_kernel +# This function return kdump_kernel given a kernel version. +prepare_kdump_kernel() +{ + local kdump_kernelver=$1 + local dir img boot_dirlist boot_imglist kdump_kernel machine_id + 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" + + # Use BOOT_IMAGE as reference if possible, strip the GRUB root device prefix in (hd0,gpt1) format + boot_img="$(sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\) .*/\2/" /proc/cmdline)" + if [[ "$boot_img" == *"$kdump_kernelver" ]]; then + boot_imglist="$boot_img $boot_imglist" + fi + + for dir in $boot_dirlist; do + for img in $boot_imglist; do + if [[ -f "$dir/$img" ]]; then + kdump_kernel=$(echo "$dir/$img" | tr -s '/') + break 2 + fi + done + done + echo "$kdump_kernel" +} + # # Detect initrd and kernel location, results are stored in global enviromental variables: # KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD @@ -701,46 +729,49 @@ prepare_kexec_args() # prepare_kdump_bootinfo() { - local boot_imglist boot_dirlist boot_initrdlist curr_kver="$(uname -r)" - local machine_id + local boot_initrdlist nondebug_kernelver debug_kernelver + local default_initrd_base var_target_initrd_dir - if [ -z "$KDUMP_KERNELVER" ]; then - KDUMP_KERNELVER="$(uname -r)" + if [[ -z $KDUMP_KERNELVER ]]; then + KDUMP_KERNELVER=$(uname -r) + nondebug_kernelver=$(sed -n -e 's/\(.*\)+debug$/\1/p' <<< "$KDUMP_KERNELVER") fi - read 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" - - # Use BOOT_IMAGE as reference if possible, strip the GRUB root device prefix in (hd0,gpt1) format - local boot_img="$(cat /proc/cmdline | sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\) .*/\2/")" - if [ -n "$boot_img" ]; then - boot_imglist="$boot_img $boot_imglist" + # Use nondebug kernel if possible, because debug kernel will consume more memory and may oom. + if [[ -n $nondebug_kernelver ]]; then + dinfo "Trying to use $nondebug_kernelver." + debug_kernelver=$KDUMP_KERNELVER + KDUMP_KERNELVER=$nondebug_kernelver fi - for dir in $boot_dirlist; do - for img in $boot_imglist; do - if [ -f "$dir/$img" ]; then - KDUMP_KERNEL=$(echo $dir/$img | tr -s '/') - break 2 - fi - done - done + KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER") - if ! [ -e "$KDUMP_KERNEL" ]; then + if ! [[ -e $KDUMP_KERNEL ]]; then + if [[ -n $debug_kernelver ]]; then + dinfo "Fallback to using debug kernel" + KDUMP_KERNELVER=$debug_kernelver + KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER") + fi + fi + + if ! [[ -e $KDUMP_KERNEL ]]; then derror "Failed to detect kdump kernel location" return 1 fi + if [[ "$KDUMP_KERNEL" == *"+debug" ]]; then + dwarn "Using debug kernel, you may need to set a larger crashkernel than the default value." + fi + # Set KDUMP_BOOTDIR to where kernel image is stored - KDUMP_BOOTDIR=$(dirname $KDUMP_KERNEL) + KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL") # Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd" for initrd in $boot_initrdlist; do - if [ -f "$KDUMP_BOOTDIR/$initrd" ]; then - defaut_initrd_base="$initrd" - DEFAULT_INITRD="$KDUMP_BOOTDIR/$defaut_initrd_base" + if [[ -f "$KDUMP_BOOTDIR/$initrd" ]]; then + default_initrd_base="$initrd" + DEFAULT_INITRD="$KDUMP_BOOTDIR/$default_initrd_base" break fi done @@ -748,16 +779,16 @@ prepare_kdump_bootinfo() # Create kdump initrd basename from default initrd basename # initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img # initrd => initrdkdump - if [[ -z "$defaut_initrd_base" ]]; then + if [[ -z $default_initrd_base ]]; then kdump_initrd_base=initramfs-${KDUMP_KERNELVER}kdump.img - elif [[ $defaut_initrd_base == *.* ]]; then - kdump_initrd_base=${defaut_initrd_base%.*}kdump.${DEFAULT_INITRD##*.} + elif [[ $default_initrd_base == *.* ]]; then + kdump_initrd_base=${default_initrd_base%.*}kdump.${DEFAULT_INITRD##*.} else - kdump_initrd_base=${defaut_initrd_base}kdump + kdump_initrd_base=${default_initrd_base}kdump fi - # Place kdump initrd in `/var/lib/kdump` if `KDUMP_BOOTDIR` not writable - if [[ ! -w "$KDUMP_BOOTDIR" ]];then + # Place kdump initrd in $(/var/lib/kdump) if $(KDUMP_BOOTDIR) not writable + if [[ ! -w $KDUMP_BOOTDIR ]]; then var_target_initrd_dir="/var/lib/kdump" mkdir -p "$var_target_initrd_dir" KDUMP_INITRD="$var_target_initrd_dir/$kdump_initrd_base" diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 9275a80..38a5c66 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.24 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component @@ -393,6 +393,9 @@ done %endif %changelog +* Mon Jul 4 2022 Pingfan Liu - 2.0.24-5 +- kdump-lib: use non-debug kernels first + * Tue Jun 21 2022 Pingfan Liu - 2.0.24-4 - kdump-lib.sh: Check the output of blkid with sed instead of eval