blob: f548ded940798dc398275d816b16899c5d3c2cb3 [file] [log] [blame]
#!/bin/bash -xe
#
# Kdump test driver: test case will trigger panic, and then crash
# dump. The test result is collected via dumped vmcore. For more
# information about kdump dirver please refer to doc/README.kdump.
#
# Copyright (C) 2008, Intel Corp.
# Author: Huang Ying <ying.huang@intel.com>
#
# This file is based on kdump test case in LTP.
#
# This file is released under the GPLv2.
#
sd=$(dirname "$0")
export ROOT=`(cd $sd/../../..; pwd)`
export driver=kdump
. $ROOT/lib/functions.sh
setup_path
. $ROOT/lib/dirs.sh
. $ROOT/lib/mce.sh
setup_crontab ()
{
echo "Setup crontab."
set +e
crontab -r
set -e
# crontab in some distros will not read from STDIN.
cat <<EOF > $WDIR/kdump.cron
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin
MAILTO=root
@reboot cd "$(pwd)"; ${0} $conf >> $WDIR/log 2>&1; cat $WDIR/log > /dev/console
EOF
crontab $WDIR/kdump.cron
echo "Enable cron daemon by default."
if [ -f /etc/init.d/crond ]; then
cron=crond
else
# SUSE
cron=cron
fi
# Red Hat and SUSE.
if [ -x "/sbin/chkconfig" ]; then
/sbin/chkconfig "${cron}" on
# Debian and Ubuntu.
elif [ -x "/sbin/update-rc.d" ]; then
/sbin/update-rc.d "${cron}" defaults
fi
}
setup_kdump ()
{
echo "Start kdump daemon."
if [ -f /etc/init.d/kdump ]; then
daemon=kdump
else
#SLE11
daemon=boot.kdump
fi
/etc/init.d/"${daemon}" restart
echo "Enable kdump daemon by default."
# Red Hat and SUSE.
if [ -x "/sbin/chkconfig" ]; then
/sbin/chkconfig "${daemon}" on
# Debian and Ubuntu.
elif [ -x "/sbin/update-rc.d" ]; then
/sbin/update-rc.d "${daemon}" defaults
fi
}
get_klog()
{
klog=$RDIR/$this_case/klog
cat <<EOF > $WDIR/get_klog_gdb.cmd
dump memory $klog log_buf log_buf+log_end
EOF
set +e
gdb -batch -batch-silent -x $WDIR/get_klog_gdb.cmd $VMLINUX $vmcore \
> /dev/null 2>&1
ret=$?
set -e
if [ $ret -eq 0 -a -s $klog ]; then
export klog
else
echo " Failed: can not get kernel log"
rm -rf $klog
fi
}
dump_gcov()
{
if [ -z "$GCOV" ]; then
return
fi
if ! chk_gcov; then
echo "gcov is not supported by kernel or there is no " \
"gcov utility installed"
echo "disabling gcov support"
unset GCOV
return
fi
if [ -z "$KSRC_DIR" ]; then
echo " Failed: please set KSRC_DIR for GCOV"
return
else
KSRC_DIR=$(set -P && cd "$KSRC_DIR" && pwd)
if [ -z "$KSRC_DIR"]; then
echo " Failed: Invalid KSRC_DIR, please check your setup"
return
fi
fi
export KSRC_DIR
local gcov_head_raw=$WDIR/dump_gcov_head_raw
cat <<EOF > $WDIR/dump_gcov_gdb.cmd
dump value $gcov_head_raw (void *)gcov_info_head
EOF
set +e
gdb -batch -batch-silent -x $WDIR/dump_gcov_gdb.cmd $VMLINUX $vmcore \
> /dev/null 2>&1
ret=$?
set -e
if [ $ret -ne 0 -o ! -s $gcov_head_raw ]; then
echo " Failed: can not get kernel gcov_info_head"
return
fi
wl=$(stat -c '%s' $gcov_head_raw)
h=$(echo -n 0x; od -A n -t x$wl $gcov_head_raw | tr -d ' ')
if ! gcovdump -g $h $vmcore &> /dev/null; then
echo " Failed: can not dump kernel gcov info"
return
fi
cat <<"EOF" > $WDIR/dump_gcov_deskew.sh
fn="$1"
bfn=$(basename "$fn")
dbfn="${bfn##\.tmp_}"
if [ -z "$dbfn" ]; then
return
fi
d=$(dirname "$fn")
cp $fn "$d/$dbfn"
EOF
chmod +x $WDIR/dump_gcov_deskew.sh
find $KSRC_DIR \( -name '*.tmp_*gcno' -o -name '*.tmp_*gcda' \) \
-exec $WDIR/dump_gcov_deskew.sh \{\} \;
export GCOV=dump
}
get_result ()
{
vmcore=$(ls -t "${COREDIR}"/*/vmcore* 2>/dev/null | head -1)
if [ -n "$vmcore" -a -f "$vmcore" ]; then
export vmcore
get_klog
dump_gcov
else
echo " Failed: can not get vmcore"
fi
export reboot=1
$CDIR/$case_sh get_result
}
verify_case ()
{
if [ -z "$vmcore" ]; then
echo " Failed: can not got vmcore"
fi
$CDIR/$case_sh verify
}
trigger_case ()
{
# Be careful to define COREDIR.
rm -rf "${COREDIR}"/*
# Save STDIO buffers.
sync
$CDIR/$case_sh trigger
}
# Start test.
if [ $# -lt 1 ]; then
die "Usage: $0 <config>"
fi
conf=$(basename "$1")
. $CONF_DIR/$conf
driver_prepare
set_tolerant 1
set_panic_on_oops 0
# Check mandatory variables.
if [ -z "${COREDIR}" ]; then
die "Fail: some mandatory variables are missing from configuration file."
fi
# Reboot the machine first to take advantage of boot parameter
# changes.
if [ ! -f $WDIR/stamps/setupped ]; then
echo "Setup test environment."
setup_crontab
$SDIR/setup.sh $CONF_DIR/$conf
echo > $WDIR/stamps/setupped
echo "System is going to reboot."
/sbin/shutdown -r now
sleep 60
exit -1
fi
#if mce_inject is a module, it is ensured to have been loaded
if modinfo mce_inject > /dev/null 2>&1; then
if ! lsmod | grep -q mce_inject; then
if ! modprobe mce_inject; then
die "module mce_inject isn't supported ?"
fi
fi
fi
for case_sh in ${CASES}; do
for this_case in $($CDIR/$case_sh enumerate); do
export this_case
_this_case=$(echo $this_case | tr '/' '_')
if [ -f $WDIR/stamps/${_this_case}_done ]; then
continue
fi
# First Test.
if [ ! -f $WDIR/stamps/first_test_checked ]; then
echo "First test..."
echo "Verify Boot Loader."
if ! grep 'crashkernel=' /proc/cmdline; then
die "Fail: error changing Boot Loader, no crashkernel=."
fi
setup_kdump
echo > $WDIR/stamps/first_test_checked
fi
if [ ! -f $WDIR/stamps/${_this_case}_triggered ]; then
echo > $WDIR/stamps/${_this_case}_triggered
mkdir -p $RDIR/$this_case
rm -rf $RDIR/$this_case/*
echo -e "\n$this_case:" | tee -a $RDIR/result
echo "Running current test $this_case."
trigger_case | tee -a $RDIR/result
triggering=1
fi
sleep 5
if [ -z "$triggering" ]; then
(get_result; verify_case) | tee -a $RDIR/result
else
echo " Failed: Failed to trigger kdump" | tee -a $RDIR/result
fi
echo > $WDIR/stamps/${_this_case}_done
# Wait for system to fully boot and leave a chance for user to
# stop test
sleep 55
done
done
echo "Test run complete" | tee -a $RDIR/result
# We are done.
# Reset.
crontab -r
exit 0