Refactor kernel image and initrd detection code
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 known 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@redhat.com> Acked-by: Dave Young <dyoung@redhat.com>
This commit is contained in:
parent
c76820bddd
commit
a37f36ad4d
@ -21,18 +21,13 @@ depends() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prepare_kernel_initrd() {
|
prepare_kernel_initrd() {
|
||||||
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
|
prepare_kdump_bootinfo
|
||||||
if [ -z "$KDUMP_KERNELVER" ]; then
|
|
||||||
kdump_kver=`uname -r`
|
# $kernel is a variable from dracut
|
||||||
if [ "$kernel" != "$kdump_kver" ]; then
|
if [ "$KDUMP_KERNELVER" != $kernel ]; then
|
||||||
dwarn "Using current kernel version '$kdump_kver' for early kdump," \
|
dwarn "Using kernel version '$KDUMP_KERNELVER' for early kdump," \
|
||||||
"but the initramfs is generated for kernel version '$kernel'"
|
"but the initramfs is generated for kernel version '$kernel'"
|
||||||
fi
|
|
||||||
else
|
|
||||||
kdump_kver=$KDUMP_KERNELVER
|
|
||||||
fi
|
fi
|
||||||
KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
|
|
||||||
KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
|
72
kdump-lib.sh
72
kdump-lib.sh
@ -666,24 +666,68 @@ prepare_kexec_args()
|
|||||||
echo $kexec_args
|
echo $kexec_args
|
||||||
}
|
}
|
||||||
|
|
||||||
check_boot_dir()
|
#
|
||||||
|
# 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 kdump_bootdir=$1
|
local boot_imglist boot_dirlist boot_initrdlist curr_kver="$(uname -r)"
|
||||||
#If user specify a boot dir for kdump kernel, let's use it. Otherwise
|
local machine_id
|
||||||
#check whether it's a atomic host. If yes parse the subdirectory under
|
|
||||||
#/boot; If not just find it under /boot.
|
if [ -z "$KDUMP_KERNELVER"]; then
|
||||||
if [ -n "$kdump_bootdir" ]; then
|
KDUMP_KERNELVER="$(uname -r)"
|
||||||
echo "$kdump_bootdir"
|
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then
|
read machine_id < /etc/machine-id
|
||||||
kdump_bootdir="/boot"
|
boot_dirlist=${KDUMP_BOOTDIR:-"/boot /boot/efi /efi /"}
|
||||||
else
|
boot_imglist="$KDUMP_IMG-$KDUMP_KERNELVER$KDUMP_IMG_EXT $machine_id/$KDUMP_KERNELVER/$KDUMP_IMG"
|
||||||
eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1)
|
|
||||||
kdump_bootdir="/boot"$(dirname ${BOOT_IMAGE#*)})
|
# 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
|
||||||
|
|
||||||
|
# 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 [[ -z "$DEFAULT_INITRD" ]]; then
|
||||||
|
KDUMP_INITRD=${KDUMP_BOOTDIR}/initramfs-${KDUMP_KERNELVER}kdump.img
|
||||||
|
elif [[ $(basename $DEFAULT_INITRD) == *.* ]]; then
|
||||||
|
KDUMP_INITRD=${DEFAULT_INITRD%.*}kdump.${DEFAULT_INITRD##*.}
|
||||||
|
else
|
||||||
|
KDUMP_INITRD=${DEFAULT_INITRD}kdump
|
||||||
fi
|
fi
|
||||||
echo $kdump_bootdir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
48
kdumpctl
48
kdumpctl
@ -2,6 +2,7 @@
|
|||||||
KEXEC=/sbin/kexec
|
KEXEC=/sbin/kexec
|
||||||
|
|
||||||
KDUMP_KERNELVER=""
|
KDUMP_KERNELVER=""
|
||||||
|
KDUMP_KERNEL=""
|
||||||
KDUMP_COMMANDLINE=""
|
KDUMP_COMMANDLINE=""
|
||||||
KEXEC_ARGS=""
|
KEXEC_ARGS=""
|
||||||
KDUMP_CONFIG_FILE="/etc/kdump.conf"
|
KDUMP_CONFIG_FILE="/etc/kdump.conf"
|
||||||
@ -13,6 +14,7 @@ INITRD_CHECKSUM_LOCATION="/boot/.fadump_initrd_checksum"
|
|||||||
DUMP_TARGET=""
|
DUMP_TARGET=""
|
||||||
DEFAULT_INITRD=""
|
DEFAULT_INITRD=""
|
||||||
DEFAULT_INITRD_BAK=""
|
DEFAULT_INITRD_BAK=""
|
||||||
|
KDUMP_INITRD=""
|
||||||
TARGET_INITRD=""
|
TARGET_INITRD=""
|
||||||
FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
|
FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
|
||||||
#kdump shall be the default dump mode
|
#kdump shall be the default dump mode
|
||||||
@ -94,7 +96,7 @@ rebuild_fadump_initrd()
|
|||||||
# this file tells the initrd is fadump enabled
|
# this file tells the initrd is fadump enabled
|
||||||
touch /tmp/fadump.initramfs
|
touch /tmp/fadump.initramfs
|
||||||
target_initrd_tmp="$TARGET_INITRD.tmp"
|
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
|
-i /tmp/fadump.initramfs /etc/fadump.initramfs
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
echo "mkdumprd: failed to rebuild initrd with fadump support" >&2
|
echo "mkdumprd: failed to rebuild initrd with fadump support" >&2
|
||||||
@ -118,7 +120,7 @@ check_earlykdump_is_enabled()
|
|||||||
|
|
||||||
rebuild_kdump_initrd()
|
rebuild_kdump_initrd()
|
||||||
{
|
{
|
||||||
$MKDUMPRD $TARGET_INITRD $kdump_kver
|
$MKDUMPRD $TARGET_INITRD $KDUMP_KERNELVER
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
echo "mkdumprd: failed to make kdump initrd" >&2
|
echo "mkdumprd: failed to make kdump initrd" >&2
|
||||||
return 1
|
return 1
|
||||||
@ -189,6 +191,10 @@ backup_default_initrd()
|
|||||||
|
|
||||||
restore_default_initrd()
|
restore_default_initrd()
|
||||||
{
|
{
|
||||||
|
if [ ! -f "$DEFAULT_INITRD" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
# If a backup initrd exists, we must be switching back from
|
# If a backup initrd exists, we must be switching back from
|
||||||
# fadump to kdump. Restore the original default initrd.
|
# fadump to kdump. Restore the original default initrd.
|
||||||
if [ -f $DEFAULT_INITRD_BAK ] && [ -f $INITRD_CHECKSUM_LOCATION ]; then
|
if [ -f $DEFAULT_INITRD_BAK ] && [ -f $INITRD_CHECKSUM_LOCATION ]; then
|
||||||
@ -301,18 +307,12 @@ get_pcs_cluster_modified_files()
|
|||||||
|
|
||||||
setup_initrd()
|
setup_initrd()
|
||||||
{
|
{
|
||||||
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
|
prepare_kdump_bootinfo
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
if [ -z "$KDUMP_KERNELVER" ]; then
|
return 1
|
||||||
kdump_kver=`uname -r`
|
|
||||||
else
|
|
||||||
kdump_kver=$KDUMP_KERNELVER
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
|
DEFAULT_INITRD_BAK="$KDUMP_BOOTDIR/.$(basename $DEFAULT_INITRD).default"
|
||||||
|
|
||||||
DEFAULT_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`.img"
|
|
||||||
DEFAULT_INITRD_BAK="${KDUMP_BOOTDIR}/.initramfs-`uname -r`.img.default"
|
|
||||||
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
||||||
TARGET_INITRD="$DEFAULT_INITRD"
|
TARGET_INITRD="$DEFAULT_INITRD"
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ setup_initrd()
|
|||||||
# with fadump aware initrd
|
# with fadump aware initrd
|
||||||
backup_default_initrd
|
backup_default_initrd
|
||||||
else
|
else
|
||||||
TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
|
TARGET_INITRD="$KDUMP_INITRD"
|
||||||
|
|
||||||
# check if a backup of default initrd exists. If yes,
|
# check if a backup of default initrd exists. If yes,
|
||||||
# it signifies a switch from fadump mode. So, restore
|
# it signifies a switch from fadump mode. So, restore
|
||||||
@ -360,25 +360,25 @@ check_files_modified()
|
|||||||
EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
|
EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
|
||||||
CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
|
CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
|
||||||
EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
|
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"
|
[[ -e /etc/fstab ]] && files="$files /etc/fstab"
|
||||||
|
|
||||||
# Check for any updated extra module
|
# Check for any updated extra module
|
||||||
EXTRA_MODULES="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')"
|
EXTRA_MODULES="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')"
|
||||||
if [ -n "$EXTRA_MODULES" ]; then
|
if [ -n "$EXTRA_MODULES" ]; then
|
||||||
if [ -e /lib/modules/$kdump_kver/modules.dep ]; then
|
if [ -e /lib/modules/$KDUMP_KERNELVER/modules.dep ]; then
|
||||||
files="$files /lib/modules/$kdump_kver/modules.dep"
|
files="$files /lib/modules/$KDUMP_KERNELVER/modules.dep"
|
||||||
fi
|
fi
|
||||||
for _module in $EXTRA_MODULES; do
|
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
|
if [[ $? -eq 0 ]]; then
|
||||||
files="$files $_module_file"
|
files="$files $_module_file"
|
||||||
for _dep_modules in $(modinfo -F depends $_module | tr ',' ' '); do
|
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
|
done
|
||||||
else
|
else
|
||||||
# If it's not a module nor builtin, give an error
|
# 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"
|
echo "Module $_module not found"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -472,8 +472,8 @@ check_dump_fs_modified()
|
|||||||
check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")"
|
check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")"
|
||||||
for _driver in $_target_drivers; do
|
for _driver in $_target_drivers; do
|
||||||
# Skip deprecated/invalid driver name or built-in module
|
# Skip deprecated/invalid driver name or built-in module
|
||||||
_module_name=$(modinfo --set-version "$kdump_kver" -F name $_driver 2>/dev/null)
|
_module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver 2>/dev/null)
|
||||||
_module_filename=$(modinfo --set-version "$kdump_kver" -n $_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
|
if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename" = *"(builtin)"* ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@ -540,7 +540,7 @@ check_wdt_modified()
|
|||||||
# modalias. Currently load all of them.
|
# modalias. Currently load all of them.
|
||||||
# TODO: Need to find a way to avoid any unwanted module
|
# TODO: Need to find a way to avoid any unwanted module
|
||||||
# represented by modalias
|
# 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
|
if [[ $_wdtdrv ]]; then
|
||||||
for i in $_wdtdrv; do
|
for i in $_wdtdrv; do
|
||||||
_drivers[$i]=1
|
_drivers[$i]=1
|
||||||
@ -555,7 +555,7 @@ check_wdt_modified()
|
|||||||
[[ -f "$_wdtppath/modalias" ]] || continue
|
[[ -f "$_wdtppath/modalias" ]] || continue
|
||||||
|
|
||||||
_wdtdrv=$(< "$_wdtppath/modalias")
|
_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
|
if [[ $_wdtdrv ]]; then
|
||||||
for i in $_wdtdrv; do
|
for i in $_wdtdrv; do
|
||||||
_drivers[$i]=1
|
_drivers[$i]=1
|
||||||
@ -700,7 +700,7 @@ load_kdump()
|
|||||||
|
|
||||||
$KEXEC $KEXEC_ARGS $standard_kexec_args \
|
$KEXEC $KEXEC_ARGS $standard_kexec_args \
|
||||||
--command-line="$KDUMP_COMMANDLINE" \
|
--command-line="$KDUMP_COMMANDLINE" \
|
||||||
--initrd=$TARGET_INITRD $kdump_kernel
|
--initrd=$TARGET_INITRD $KDUMP_KERNEL
|
||||||
if [ $? == 0 ]; then
|
if [ $? == 0 ]; then
|
||||||
echo "kexec: loaded kdump kernel"
|
echo "kexec: loaded kdump kernel"
|
||||||
return 0
|
return 0
|
||||||
|
Loading…
Reference in New Issue
Block a user