Kdump uses currently running kernel as default, but when currently
running kernel is a debug kernel, it will consume more memory,
which may cause out-of-memory and fail to collect vmcore.
Now we will try to use non-debug kernels first if possible.
Also extract the logic of determine KDUMP_KERNEL from
prepare_kdump_bootinfo into a function. This function will return
KDUMP_KERNEL given a kernel version.
Signed-off-by: Lichen Liu <lichliu(a)redhat.com>
---
Update:
v1 -> v2:
- extract the logic of determine KDUMP_KERNEL from prepare_kdump_bootinfo into a function.
v2 -> v3:
- remove an extra space.
- remove 2 unused variable declarations.
- warn when using debug kernel.
v3 -> v4:
- remove useless double quotes.
- add declarations of two temporary variables.
kdump-lib.sh | 67 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 49 insertions(+), 18 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh
index b137c89..944d823 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -633,46 +633,77 @@ prepare_kexec_args()
echo "$kexec_args"
}
-#
-# Detect initrd and kernel location, results are stored in global enviromental variables:
-# KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD
-#
-# Expectes KDUMP_BOOTDIR, KDUMP_IMG, KDUMP_IMG_EXT, KDUMP_KERNELVER to be loaded from config already
-# and will prefer already set values so user can specify custom kernel/initramfs location
-#
-prepare_kdump_bootinfo()
+# prepare_kdump_kernel <kdump_kernelver>
+# This function return kdump_kernel given a kernel version.
+prepare_kdump_kernel()
{
- local boot_img boot_imglist boot_dirlist boot_initrdlist
- local machine_id dir img default_initrd_base var_target_initrd_dir
-
- if [[ -z $KDUMP_KERNELVER ]]; then
- KDUMP_KERNELVER="$(uname -r)"
- fi
-
+ 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"
+ 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 [[ -n $boot_img ]]; then
+ 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 '/')
+ 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 environmental variables:
+# KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD
+#
+# Expectes KDUMP_BOOTDIR, KDUMP_IMG, KDUMP_IMG_EXT, KDUMP_KERNELVER to be loaded from config already
+# and will prefer already set values so user can specify custom kernel/initramfs location
+#
+prepare_kdump_bootinfo()
+{
+ local boot_initrdlist nondebug_kernelver debug_kernelver
+ local default_initrd_base var_target_initrd_dir
+
+ if [[ -z $KDUMP_KERNELVER ]]; then
+ KDUMP_KERNELVER=$(uname -r)
+ nondebug_kernelver=$(sed -n -e 's/\(.*\)+debug$/\1/p' <<< "$KDUMP_KERNELVER")
+ fi
+
+ # 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
+
+ KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER")
+
+ 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")
--
2.31.1