b47c0915d2
Currently net options means either nfs or ssh dump. Better to split these two into standalone options. That's more clear to user. after the split, ssh dump need user specify "ssh user@host" nfs dump need user specify "nfs host:nfsshare" Signed-off-by: Dave Young <dyoung@redhat.com> Acked-by: Vivek Goyal <vgoyal@redhat.com>
245 lines
5.4 KiB
Bash
245 lines
5.4 KiB
Bash
#!/bin/bash --norc
|
|
# New mkdumprd
|
|
#
|
|
# Copyright 2011 Red Hat, Inc.
|
|
#
|
|
# Written by Cong Wang <amwang@redhat.com>
|
|
#
|
|
|
|
export IN_KDUMP=1
|
|
|
|
conf_file="/etc/kdump.conf"
|
|
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
|
SAVE_PATH=$(grep ^path $conf_file| cut -d' ' -f2)
|
|
[ -z "$SAVE_PATH" ] && SAVE_PATH="/var/crash"
|
|
extra_modules=""
|
|
dracut_args=("--hostonly" "-o" "plymouth dash")
|
|
|
|
add_dracut_arg() {
|
|
while [ $# -gt 0 ];
|
|
do
|
|
dracut_args+=("$1")
|
|
shift
|
|
done
|
|
}
|
|
|
|
add_dracut_module() {
|
|
add_dracut_arg "--add" "$1"
|
|
}
|
|
|
|
add_dracut_mount() {
|
|
add_dracut_arg "--mount" "$1"
|
|
}
|
|
|
|
add_dracut_sshkey() {
|
|
add_dracut_arg "--sshkey" "$1"
|
|
}
|
|
|
|
# Generic substring function. If $2 is in $1, return 0.
|
|
strstr() { [[ $1 =~ $2 ]]; }
|
|
|
|
to_dev_name() {
|
|
local dev="$1"
|
|
|
|
case "$dev" in
|
|
UUID=*)
|
|
dev=`blkid -U "${dev#UUID=}"`
|
|
;;
|
|
LABEL=*)
|
|
dev=`blkid -L "${dev#LABEL=}"`
|
|
;;
|
|
esac
|
|
echo $dev
|
|
}
|
|
|
|
get_rootdev() {
|
|
mount | grep 'on / ' | grep -v rootfs | awk '{print $1}'
|
|
}
|
|
|
|
to_mount() {
|
|
local _dev=$(to_dev_name $1)
|
|
echo "$(grep "$_dev" /proc/mounts | cut -d' ' -f1-4)"
|
|
}
|
|
|
|
to_mount_point() {
|
|
local _dev=$(to_dev_name $1)
|
|
echo "$(grep "$_dev" /proc/mounts | cut -d' ' -f2)"
|
|
}
|
|
|
|
#Function: get_ssh_size
|
|
#$1=dump target
|
|
get_ssh_size() {
|
|
local _opt _out _size
|
|
_opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
|
|
_out=$(ssh -q $_opt $1 "df -P $SAVE_PATH")
|
|
if [ $? -ne 0 ]; then
|
|
echo "checking remote ssh server available size failed."
|
|
exit 1
|
|
fi
|
|
#ssh output removed the line break, so print $11 instead of $4
|
|
_size=$(echo -n $_out|tail -1 | awk '{print $11}')
|
|
echo -n $_size
|
|
}
|
|
|
|
#Function: get_fs_size
|
|
#$1=dump target
|
|
get_fs_size() {
|
|
local _mnt=$(to_mount_point $1)
|
|
[ ! -d ${_mnt}/$SAVE_PATH ] && {
|
|
mkdir -p ${_mnt}/$SAVE_PATH
|
|
[ $? -ne 0 ] && {
|
|
echo "Creating ${_mnt}/$SAVE_PATH failed."
|
|
exit 1
|
|
}
|
|
}
|
|
echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}')
|
|
}
|
|
|
|
#Function: get_raw_size
|
|
#$1=dump target
|
|
get_raw_size() {
|
|
echo -n $(fdisk -s "$1")
|
|
}
|
|
|
|
#Function: check_size
|
|
#$1: dump type string ('raw', 'fs', 'ssh')
|
|
#$2: dump target
|
|
check_size() {
|
|
local avail memtotal
|
|
|
|
memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
|
|
case "$1" in
|
|
raw)
|
|
avail=$(get_raw_size "$2")
|
|
;;
|
|
ssh)
|
|
avail=$(get_ssh_size "$2")
|
|
;;
|
|
fs)
|
|
avail=$(get_fs_size "$2")
|
|
;;
|
|
*)
|
|
return
|
|
esac
|
|
|
|
if [ $avail -lt $memtotal ]; then
|
|
echo "Warning: There might not be enough space to save a vmcore."
|
|
echo " The size of $2 should be greater than $memtotal kilo bytes."
|
|
fi
|
|
}
|
|
|
|
is_ssh_dump_target()
|
|
{
|
|
grep -q "^ssh.*@" $conf_file
|
|
}
|
|
|
|
is_raw_dump_target()
|
|
{
|
|
grep -q "^raw" $conf_file
|
|
}
|
|
|
|
# $1: core_collector config value
|
|
verify_core_collector() {
|
|
if grep -q "^raw" $conf_file && [ "${1%% *}" != "makedumpfile" ]; then
|
|
echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
|
|
fi
|
|
if is_ssh_dump_target || is_raw_dump_target; then
|
|
if [ "${1%% *}" = "makedumpfile" ]; then
|
|
! strstr "$1" "-F" && {
|
|
echo "The specified dump target needs makedumpfile \"-F\" option."
|
|
exit 1
|
|
}
|
|
fi
|
|
fi
|
|
}
|
|
|
|
add_mount() {
|
|
local _dev=$(to_dev_name "$1")
|
|
local _mnt=$(to_mount "$1")
|
|
if [ "$_dev" = "$(get_rootdev)" ]; then
|
|
:
|
|
elif [ -n "$_mnt" ]; then
|
|
add_dracut_mount "$_mnt"
|
|
else
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# firstly get right SSH_KEY_LOCATION
|
|
keyfile=$(awk '/sshkey/ {print $2}' $conf_file)
|
|
if [ -f "$keyfile" ]; then
|
|
# canonicalize the path
|
|
SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile)
|
|
fi
|
|
|
|
if [ "$(uname -m)" = "s390x" ]; then
|
|
add_dracut_module "znet"
|
|
fi
|
|
|
|
while read config_opt config_val;
|
|
do
|
|
case "$config_opt" in
|
|
extra_modules)
|
|
extra_modules="$extra_modules $config_val"
|
|
;;
|
|
ext[234]|xfs|btrfs|minix|nfs)
|
|
if [ "$config_opt" = "nfs" ]; then
|
|
add_dracut_module "nfs"
|
|
fi
|
|
add_mount "$config_val"
|
|
if [ $? -ne 0 ]; then
|
|
echo "Dump target $config_val is probably not mounted."
|
|
exit 1
|
|
fi
|
|
check_size fs $config_val
|
|
;;
|
|
raw)
|
|
#checking raw disk writable
|
|
dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || {
|
|
echo "Bad raw disk $config_val"
|
|
exit 1
|
|
}
|
|
check_size raw $config_val
|
|
;;
|
|
ssh)
|
|
if strstr "$config_val" "@";
|
|
then
|
|
check_size ssh $config_val
|
|
add_dracut_module "ssh-client"
|
|
add_dracut_sshkey "$SSH_KEY_LOCATION"
|
|
else
|
|
echo "Bad ssh dump target $config_val"
|
|
exit 1
|
|
fi
|
|
;;
|
|
net)
|
|
echo "net option is not supported anymore, please use nfs|ssh instead."
|
|
exit 1
|
|
;;
|
|
core_collector)
|
|
verify_core_collector "$config_val"
|
|
;;
|
|
blacklist)
|
|
add_dracut_arg "--omit-drivers" "$config_val"
|
|
;;
|
|
*)
|
|
if [ -n $(echo $config_opt | grep "^#.*$") ]
|
|
then
|
|
continue
|
|
fi
|
|
;;
|
|
esac
|
|
done < $conf_file
|
|
|
|
if [ -n "$extra_modules" ]
|
|
then
|
|
add_dracut_arg "--add-drivers" "$extra_modules"
|
|
fi
|
|
|
|
dracut "${dracut_args[@]}" -M "$@"
|
|
_rc=$?
|
|
sync
|
|
exit $_rc
|
|
|