|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /etc/rc6.d/ |
Upload File : |
#! /bin/sh
#
# 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.
#
# Copyright 2005 Red Hat, Inc.
#
# chkconfig: - 20 80
#
# Author: Jeff Moyer <jmoyer@redhat.com>
# Source function library.
. /etc/init.d/functions
KEXEC=/sbin/kexec
# Will be different for ia64, for example. For now, that architecture isn't
# supported. Code needs to be added here when we do.
BOOTDIR="/boot"
KDUMP_KERNELVER=""
KDUMP_INITRDEXT=""
KDUMP_COMMANDLINE=""
KDUMP_IDE_NOPROBE_COMMANDLINE=""
KEXEC_ARGS=""
KDUMP_CONFIG_FILE="/etc/kdump.conf"
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
LOGGER="/usr/bin/logger -p info -t kdump"
ARCH=`uname -m`
standard_kexec_args="-p"
if [ -f /etc/sysconfig/kdump ]; then
. /etc/sysconfig/kdump
fi
function save_core()
{
local kdump_path
$LOGGER "entering user-space to capture the vmcore"
kdump_path=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`
if [ -z "$kdump_path" ]; then
coredir="/var/crash/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"
else
coredir="${kdump_path}/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"
fi
mkdir -p $coredir
cp --sparse=always /proc/vmcore $coredir/vmcore-incomplete
exitcode=$?
if [ $exitcode == 0 ]; then
mv $coredir/vmcore-incomplete $coredir/vmcore
$LOGGER "saved a vmcore to $coredir"
else
$LOGGER "failed to save a vmcore to $coredir"
fi
return $exitcode
}
function run_kdump_post()
{
kdumpsuccess=$1
KDUMP_POST=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2`
if [ -x "$KDUMP_POST" ]; then
$KDUMP_POST $kdumpsuccess
$LOGGER "run \"$KDUMP_POST $kdumpsuccess\""
fi
}
function check_config()
{
if [ -z "$KDUMP_KERNELVER" ]; then
local running_kernel=`uname -r`
kdump_kver=`echo $running_kernel | sed -r 's/(smp|xen)//g'`
# on i686 xen, if any portion of memory is mapped above 4G,
# we need to use kernel-PAE for kdump
if [ "$ARCH" == "i686" ] && [ -e /proc/xen ]; then
need_64bit_headers
if [ $? == 1 ]; then
kdump_kver=${kdump_kver}PAE
fi
fi
else
kdump_kver=$KDUMP_KERNELVER
fi
kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
kdump_initrd="${KDUMP_BOOTDIR}/initrd-${kdump_kver}${KDUMP_INITRDEXT}kdump.img"
if [ ! -f $kdump_kernel ]; then
echo -n "No kdump kernel image found."; warning; echo
echo "Tried to locate ${kdump_kernel}"
return 0
fi
if [ ! -f $kdump_initrd ]; then
echo -n "No kdump initial ramdisk found."; warning; echo
echo "Rebuilding $kdump_initrd"
/sbin/mkdumprd -d -f $kdump_initrd $kdump_kver
if [ $? != 0 ]; then
echo "Failed to run mkdumprd"
$LOGGER "mkdumprd: failed to make kdump initrd"
exit 1
fi
return 0
fi
#check to see if config file or kdump post has been modified
#since last build of the image file
image_time=`stat -c "%Y" $kdump_initrd`
EXTRA_FILES=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2`
CHECK_FILE=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2`
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
CHECK_FILE=`grep ^extra_modules $KDUMP_CONFIG_FILE | cut -d\ -f2-`
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
CHECK_FILE=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
FORCE_REBUILD=`grep ^extra_modules $KDUMP_CONFIG_FILE`
files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_FILES"
modified_files=""
for file in $files; do
time_stamp=0
if [ -f "$file" ]; then
time_stamp=`stat -c "%Y" $file`
else
modified_files="$modified_files $file"
continue
fi
if [ "$time_stamp" -gt "$image_time" ]; then
modified_files="$modified_files $file"
fi
done
if [ -n "$FORCE_REBUILD" -a "$modified_files"!=" " ]
then
modified_files="force_rebuild"
fi
if [ -n "$modified_files" -a "$modified_files"!=" " ]; then
if [ "$modified_files" != "force_rebuild" ]
then
echo "Detected change(s) the following file(s):"
echo -n " "; echo "$modified_files" | sed 's/\s/\n /g'
fi
echo "Rebuilding $kdump_initrd"
/sbin/mkdumprd -d -f $kdump_initrd $kdump_kver
if [ $? != 0 ]; then
echo "Failed to run mkdumprd"
$LOGGER "mkdumprd: failed to make kdump initrd"
return 1
fi
fi
return 0
}
# This function check iomem and determines if we have more than
# 4GB of ram available. Returns 1 if we do, 0 if we dont
function need_64bit_headers()
{
MEMSZ=`sed -e's/\(^[0-9]\+.*\)/0x\1/' -e's/\(-\)\(.*\)/ 0x\2/' /proc/iomem | \
awk 'BEGIN {
totalmem=0;
segmentmem=0;
}
/.*RAM.*/ {
start = strtonum($1);
end = strtonum($2);
segmentmem=end-start;
totalmem=totalmem+(segmentmem/1024);
if (end >= 4294967296) {
totalmem=totalmem+4194304;
}
}
END {
printf "%d", (totalmem+1);
}'`
#The AWK script above computes the total number of KB
#in the RAM areas of /proc/iomem
#Note also that we set totalmem to 4GB in the event that
#any physical address is larger than 4GB. This lets us
#default to 64 bit ELF headers for PAE kernels, which
#need then to access those higher addresses.
#This comparison tells us if the above amount is more than
#4GB (4096 KB). I do the funny math to avoid overflow
if [ $MEMSZ -ge 4194304 ]
then
return 1
fi
return 0
}
function avoid_cdrom_drive()
{
local DRIVE=""
local MEDIA=""
local IDE_DRIVES=(`echo hd{a,b,c,d}`)
local COUNTER="0"
for DRIVE in ${IDE_DRIVES[@]}
do
if ! $(echo "$KDUMP_COMMANDLINE" |grep -q "$DRIVE=");then
if [ -f /proc/ide/$DRIVE/media ];then
MEDIA=$(cat /proc/ide/$DRIVE/media)
if [ x"$MEDIA" == x"cdrom" ]; then
KDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=cdrom"
COUNTER=$(($COUNTER+1))
fi
fi
else
KDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=noprobe"
fi
done
# We don't find cdrom drive.
if [ $COUNTER -eq 0 ]; then
KDUMP_IDE_NOPROBE_COMMANDLINE=""
fi
}
# 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.
function load_kdump()
{
if [ -z "$KDUMP_COMMANDLINE" ]
then
KDUMP_COMMANDLINE=`cat /proc/cmdline`
fi
ARCH=`uname -m`
if [ "$ARCH" == "ppc64" ]
then
MEM_RESERVED=`grep "crashkernel=[0-9]\+[MmKkGg]@[0-9]\+[MmGgKk]" /proc/cmdline`
else
MEM_RESERVED=`grep "Crash kernel" /proc/iomem | grep -v "00000000-00000000"`
fi
if [ -z "$MEM_RESERVED" ]
then
$LOGGER "No crashkernel parameter was specified or crashkernel memory reservation failed"
return 1
fi
if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
then
need_64bit_headers
if [ $? == 1 ]
then
FOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf32-core-headers`
if [ -n "$FOUND_ELF_ARGS" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
warning
echo
else
KEXEC_ARGS="$KEXEC_ARGS --elf64-core-headers"
fi
else
FOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf64-core-headers`
if [ -z "$FOUND_ELF_ARGS" ]
then
KEXEC_ARGS="$KEXEC_ARGS --elf32-core-headers"
fi
fi
fi
KDUMP_COMMANDLINE=`echo $KDUMP_COMMANDLINE | sed -e 's/crashkernel=[0-9]\+[MmKkGg]@[0-9]\+[MmGgKk]//'`
KDUMP_COMMANDLINE=`echo $KDUMP_COMMANDLINE | sed -e's/mem=[0-9]\+[GMKgmk]* *//'`
KDUMP_COMMANDLINE=`echo $KDUMP_COMMANDLINE | sed -e's/hugepages=[0-9]\+ */ /g' -e's/hugepagesz=[0-9]\+[kKmMgG]* */ /g'`
KDUMP_COMMANDLINE="${KDUMP_COMMANDLINE} ${KDUMP_COMMANDLINE_APPEND}"
avoid_cdrom_drive
KDUMP_COMMANDLINE="${KDUMP_COMMANDLINE} ${KDUMP_IDE_NOPROBE_COMMANDLINE}"
if ! grep -q /sys/kernel/debug /proc/mounts;
then
mount -t debugfs debug /sys/kernel/debug
MNTDEBUG=/sys/kernel/debug
fi
KEXEC_OUTPUT=`$KEXEC $KEXEC_ARGS $standard_kexec_args \
--command-line="$KDUMP_COMMANDLINE" \
--initrd=$kdump_initrd $kdump_kernel 2>&1`
if [ $? == 0 ]; then
umount $MNTDEBUG 2>/dev/null
$LOGGER "kexec: loaded kdump kernel"
return 0
else
umount $MNTDEBUG 2>/dev/null
$LOGGER $KEXEC_OUTPUT
$LOGGER "kexec: failed to load kdump kernel"
return 1
fi
}
function propagate_ssh_key()
{
#Check if selinux is on... must flip to permissive mode
#for the moment to create key, then flip back...
se_enforce=`/usr/sbin/sestatus | grep -c "^Current mode.*enforcing"`
if [ "$se_enforce" -ge 1 ]; then
/usr/sbin/setenforce 0 2>&1 > /dev/null
fi
while read config_opt config_val; do
case "$config_opt" in
sshkey)
SSH_KEY_LOCATION=$config_val
;;
*)
;;
esac
done < $KDUMP_CONFIG_FILE
local KEYFILE=$SSH_KEY_LOCATION
local errmsg="Failed to propagate ssh key"
#make sure they've configured kdump.conf for ssh dumps
local SSH_TARGET=`awk '/^\ *net.*@.*$/ {print $0}' $KDUMP_CONFIG_FILE`
if [ -z "$SSH_TARGET" ]; then
echo "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate"
$LOGGER "$errmsg, no ssh config specified in $KDUMP_CONFIG_FILE"
exit 1
fi
#Check to see if we already created key, if not, create it.
if [ -f $KEYFILE ]; then
echo "Using existing keys..."
else
echo -n "Generating new ssh keys... "
/usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/null
echo "done."
fi
#If necessary, flip selinux back to enforcing
if [ "$se_enforce" -ge 1 ]; then
/usr/sbin/setenforce 1 2>&1 > /dev/null
fi
#now find the target ssh user and server to contact.
SSH_USER=`echo $SSH_TARGET | cut -d\ -f2 | cut -d@ -f1`
SSH_SERVER=`echo $SSH_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'`
#now send the found key to the found server
ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER &>/dev/null
RET=$?
if [ $RET == 0 ]; then
echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER
$LOGGER "propagated ssh key (ssh server: $SSH_SERVER)"
return 0
else
echo $KEYFILE failed in transfer to $SSH_SERVER
$LOGGER "$errmsg, unable to transfer $KEYFILE to $SSH_SERVER"
exit 1
fi
}
function status()
{
if [ ! -e /sys/kernel/kexec_crash_loaded ]
then
return 2
fi
if [ -f /proc/xen/capabilities ] && grep -q "control_d" /proc/xen/capabilities
then
: # We are in dom0
elif [ -f /sys/hypervisor/type ] && grep -q "xen" /sys/hypervisor/type
then
return 2 # We are in PV
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
}
function save_raw()
{
local kdump_path
raw_part=$(awk '$1 ~ /^raw$/ { print $2; }' $KDUMP_CONFIG_FILE)
if [ "$raw_part" ]; then
[ -b "$raw_part" ] || {
echo "raw partition $raw_part not found"
return 1
}
kdump_path=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`
if [ -z "$kdump_path" ]; then
coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"
else
coredir="${kdump_path}/`date +"%Y-%m-%d-%H:%M"`"
fi
mkdir -p $coredir
[ -d $coredir ] || {
echo "failed to create $coredir"
return 1
}
if makedumpfile -R $coredir/vmcore <$raw_part >/dev/null 2>&1
then
# dump found
echo "Dump saved to $coredir/vmcore"
# wipe makedumpfile header
dd if=/dev/zero of=$raw_part bs=1b count=1 2>/dev/null
else
rm -rf $coredir
fi
fi
return 0
}
function start()
{
save_raw
if [ $? -ne 0 ]; then
echo -n "Starting kdump:"; failure; echo
$LOGGER "failed to start up"
return 1
fi
status
rc=$?
if [ $rc == 2 ]; then
echo -n "Kdump is not supported on this kernel"; failure; echo
return 1;
else
if [ $rc == 0 ]; then
echo -n "Kdump already running"; success; echo
return 0
fi
fi
check_config
if [ $? != 0 ]; then
echo -n "Starting kdump:"; failure; echo
$LOGGER "failed to start up, config file incorrect"
return 1
fi
load_kdump
if [ $? != 0 ]; then
echo -n "Starting kdump:"; failure; echo
$LOGGER "failed to start up"
return 1
fi
echo -n "Starting kdump:"; success; echo
$LOGGER "started up"
}
function stop()
{
$KEXEC -p -u 2>/dev/null
if [ $? == 0 ]; then
$LOGGER "kexec: unloaded kdump kernel"
echo -n "Stopping kdump:"; success; echo
$LOGGER "stopped"
else
$LOGGER "kexec: failed to unload kdump kernel"
echo -n "Stopping kdump:"; failure; echo
$LOGGER "failed to stop"
fi
}
function do_final_action()
{
reboot
}
function run_kdump_pre()
{
KDUMP_PRE=$(awk '/^kdump_pre/ {print $2}' $KDUMP_CONFIG_FILE)
if [ -x "$KDUMP_PRE" ]; then
$LOGGER "kdump: run $KDUMP_PRE"
$KDUMP_PRE
fi
}
case "$1" in
start)
if [ -s /proc/vmcore ]; then
run_kdump_pre
save_core
run_kdump_post $?
do_final_action
else
start
fi
;;
stop)
stop
;;
status)
EXIT_CODE=0
status
case "$?" in
0)
echo "Kdump is operational"
;;
1)
echo "Kdump is not operational"
EXIT_CODE=1
;;
2)
echo "Kdump is unsupported on this kernel"
EXIT_CODE=1
;;
esac
exit $EXIT_CODE
;;
restart)
stop
start
;;
condrestart)
EXIT_CODE=1
status
case "$?" in
0)
stop
start
EXIT_CODE=0
;;
esac
exit $EXIT_CODE
;;
propagate)
propagate_ssh_key
;;
*)
echo $"Usage: $0 {start|stop|status|restart|propagate}"
exit 1
esac
exit $?