kdump: Rebuild default initrd for firmware assisted dump

The current kdump infrastructure builds a separate initrd which then
gets loaded into memory by kexec-tools for use by  kdump kernel. But
firmware  assisted dump (FADUMP) does not  use kexec-based approach.
After crash, firmware reboots  the  partition and  loads grub loader
like the normal  booting process does. Hence in the FADUMP approach,
the second kernel  (after crash) will always  use the default initrd
(OS built). So, to support FADUMP, change is required,  as in to add
dump capturing steps, in this initrd.

The  current kdumpctl script implementation  already has the code to
build initrd  using mkdumprd. This patch  uses  the new  '--rebuild'
option introduced, in  dracut, to incrementally build  the initramfs
image. Before rebuilding, we may need to  probe the initrd image for
fadump support, to avoid  rebuilding the initrd image multiple times
unnecessarily. This can be done using "lsinitrd" tool with the newly
proposed '--mod' option  & inspecting the presence of "kdumpbase" in
the list of modules of default initrd image. We rebuild the image if
only "kdumpbase" module is missing in the initrd image. Also, before
rebuilding, a backup of default initrd image is taken.

Kexec-tools package in rhel7 is now enhanced to insert a out-of-tree
kdump  module for  dracut,  which is responsible for  adding  vmcore
capture  steps into initrd,  if dracut is  invoked  with  "IN_KDUMP"
environment variable set to 1.  mkdumprd script exports "IN_KDUMP=1"
environment variable before  invoking  dracut to build kdump initrd.
This patch relies on this current mechanism of kdump init script.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
This commit is contained in:
Hari Bathini 2014-07-25 00:09:07 +05:30 committed by WANG Chao
parent 9f7b8b03b4
commit 5bb5be045c
1 changed files with 77 additions and 8 deletions

View File

@ -9,6 +9,7 @@ MKDUMPRD="/sbin/mkdumprd -f"
SAVE_PATH=/var/crash SAVE_PATH=/var/crash
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
DUMP_TARGET="" DUMP_TARGET=""
TARGET_INITRD=""
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled" FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
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
@ -143,13 +144,47 @@ save_core()
fi fi
} }
rebuild_initrd() rebuild_fadump_initrd()
{ {
$MKDUMPRD $kdump_initrd $kdump_kver local target_initrd_tmp
# backup fadump initrd for reference before replacing it
backup_initrd
target_initrd_tmp="$TARGET_INITRD.tmp"
$MKDUMPRD $target_initrd_tmp --rebuild $TARGET_INITRD --kver $kdump_kver
if [ $? != 0 ]; then
echo "mkdumprd: failed to rebuild initrd with fadump support" >&2
return 1
fi
# updating fadump initrd
mv $target_initrd_tmp $TARGET_INITRD
sync
return 0
}
rebuild_kdump_initrd()
{
$MKDUMPRD $TARGET_INITRD $kdump_kver
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
fi fi
return 0
}
rebuild_initrd()
{
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
rebuild_fadump_initrd
else
rebuild_kdump_initrd
fi
return $?
} }
#$1: the files to be checked with IFS=' ' #$1: the files to be checked with IFS=' '
@ -174,6 +209,18 @@ check_executable()
done done
} }
backup_initrd()
{
local target_initrd_bak
# Check if backup initrd is already present.
target_initrd_bak="$TARGET_INITRD.bak"
if [ ! -e $target_initrd_bak ];then
echo "Backing up $TARGET_INITRD"
cp $TARGET_INITRD $target_initrd_bak
fi
}
check_config() check_config()
{ {
local nr local nr
@ -240,10 +287,24 @@ get_pcs_cluster_modified_files()
echo $modified_files echo $modified_files
} }
setup_target_initrd()
{
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}.img"
if [ ! -s "$TARGET_INITRD" ]; then
echo "Error: No initrd found to rebuild!"
return 1
fi
else
TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
fi
}
check_rebuild() check_rebuild()
{ {
local extra_modules modified_files="" local extra_modules modified_files=""
local _force_rebuild force_rebuild="0" local _force_rebuild force_rebuild="0"
local initramfs_has_fadump
if [ -z "$KDUMP_KERNELVER" ]; then if [ -z "$KDUMP_KERNELVER" ]; then
kdump_kver=`uname -r` kdump_kver=`uname -r`
@ -252,7 +313,10 @@ check_rebuild()
fi fi
kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}" kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
kdump_initrd="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img" setup_target_initrd
if [ $? -ne 0 ]; then
return 1
fi
_force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE 2>/dev/null` _force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE 2>/dev/null`
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
@ -269,8 +333,8 @@ check_rebuild()
#check to see if dependent files has been modified #check to see if dependent files has been modified
#since last build of the image file #since last build of the image file
if [ -f $kdump_initrd ]; then if [ -f $TARGET_INITRD ]; then
image_time=`stat -c "%Y" $kdump_initrd 2>/dev/null` image_time=`stat -c "%Y" $TARGET_INITRD 2>/dev/null`
else else
image_time=0 image_time=0
fi fi
@ -295,10 +359,15 @@ check_rebuild()
fi fi
done done
#check if target initrd has fadump support
initramfs_has_fadump=`lsinitrd -m $TARGET_INITRD | grep ^kdumpbase$ | wc -l`
if [ $image_time -eq 0 ]; then if [ $image_time -eq 0 ]; then
echo -n "No kdump initial ramdisk found."; echo echo -n "No kdump initial ramdisk found."; echo
elif [ $DEFAULT_DUMP_MODE == "fadump" ] && [ "$initramfs_has_fadump" -eq "0" ]; then
echo "$TARGET_INITRD has no fadump support"
elif [ "$force_rebuild" != "0" ]; then elif [ "$force_rebuild" != "0" ]; then
echo -n "Force rebuild $kdump_initrd"; echo echo -n "Force rebuild $TARGET_INITRD"; echo
elif [ -n "$modified_files" ]; then elif [ -n "$modified_files" ]; then
echo "Detected change(s) in the following file(s):" echo "Detected change(s) in the following file(s):"
echo -n " "; echo "$modified_files" | sed 's/\s/\n /g' echo -n " "; echo "$modified_files" | sed 's/\s/\n /g'
@ -306,7 +375,7 @@ check_rebuild()
return 0 return 0
fi fi
echo "Rebuilding $kdump_initrd" echo "Rebuilding $TARGET_INITRD"
rebuild_initrd rebuild_initrd
return $? return $?
} }
@ -359,7 +428,7 @@ load_kdump()
$KEXEC $KEXEC_ARGS $standard_kexec_args \ $KEXEC $KEXEC_ARGS $standard_kexec_args \
--command-line="$KDUMP_COMMANDLINE" \ --command-line="$KDUMP_COMMANDLINE" \
--initrd=$kdump_initrd $kdump_kernel 2>/dev/null --initrd=$TARGET_INITRD $kdump_kernel 2>/dev/null
if [ $? == 0 ]; then if [ $? == 0 ]; then
echo "kexec: loaded kdump kernel" echo "kexec: loaded kdump kernel"
return 0 return 0