kernel installation is not always in a fixed location /boot, there are
multiple different style of kernel installation, and initramfs location
changes with kernel. The two files should be detected together and adapt
to different style.
To do so we use a list of potential installation destinations and a list
of possible kernel image and initrd names. Iterate the two list to
detect the installation location of the two files. If GRUB is in use,
the BOOT_IMAGE= cmdline from GRUB will also be considered. And also
prefers user specified config if given.
Previous atomic workaround is no longer needed as the new detection
method can cover that case.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
dracut-early-kdump-module-setup.sh | 17 +++----
kdump-lib.sh | 75 ++++++++++++++++++++++++------
kdumpctl | 44 ++++++++----------
3 files changed, 87 insertions(+), 49 deletions(-)
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh
index 626ca0e..f30bd67 100755
--- a/dracut-early-kdump-module-setup.sh
+++ b/dracut-early-kdump-module-setup.sh
@@ -21,18 +21,13 @@ depends() {
}
prepare_kernel_initrd() {
- KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
- if [ -z "$KDUMP_KERNELVER" ]; then
- kdump_kver=`uname -r`
- if [ "$kernel" != "$kdump_kver" ]; then
- dwarn "Using current kernel version '$kdump_kver' for early
kdump," \
- "but the initramfs is generated for kernel version
'$kernel'"
- fi
- else
- kdump_kver=$KDUMP_KERNELVER
+ prepare_kdump_bootinfo
+
+ # $kernel is a variable from dracut
+ if [ "$KDUMP_KERNELVER" != $kernel ]; then
+ dwarn "Using kernel version '$KDUMP_KERNELVER' for early
kdump," \
+ "but the initramfs is generated for kernel version
'$kernel'"
fi
- KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
- KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
}
install() {
diff --git a/kdump-lib.sh b/kdump-lib.sh
index f632f65..c35b904 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -666,24 +666,71 @@ prepare_kexec_args()
echo $kexec_args
}
-check_boot_dir()
-{
- local kdump_bootdir=$1
- #If user specify a boot dir for kdump kernel, let's use it. Otherwise
- #check whether it's a atomic host. If yes parse the subdirectory under
- #/boot; If not just find it under /boot.
- if [ -n "$kdump_bootdir" ]; then
- echo "$kdump_bootdir"
- return
+#
+# 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()
+{
+ local boot_imglist boot_dirlist boot_initrdlist curr_kver="$(uname -r)"
+ local machine_id
+
+ if [ -z "$KDUMP_KERNELVER"]; then
+ KDUMP_KERNELVER="$(uname -r)"
+ 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"
+ 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
+
+ if ! [ -e "$KDUMP_KERNEL" ]; then
+ echo "Failed to detect kdump kernel location"
+ return 1
+ fi
+
+ # Set KDUMP_BOOTDIR to where kernel image is stored
+ 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
+ DEFAULT_INITRD="$KDUMP_BOOTDIR/$initrd"
+ break
+ fi
+ done
+
+ if ! [ -e "$DEFAULT_INITRD" ]; then
+ echo "Failed to detect default initrd location"
+ return 1
fi
- if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then
- kdump_bootdir="/boot"
+ # Get kdump initrd from default initrd filename
+ # initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img
+ # initrd => initrdkdump
+ if [[ $(basename $DEFAULT_INITRD) == *.* ]]; then
+ KDUMP_INITRD=${DEFAULT_INITRD%.*}kdump.${DEFAULT_INITRD##*.}
else
- eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1)
- kdump_bootdir="/boot"$(dirname ${BOOT_IMAGE#*)})
+ KDUMP_INITRD=${DEFAULT_INITRD}kdump
fi
- echo $kdump_bootdir
}
#
diff --git a/kdumpctl b/kdumpctl
index 42c11d3..9069326 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -2,6 +2,7 @@
KEXEC=/sbin/kexec
KDUMP_KERNELVER=""
+KDUMP_KERNEL=""
KDUMP_COMMANDLINE=""
KEXEC_ARGS=""
KDUMP_CONFIG_FILE="/etc/kdump.conf"
@@ -13,6 +14,7 @@ INITRD_CHECKSUM_LOCATION="/boot/.fadump_initrd_checksum"
DUMP_TARGET=""
DEFAULT_INITRD=""
DEFAULT_INITRD_BAK=""
+KDUMP_INITRD=""
TARGET_INITRD=""
FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
#kdump shall be the default dump mode
@@ -94,7 +96,7 @@ rebuild_fadump_initrd()
# this file tells the initrd is fadump enabled
touch /tmp/fadump.initramfs
target_initrd_tmp="$TARGET_INITRD.tmp"
- $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $kdump_kver \
+ $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $KDUMP_KERNELVER \
-i /tmp/fadump.initramfs /etc/fadump.initramfs
if [ $? != 0 ]; then
echo "mkdumprd: failed to rebuild initrd with fadump support" >&2
@@ -118,7 +120,7 @@ check_earlykdump_is_enabled()
rebuild_kdump_initrd()
{
- $MKDUMPRD $TARGET_INITRD $kdump_kver
+ $MKDUMPRD $TARGET_INITRD $KDUMP_KERNELVER
if [ $? != 0 ]; then
echo "mkdumprd: failed to make kdump initrd" >&2
return 1
@@ -301,18 +303,12 @@ get_pcs_cluster_modified_files()
setup_initrd()
{
- KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
-
- if [ -z "$KDUMP_KERNELVER" ]; then
- kdump_kver=`uname -r`
- else
- kdump_kver=$KDUMP_KERNELVER
+ prepare_kdump_bootinfo
+ if [ $? -ne 0 ]; then
+ return 1
fi
- kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
-
- DEFAULT_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`.img"
- DEFAULT_INITRD_BAK="${KDUMP_BOOTDIR}/.initramfs-`uname -r`.img.default"
+ DEFAULT_INITRD_BAK="$KDUMP_BOOTDIR/.$(basename $DEFAULT_INITRD).default"
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
TARGET_INITRD="$DEFAULT_INITRD"
@@ -320,7 +316,7 @@ setup_initrd()
# with fadump aware initrd
backup_default_initrd
else
- TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
+ TARGET_INITRD="$KDUMP_INITRD"
# check if a backup of default initrd exists. If yes,
# it signifies a switch from fadump mode. So, restore
@@ -360,25 +356,25 @@ check_files_modified()
EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
- files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS $CORE_COLLECTOR"
+ files="$KDUMP_CONFIG_FILE $KDUMP_KERNEL $EXTRA_BINS $CORE_COLLECTOR"
[[ -e /etc/fstab ]] && files="$files /etc/fstab"
# Check for any updated extra module
EXTRA_MODULES="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed
's/^extra_modules\s*//')"
if [ -n "$EXTRA_MODULES" ]; then
- if [ -e /lib/modules/$kdump_kver/modules.dep ]; then
- files="$files /lib/modules/$kdump_kver/modules.dep"
+ if [ -e /lib/modules/$KDUMP_KERNELVER/modules.dep ]; then
+ files="$files /lib/modules/$KDUMP_KERNELVER/modules.dep"
fi
for _module in $EXTRA_MODULES; do
- _module_file="$(modinfo --set-version "$kdump_kver" --filename
"$_module" 2>/dev/null)"
+ _module_file="$(modinfo --set-version "$KDUMP_KERNELVER" --filename
"$_module" 2>/dev/null)"
if [[ $? -eq 0 ]]; then
files="$files $_module_file"
for _dep_modules in $(modinfo -F depends $_module | tr ',' ' '); do
- files="$files $(modinfo --set-version "$kdump_kver" --filename
$_dep_modules 2>/dev/null)"
+ files="$files $(modinfo --set-version "$KDUMP_KERNELVER"
--filename $_dep_modules 2>/dev/null)"
done
else
# If it's not a module nor builtin, give an error
- if ! ( modprobe --set-version "$kdump_kver" --dry-run "$_module"
&>/dev/null ); then
+ if ! ( modprobe --set-version "$KDUMP_KERNELVER" --dry-run
"$_module" &>/dev/null ); then
echo "Module $_module not found"
fi
fi
@@ -472,8 +468,8 @@ check_dump_fs_modified()
check_block_and_slaves_all _record_block_drivers "$(get_maj_min
"$_target")"
for _driver in $_target_drivers; do
# Skip deprecated/invalid driver name or built-in module
- _module_name=$(modinfo --set-version "$kdump_kver" -F name $_driver
2>/dev/null)
- _module_filename=$(modinfo --set-version "$kdump_kver" -n $_driver
2>/dev/null)
+ _module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver
2>/dev/null)
+ _module_filename=$(modinfo --set-version "$KDUMP_KERNELVER" -n $_driver
2>/dev/null)
if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename"
= *"(builtin)"* ]]; then
continue
fi
@@ -540,7 +536,7 @@ check_wdt_modified()
# modalias. Currently load all of them.
# TODO: Need to find a way to avoid any unwanted module
# represented by modalias
- _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null)
+ _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv
2>/dev/null)
if [[ $_wdtdrv ]]; then
for i in $_wdtdrv; do
_drivers[$i]=1
@@ -555,7 +551,7 @@ check_wdt_modified()
[[ -f "$_wdtppath/modalias" ]] || continue
_wdtdrv=$(< "$_wdtppath/modalias")
- _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null)
+ _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv
2>/dev/null)
if [[ $_wdtdrv ]]; then
for i in $_wdtdrv; do
_drivers[$i]=1
@@ -700,7 +696,7 @@ load_kdump()
$KEXEC $KEXEC_ARGS $standard_kexec_args \
--command-line="$KDUMP_COMMANDLINE" \
- --initrd=$TARGET_INITRD $kdump_kernel
+ --initrd=$TARGET_INITRD $KDUMP_KERNEL
if [ $? == 0 ]; then
echo "kexec: loaded kdump kernel"
return 0
--
2.26.2