2006-12-20 12:32:29 +01:00
|
|
|
#! /bin/sh
|
|
|
|
#
|
|
|
|
# Copyright 2005 Red Hat, Inc.
|
|
|
|
# Author: Jeff Moyer <jmoyer@redhat.com>
|
|
|
|
# Modifications for SUSE from Chris Mason <mason@suse.com>
|
|
|
|
# Takashi Iwai <tiwai@suse.de>
|
|
|
|
#
|
|
|
|
# kdump
|
|
|
|
#
|
|
|
|
# Description: The kdump init script provides the support necessary for
|
|
|
|
# loading a kdump kernel into memory at system bootup time,
|
|
|
|
# and for copying away a vmcore at system panic time.
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# /etc/init.d/kexec
|
|
|
|
### BEGIN INIT INFO
|
|
|
|
# Provides: kdump
|
|
|
|
# Required-Start: boot.localfs $remote_fs
|
|
|
|
# Should-Start:
|
|
|
|
# Required-Stop:
|
|
|
|
# Default-Start: 1 2 3 5
|
|
|
|
# Default-Stop:
|
2007-06-11 18:14:03 +02:00
|
|
|
# Short-Description: kdump core saving and boot configuration
|
2006-12-20 12:32:29 +01:00
|
|
|
# Description: kdump core saving and boot configuration
|
|
|
|
### END INIT INFO
|
|
|
|
|
|
|
|
. /etc/sysconfig/kdump
|
|
|
|
. /etc/rc.status
|
|
|
|
|
|
|
|
KEXEC=/sbin/kexec
|
2007-01-18 01:34:30 +01:00
|
|
|
KDUMP_HELPER=/usr/sbin/kdump-helper
|
2007-06-11 18:14:03 +02:00
|
|
|
KDUMP_CLEANUP_DUMPS=/usr/sbin/kdump-cleanup_dumps
|
|
|
|
KDUMP_SAVE_DUMP=/usr/sbin/kdump-save_dump
|
|
|
|
KDUMP_IDENTIFY_KERNEL=/usr/sbin/kdump-identify_kernel
|
2006-12-20 12:32:29 +01:00
|
|
|
|
|
|
|
BOOTDIR="/boot"
|
|
|
|
|
|
|
|
# The default dumper
|
|
|
|
#
|
|
|
|
# Clean up old stuff if necessary, check the free size
|
|
|
|
# and save the vmcore
|
|
|
|
save_core()
|
|
|
|
{
|
2007-06-11 18:14:03 +02:00
|
|
|
$KDUMP_CLEANUP_DUMPS
|
|
|
|
if [ "$?" -ne 0 ] ; then
|
|
|
|
rc_status -v
|
|
|
|
return 1
|
2006-12-20 12:32:29 +01:00
|
|
|
fi
|
|
|
|
|
2007-06-11 18:14:03 +02:00
|
|
|
$KDUMP_SAVE_DUMP /proc/vmcore
|
2006-12-20 12:32:29 +01:00
|
|
|
rc_status -v
|
2007-06-11 18:14:03 +02:00
|
|
|
|
|
|
|
return 0
|
2006-12-20 12:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# print the available kdump kernel path
|
|
|
|
# empty if no matching file is found
|
|
|
|
check_boot_kernel ()
|
|
|
|
{
|
|
|
|
local kstr
|
2007-06-11 18:14:03 +02:00
|
|
|
|
|
|
|
# if the kernel is relocatable, try vmlinuz first because
|
|
|
|
# currently there are bugs with relocatable ELF-Images
|
|
|
|
# (ET_DYN => GDB doesn't work / ET_EXEC => kexec-tools doesn't
|
|
|
|
# detect)
|
|
|
|
case `uname -i` in
|
|
|
|
x86_64|i386)
|
|
|
|
kstr="${BOOTDIR}/vmlinuz-$1$2"
|
|
|
|
if [ -f $kstr ] ; then
|
|
|
|
if $KDUMP_IDENTIFY_KERNEL -r $kstr &>/dev/null ; then
|
|
|
|
echo $kstr
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
esac
|
|
|
|
|
2006-12-20 12:32:29 +01:00
|
|
|
kstr="${BOOTDIR}/vmlinux-$1$2"
|
|
|
|
if [ -f $kstr ]; then
|
|
|
|
echo $kstr
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
kstr="$kstr.gz"
|
|
|
|
if [ -f $kstr ]; then
|
|
|
|
echo $kstr
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
case `uname -i` in
|
|
|
|
ia64)
|
|
|
|
# ia64 uses vmlinuz as of vmlinux.gz
|
|
|
|
kstr="${BOOTDIR}/vmlinuz-$1$2"
|
|
|
|
if [ -f $kstr ]; then
|
|
|
|
echo $kstr
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Load the kdump kerel specified in /etc/sysconfig/kdump
|
|
|
|
# If none is specified, try to load a kdump kernel with the same version
|
|
|
|
# as the currently running kernel.
|
|
|
|
load_kdump()
|
|
|
|
{
|
|
|
|
echo -n "Loading kdump "
|
|
|
|
if [ -z "$KDUMP_KERNELVER" ]; then
|
|
|
|
kdump_kver=`uname -r | sed -e's/-[^-]*$//g'`
|
|
|
|
kdump_kernel=`check_boot_kernel $kdump_kver -kdump`
|
|
|
|
if [ -n "$kdump_kernel" ]; then
|
|
|
|
kdump_kver="${kdump_kver}-kdump"
|
|
|
|
elif [ -z "$kdump_kernel" ]; then
|
|
|
|
kdump_kver=`uname -r`
|
|
|
|
kdump_kernel=`check_boot_kernel $kdump_kver`
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
kdump_kver="$KDUMP_KERNELVER"
|
|
|
|
kdump_kernel=`check_boot_kernel $kdump_kver`
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$kdump_kernel" -o ! -f "$kdump_kernel" ]; then
|
|
|
|
echo -n ": No kdump kernel image found for kernel $kdump_kver."
|
|
|
|
rc_status -s
|
|
|
|
rc_failed 6
|
|
|
|
rc_exit
|
|
|
|
fi
|
|
|
|
|
|
|
|
kdump_initrd="${BOOTDIR}/initrd-${kdump_kver}"
|
|
|
|
|
|
|
|
if [ ! -f $kdump_initrd ]; then
|
|
|
|
echo -n ": No kdump initial ramdisk found."
|
|
|
|
echo "Tried to locate ${kdump_initrd}"
|
|
|
|
rc_status -s
|
|
|
|
rc_failed 6
|
|
|
|
rc_exit
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$KDUMP_COMMANDLINE" ]; then
|
2007-02-05 15:39:32 +01:00
|
|
|
KDUMP_COMMANDLINE=`cat /proc/cmdline | \
|
|
|
|
sed -e 's/crashkernel=[0-9]\+[mM]\(@[0-9]\+[Mm]\?\)\?//g' \
|
|
|
|
-e 's/ *splash=[^ ]*/ /g' \
|
|
|
|
-e 's/ *BOOT_IMAGE=[^ ]* / /g' \
|
2006-12-20 12:32:29 +01:00
|
|
|
-e 's/ *showopts/ /g'`
|
|
|
|
# Use deadline for saving the memory footprint
|
|
|
|
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE elevator=deadline sysrq=1"
|
|
|
|
case `uname -i` in
|
2007-02-05 15:39:32 +01:00
|
|
|
i?86|x86_64|ia64)
|
2006-12-20 12:32:29 +01:00
|
|
|
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE irqpoll"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
KDUMP_COMMANDLINE="CRASH=1 $KDUMP_COMMANDLINE"
|
2007-02-05 15:39:32 +01:00
|
|
|
|
|
|
|
if [ -n "$KDUMP_COMMANDLINE_APPEND" ] ; then
|
|
|
|
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE $KDUMP_COMMANDLINE_APPEND"
|
|
|
|
fi
|
|
|
|
|
2006-12-20 12:32:29 +01:00
|
|
|
if [ -n "$KDUMP_RUNLEVEL" ]; then
|
|
|
|
case "$KDUMP_RUNLEVEL" in
|
|
|
|
[1-5s])
|
|
|
|
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE $KDUMP_RUNLEVEL"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo " : Invalid KDUMP_RUNLEVEL=$KDUMP_RUNLEVEL, ignored"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
|
2007-01-18 01:34:30 +01:00
|
|
|
# add the dump device
|
|
|
|
if [ -n "$KDUMP_DUMPDEV" ] ; then
|
|
|
|
KDUMP_COMMANDLINE="dumpdev=$KDUMP_DUMPDEV $KDUMP_COMMANDLINE"
|
|
|
|
fi
|
|
|
|
|
2006-12-20 12:32:29 +01:00
|
|
|
echo 1 > /proc/sys/kernel/panic_on_oops
|
|
|
|
|
2007-06-11 18:14:03 +02:00
|
|
|
# remove `--args-linux' for x86 type kernel files here
|
|
|
|
if [ $($KDUMP_IDENTIFY_KERNEL -t $kdump_kernel) = "x86" ] ; then
|
|
|
|
KEXEC_OPTIONS=$(echo $KEXEC_OPTIONS | sed -e 's/--args-linux//g')
|
|
|
|
fi
|
|
|
|
|
2007-02-15 18:13:06 +01:00
|
|
|
KEXEC_CALL="$KEXEC -p $kdump_kernel --append=\"$KDUMP_COMMANDLINE\""
|
|
|
|
KEXEC_CALL="$KEXEC_CALL --initrd=$kdump_initrd $KEXEC_OPTIONS"
|
|
|
|
|
|
|
|
if [ $(($KDUMP_VERBOSE & 1)) -gt 0 ] ; then
|
|
|
|
logger -i -t kdump "Loading kdump kernel: $KEXEC_CALL"
|
|
|
|
fi
|
|
|
|
if [ $(($KDUMP_VERBOSE & 4)) -gt 0 ] ; then
|
|
|
|
echo "Loading kdump kernel: $KEXEC_CALL"
|
|
|
|
fi
|
|
|
|
|
|
|
|
eval "$KEXEC_CALL"
|
2006-12-20 12:32:29 +01:00
|
|
|
|
|
|
|
rc_status -v
|
|
|
|
}
|
|
|
|
|
|
|
|
# return success if running in a crash environemnt
|
|
|
|
is_crash_kernel ()
|
|
|
|
{
|
|
|
|
test -f /proc/vmcore || return 1
|
|
|
|
# FIXME: any better way to detect crash environment?
|
|
|
|
test -n "$CRASH" && return 0
|
2007-03-15 01:41:29 +01:00
|
|
|
grep -q elfcorehdr= /proc/cmdline && return 0
|
|
|
|
return 1
|
2006-12-20 12:32:29 +01:00
|
|
|
}
|
|
|
|
|
2007-01-18 01:34:30 +01:00
|
|
|
# return success if we have a valid dump on the dump device
|
|
|
|
have_valid_dump_in_dumpdev ()
|
|
|
|
{
|
|
|
|
if [ ! -b "$KDUMP_DUMPDEV" ] ; then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# return the return code from this command
|
|
|
|
$KDUMP_HELPER -c "$KDUMP_DUMPDEV" >> /dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
# invalidate the dump device so that it's not read on next boot
|
|
|
|
invalidate_dumpdev ()
|
|
|
|
{
|
2007-06-11 18:14:03 +02:00
|
|
|
dd if=/dev/zero of=$KDUMP_DUMPDEV bs=512 count=1 &>/dev/null
|
2007-01-18 01:34:30 +01:00
|
|
|
}
|
|
|
|
|
2006-12-20 12:32:29 +01:00
|
|
|
case "$1" in
|
|
|
|
start)
|
|
|
|
if is_crash_kernel; then
|
2007-01-18 01:34:30 +01:00
|
|
|
if [ -z "$KDUMP_DUMPDEV" ] ; then
|
|
|
|
if [ -n "$KDUMP_TRANSFER" ]; then
|
|
|
|
$KDUMP_TRANSFER
|
|
|
|
else
|
|
|
|
save_core
|
|
|
|
fi
|
|
|
|
fi
|
2006-12-20 12:32:29 +01:00
|
|
|
if test "$KDUMP_IMMEDIATE_REBOOT" = "yes"; then
|
|
|
|
/sbin/reboot
|
|
|
|
# sleep to avoid the conflict with script "single"
|
|
|
|
sleep 600
|
|
|
|
fi
|
|
|
|
else
|
2007-01-18 01:34:30 +01:00
|
|
|
if have_valid_dump_in_dumpdev ; then
|
2007-06-11 18:14:03 +02:00
|
|
|
$KDUMP_SAVE_DUMP $KDUMP_DUMPDEV
|
|
|
|
rc_status -v
|
|
|
|
if [ "$?" -eq 0 ] ; then
|
|
|
|
invalidate_dumpdev
|
|
|
|
rc_status
|
|
|
|
fi
|
2007-01-18 01:34:30 +01:00
|
|
|
fi
|
2006-12-20 12:32:29 +01:00
|
|
|
load_kdump
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
stop)
|
2007-03-21 00:41:49 +01:00
|
|
|
if ! is_crash_kernel ; then
|
2007-02-05 15:39:32 +01:00
|
|
|
if [ "$RUNLEVEL" != "" ]; then
|
|
|
|
echo -n "Not unloading kdump during runlevel changes"
|
|
|
|
rc_status -s
|
|
|
|
else
|
|
|
|
echo -n "Unloading kdump"
|
|
|
|
$KEXEC -p -u
|
|
|
|
rc_status -v
|
|
|
|
fi
|
2006-12-20 12:32:29 +01:00
|
|
|
fi
|
|
|
|
;;
|
|
|
|
status)
|
|
|
|
echo "not implemented"
|
|
|
|
;;
|
|
|
|
restart|reload)
|
|
|
|
$0 stop
|
|
|
|
$0 start
|
|
|
|
;;
|
|
|
|
condrestart)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo $"Usage: $0 {start|stop|status|restart|reload}"
|
|
|
|
exit 1
|
|
|
|
esac
|
|
|
|
|
|
|
|
exit $?
|
2007-02-15 18:13:06 +01:00
|
|
|
|
|
|
|
# vim: set ts=8 sw=4 sts=4 noet:
|