2006-07-20 03:36:18 +00:00
|
|
|
#!/bin/bash --norc
|
2011-07-21 10:51:33 +00:00
|
|
|
# New mkdumprd
|
2006-07-20 03:36:18 +00:00
|
|
|
#
|
2011-07-21 10:51:33 +00:00
|
|
|
# Copyright 2011 Red Hat, Inc.
|
2006-07-20 03:36:18 +00:00
|
|
|
#
|
2011-07-21 10:51:33 +00:00
|
|
|
# Written by Cong Wang <amwang@redhat.com>
|
2006-07-20 03:36:18 +00:00
|
|
|
#
|
|
|
|
|
2011-07-21 10:51:33 +00:00
|
|
|
export IN_KDUMP=1
|
2006-07-20 03:36:18 +00:00
|
|
|
|
2011-07-21 10:51:33 +00:00
|
|
|
conf_file="/etc/kdump.conf"
|
2012-02-22 03:16:09 +00:00
|
|
|
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
2012-06-26 09:21:53 +00:00
|
|
|
SAVE_PATH=$(grep ^path $conf_file| cut -d' ' -f2)
|
|
|
|
[ -z "$SAVE_PATH" ] && SAVE_PATH="/var/crash"
|
2011-07-21 10:51:33 +00:00
|
|
|
extra_modules=""
|
2012-07-12 03:15:36 +00:00
|
|
|
dracut_args=("--hostonly" "-o" "plymouth dash")
|
2006-07-20 03:36:18 +00:00
|
|
|
|
2012-09-20 03:03:09 +00:00
|
|
|
get_persistent_dev() {
|
|
|
|
local i _tmp _dev
|
|
|
|
|
|
|
|
_dev=$(udevadm info --query=name --name="$1" 2>/dev/null)
|
|
|
|
[ -z "$_dev" ] && {
|
|
|
|
echo "Kernel dev name of $1 is not found."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2012-10-10 07:09:15 +00:00
|
|
|
for i in /dev/mapper/* /dev/disk/by-uuid/* /dev/disk/by-id/*; do
|
2012-09-20 03:03:09 +00:00
|
|
|
_tmp=$(udevadm info --query=name --name="$i" 2>/dev/null)
|
|
|
|
if [ "$_tmp" = "$_dev" ]; then
|
|
|
|
echo $i
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
echo "Persistent device name of $1 is not found."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2011-07-21 10:51:33 +00:00
|
|
|
add_dracut_arg() {
|
2011-12-16 10:06:45 +00:00
|
|
|
while [ $# -gt 0 ];
|
|
|
|
do
|
|
|
|
dracut_args+=("$1")
|
|
|
|
shift
|
|
|
|
done
|
2006-07-20 03:36:18 +00:00
|
|
|
}
|
|
|
|
|
2011-08-01 09:19:24 +00:00
|
|
|
add_dracut_module() {
|
2011-12-16 10:06:45 +00:00
|
|
|
add_dracut_arg "--add" "$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
add_dracut_mount() {
|
|
|
|
add_dracut_arg "--mount" "$1"
|
2011-08-01 09:19:24 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 03:16:09 +00:00
|
|
|
add_dracut_sshkey() {
|
|
|
|
add_dracut_arg "--sshkey" "$1"
|
|
|
|
}
|
|
|
|
|
2012-06-26 09:21:54 +00:00
|
|
|
# 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() {
|
2012-11-27 04:48:56 +00:00
|
|
|
local _dev _t _o _mntopts _pdev
|
2012-09-20 03:03:19 +00:00
|
|
|
_dev=$(to_dev_name $1)
|
2012-11-27 04:48:56 +00:00
|
|
|
_t=$(findmnt -k -f -n -r -o TARGET,FSTYPE $_dev)
|
|
|
|
_o=$(findmnt -k -f -n -r -o OPTIONS $_dev)
|
|
|
|
[ -z "$_t" -o -z "$_o" ] && return
|
|
|
|
_o=${_o/#ro/rw} #mount fs target as rw in 2nd kernel
|
|
|
|
_mntopts="$_t $_o"
|
2012-09-20 03:03:19 +00:00
|
|
|
#for non-nfs _dev converting to use udev persistent name
|
|
|
|
if [ -b "$_dev" ]; then
|
|
|
|
_pdev="$(get_persistent_dev $_dev)"
|
|
|
|
else
|
|
|
|
_pdev=$_dev
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$_pdev $_mntopts"
|
2012-06-26 09:21:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
to_mount_point() {
|
2012-09-20 03:03:19 +00:00
|
|
|
echo $(findmnt -k -f -n -r -o TARGET $1)
|
2012-06-26 09:21:54 +00:00
|
|
|
}
|
|
|
|
|
2012-11-27 04:48:56 +00:00
|
|
|
is_readonly_mount() {
|
|
|
|
local _mnt
|
|
|
|
_mnt=$(findmnt -k -f -n -r -o OPTIONS $1)
|
|
|
|
|
|
|
|
#fs/proc_namespace.c: show_mountinfo():
|
|
|
|
#seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
|
|
|
|
[[ "$_mnt" =~ ^ro ]]
|
|
|
|
}
|
|
|
|
|
2012-06-26 09:21:53 +00:00
|
|
|
#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"
|
2012-11-12 08:51:04 +00:00
|
|
|
_out=$(ssh -q -n $_opt $1 "df -P $SAVE_PATH")
|
2012-06-26 09:21:53 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2012-11-27 04:48:56 +00:00
|
|
|
#mkdir if save path does not exist on dump target filesystem
|
2012-06-26 09:21:54 +00:00
|
|
|
#$1=dump target
|
2012-11-27 04:48:56 +00:00
|
|
|
mkdir_save_path() {
|
2012-06-26 09:21:54 +00:00
|
|
|
local _mnt=$(to_mount_point $1)
|
2012-11-27 04:48:56 +00:00
|
|
|
local _remount="no"
|
|
|
|
local _ret
|
|
|
|
|
2012-06-26 09:21:54 +00:00
|
|
|
[ ! -d ${_mnt}/$SAVE_PATH ] && {
|
2012-11-27 04:48:56 +00:00
|
|
|
if is_readonly_mount $1; then
|
|
|
|
echo "Mounting $1 as read-write for creating dump directory.."
|
|
|
|
mount -o remount,rw $1
|
|
|
|
[ $? -ne 0 ] && {
|
|
|
|
echo "Mounting $1 as read-write failed."
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
_remount="yes"
|
|
|
|
fi
|
2012-06-26 09:21:54 +00:00
|
|
|
mkdir -p ${_mnt}/$SAVE_PATH
|
2012-11-27 04:48:56 +00:00
|
|
|
_ret=$?
|
|
|
|
[ "$_remount" = "yes" ] && {
|
|
|
|
echo "Remounting $1 as read-only."
|
|
|
|
mount -o remount,ro $1 || {
|
|
|
|
echo "Remounting $1 as read-only failed."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[ $_ret -ne 0 ] && {
|
2012-06-26 09:21:54 +00:00
|
|
|
echo "Creating ${_mnt}/$SAVE_PATH failed."
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
2012-11-27 04:48:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#Function: get_fs_size
|
|
|
|
#$1=dump target
|
|
|
|
get_fs_size() {
|
|
|
|
local _mnt=$(to_mount_point $1)
|
2012-06-26 09:21:54 +00:00
|
|
|
echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}')
|
|
|
|
}
|
|
|
|
|
2012-04-28 10:01:18 +00:00
|
|
|
#Function: get_raw_size
|
|
|
|
#$1=dump target
|
|
|
|
get_raw_size() {
|
|
|
|
echo -n $(fdisk -s "$1")
|
|
|
|
}
|
|
|
|
|
|
|
|
#Function: check_size
|
2012-06-26 09:21:54 +00:00
|
|
|
#$1: dump type string ('raw', 'fs', 'ssh')
|
2012-04-28 10:01:18 +00:00
|
|
|
#$2: dump target
|
|
|
|
check_size() {
|
|
|
|
local avail memtotal
|
|
|
|
|
|
|
|
memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
|
|
|
|
case "$1" in
|
|
|
|
raw)
|
|
|
|
avail=$(get_raw_size "$2")
|
|
|
|
;;
|
2012-06-26 09:21:53 +00:00
|
|
|
ssh)
|
|
|
|
avail=$(get_ssh_size "$2")
|
|
|
|
;;
|
2012-06-26 09:21:54 +00:00
|
|
|
fs)
|
|
|
|
avail=$(get_fs_size "$2")
|
|
|
|
;;
|
2012-04-28 10:01:18 +00:00
|
|
|
*)
|
|
|
|
return
|
|
|
|
esac
|
|
|
|
|
|
|
|
if [ $avail -lt $memtotal ]; then
|
2012-07-12 03:15:35 +00:00
|
|
|
echo "Warning: There might not be enough space to save a vmcore."
|
|
|
|
echo " The size of $2 should be greater than $memtotal kilo bytes."
|
2012-04-28 10:01:18 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2012-06-14 01:56:10 +00:00
|
|
|
is_ssh_dump_target()
|
|
|
|
{
|
2012-07-23 07:31:28 +00:00
|
|
|
grep -q "^ssh.*@" $conf_file
|
2012-06-14 01:56:10 +00:00
|
|
|
}
|
|
|
|
|
2012-06-14 01:57:07 +00:00
|
|
|
is_raw_dump_target()
|
|
|
|
{
|
|
|
|
grep -q "^raw" $conf_file
|
|
|
|
}
|
|
|
|
|
2012-06-14 01:56:10 +00:00
|
|
|
# $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
|
2012-06-14 01:57:07 +00:00
|
|
|
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
|
2012-06-14 01:56:10 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2012-01-25 08:58:35 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2012-04-28 10:01:18 +00:00
|
|
|
# firstly get right SSH_KEY_LOCATION
|
2012-12-20 05:24:25 +00:00
|
|
|
keyfile=$(awk '/^sshkey/ {print $2}' $conf_file)
|
2012-04-28 10:01:18 +00:00
|
|
|
if [ -f "$keyfile" ]; then
|
|
|
|
# canonicalize the path
|
|
|
|
SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile)
|
|
|
|
fi
|
|
|
|
|
2012-06-22 06:50:40 +00:00
|
|
|
if [ "$(uname -m)" = "s390x" ]; then
|
|
|
|
add_dracut_module "znet"
|
|
|
|
fi
|
|
|
|
|
2012-04-28 10:01:18 +00:00
|
|
|
while read config_opt config_val;
|
|
|
|
do
|
|
|
|
case "$config_opt" in
|
|
|
|
extra_modules)
|
|
|
|
extra_modules="$extra_modules $config_val"
|
|
|
|
;;
|
2012-07-23 07:31:28 +00:00
|
|
|
ext[234]|xfs|btrfs|minix|nfs)
|
|
|
|
if [ "$config_opt" = "nfs" ]; then
|
|
|
|
add_dracut_module "nfs"
|
|
|
|
fi
|
2012-04-28 10:01:18 +00:00
|
|
|
add_mount "$config_val"
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
echo "Dump target $config_val is probably not mounted."
|
|
|
|
exit 1
|
|
|
|
fi
|
2012-11-27 04:48:56 +00:00
|
|
|
mkdir_save_path $config_val
|
2012-06-26 09:21:54 +00:00
|
|
|
check_size fs $config_val
|
2012-04-28 10:01:18 +00:00
|
|
|
;;
|
|
|
|
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
|
|
|
|
}
|
2012-09-20 03:03:24 +00:00
|
|
|
add_dracut_arg "--device" "$(get_persistent_dev $config_val)"
|
2012-04-28 10:01:18 +00:00
|
|
|
check_size raw $config_val
|
|
|
|
;;
|
2012-07-23 07:31:28 +00:00
|
|
|
ssh)
|
2012-04-28 10:01:18 +00:00
|
|
|
if strstr "$config_val" "@";
|
|
|
|
then
|
2012-06-26 09:21:53 +00:00
|
|
|
check_size ssh $config_val
|
2012-04-28 10:01:18 +00:00
|
|
|
add_dracut_module "ssh-client"
|
|
|
|
add_dracut_sshkey "$SSH_KEY_LOCATION"
|
|
|
|
else
|
2012-07-23 07:31:28 +00:00
|
|
|
echo "Bad ssh dump target $config_val"
|
|
|
|
exit 1
|
2012-04-28 10:01:18 +00:00
|
|
|
fi
|
|
|
|
;;
|
2012-07-23 07:31:28 +00:00
|
|
|
net)
|
|
|
|
echo "net option is not supported anymore, please use nfs|ssh instead."
|
|
|
|
exit 1
|
|
|
|
;;
|
2012-04-28 10:01:18 +00:00
|
|
|
core_collector)
|
2012-06-14 01:56:10 +00:00
|
|
|
verify_core_collector "$config_val"
|
2012-04-28 10:01:18 +00:00
|
|
|
;;
|
2012-06-26 09:21:52 +00:00
|
|
|
blacklist)
|
|
|
|
add_dracut_arg "--omit-drivers" "$config_val"
|
|
|
|
;;
|
2012-04-28 10:01:18 +00:00
|
|
|
*)
|
|
|
|
if [ -n $(echo $config_opt | grep "^#.*$") ]
|
|
|
|
then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done < $conf_file
|
2006-07-20 03:36:18 +00:00
|
|
|
|
2011-07-21 10:51:33 +00:00
|
|
|
if [ -n "$extra_modules" ]
|
|
|
|
then
|
2012-01-10 14:34:47 +00:00
|
|
|
add_dracut_arg "--add-drivers" "$extra_modules"
|
2010-06-13 19:20:48 +00:00
|
|
|
fi
|
|
|
|
|
2011-12-16 10:06:45 +00:00
|
|
|
dracut "${dracut_args[@]}" -M "$@"
|
2012-01-25 04:18:51 +00:00
|
|
|
_rc=$?
|
2012-01-10 05:28:27 +00:00
|
|
|
sync
|
2012-01-25 04:18:51 +00:00
|
|
|
exit $_rc
|
2008-02-22 12:40:20 +00:00
|
|
|
|