Add ssh dump support

Add ssh dump support

changes including below items:
1. sshkey option
2. sshkey propagate
3. fix a bug of  _server ip calculation for dump target string
4. change the prefix of kdump hook from 93 to 01 to avoid dhclient and
   other cleanups happening before us
5. enable network with dracut cmdline rd.neednet=1 when there's network
   target config

[v1 - v2]:
Only check_ssh_target when there's ssh dump target in kdump config file

[v2 -> v3]
style fixes: trailing spaces and space before tab indent
remove set -x
simply check_ssh_target
use awk to get sshkey option value
change pivot hook order to 0000

Signed-off-by: Dave Young <dyoung@redhat.com>
This commit is contained in:
Dave Young 2012-02-22 11:16:09 +08:00 committed by Cong Wang
parent 6ffa63d416
commit ba0aa24316
6 changed files with 124 additions and 48 deletions

View File

@ -102,6 +102,7 @@
#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
#net my.server.com:/export/tmp #net my.server.com:/export/tmp
#net user@my.server.com #net user@my.server.com
#sshkey /root/.ssh/kdump_id_rsa
#path /var/crash #path /var/crash
#core_collector makedumpfile -c #core_collector makedumpfile -c
#link_delay 60 #link_delay 60

View File

@ -8,6 +8,15 @@ CORE_COLLECTOR="makedumpfile -d 31 -c"
DEFAULT_ACTION="dump_rootfs" DEFAULT_ACTION="dump_rootfs"
DATEDIR=`date +%d.%m.%y-%T` DATEDIR=`date +%d.%m.%y-%T`
DUMP_INSTRUCTION="" DUMP_INSTRUCTION=""
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
# we use manual setup nics in udev rules,
# so we need to test network is really ok
wait_for_net_ok() {
local ip=$(getarg ip)
local iface=`echo $ip|cut -d':' -f1`
return $(wait_for_route_ok $iface)
}
do_default_action() do_default_action()
{ {
@ -96,8 +105,8 @@ dump_nfs()
dump_ssh() dump_ssh()
{ {
ssh -q -o BatchMode=yes -o StrictHostKeyChecking=yes $1 mkdir -p $KDUMP_PATH/$DATEDIR || return 1 ssh -q -i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes $2 mkdir -p $KDUMP_PATH/$DATEDIR || return 1
scp -q -o BatchMode=yes -o StrictHostKeyChecking=yes /proc/vmcore "$1:$KDUMP_PATH/$DATEDIR" || return 1 scp -q -i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes /proc/vmcore "$2:$KDUMP_PATH/$DATEDIR" || return 1
return 0 return 0
} }
@ -105,26 +114,19 @@ read_kdump_conf()
{ {
local conf_file="/etc/kdump.conf" local conf_file="/etc/kdump.conf"
if [ -f "$conf_file" ]; then if [ -f "$conf_file" ]; then
# first get the necessary variables
while read config_opt config_val; while read config_opt config_val;
do do
case "$config_opt" in case "$config_opt" in
ext[234]|xfs|btrfs|minix)
add_dump_code "dump_localfs $config_val || do_default_action"
;;
raw)
add_dump_code "dump_raw $config_val || do_default_action"
;;
path) path)
KDUMP_PATH="$config_val" KDUMP_PATH="$config_val"
;; ;;
core_collector) core_collector)
CORE_COLLECTOR="$config_val" CORE_COLLECTOR="$config_val"
;; ;;
net) sshkey)
if [[ "$config_val" =~ "@" ]]; then if [ -f "$config_val" ]; then
add_dump_code "dump_ssh $config_val || do_default_action" SSH_KEY_LOCATION=$config_val
else
add_dump_code "dump_nfs $config_val || do_default_action"
fi fi
;; ;;
default) default)
@ -145,6 +147,27 @@ read_kdump_conf()
;; ;;
esac esac
done < $conf_file done < $conf_file
# rescan for add code for dump target
while read config_opt config_val;
do
case "$config_opt" in
ext[234]|xfs|btrfs|minix)
add_dump_code "dump_localfs $config_val || do_default_action"
;;
raw)
add_dump_code "dump_raw $config_val || do_default_action"
;;
net)
wait_for_net_ok
if [[ "$config_val" =~ "@" ]]; then
add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val || do_default_action"
else
add_dump_code "dump_nfs $config_val || do_default_action"
fi
;;
esac
done < $conf_file
fi fi
} }

View File

@ -52,7 +52,7 @@ install() {
;; ;;
net) net)
if strstr "$config_val" "@"; then if strstr "$config_val" "@"; then
_server=$(echo $config_val | sed -e 's#.*@\(.*\):.*#\1#') _server=`echo $config_val | sed 's/.*@//' | cut -d':' -f1`
else else
_server=$(echo $config_val | sed -e 's#\(.*\):.*#\1#') _server=$(echo $config_val | sed -e 's#\(.*\):.*#\1#')
fi fi
@ -68,7 +68,7 @@ install() {
# we are on the same subnet # we are on the same subnet
_netdev=`echo $_netdev|awk '{print $3}'|head -n 1` _netdev=`echo $_netdev|awk '{print $3}'|head -n 1`
fi fi
echo " ip=$_netdev:dhcp" > ${initdir}/etc/cmdline.d/40ip.conf echo " ip=$_netdev:dhcp rd.neednet=1" > ${initdir}/etc/cmdline.d/40ip.conf
if is_bridge "$_netdev"; then if is_bridge "$_netdev"; then
echo " bridge=$_netdev:$(cd /sys/class/net/$_netdev/brif/; echo *)" > ${initdir}/etc/cmdline.d/41bridge.conf echo " bridge=$_netdev:$(cd /sys/class/net/$_netdev/brif/; echo *)" > ${initdir}/etc/cmdline.d/41bridge.conf
elif is_bond "$_netdev"; then elif is_bond "$_netdev"; then
@ -84,8 +84,8 @@ install() {
inst "/bin/date" "/bin/date" inst "/bin/date" "/bin/date"
inst "/bin/sync" "/bin/sync" inst "/bin/sync" "/bin/sync"
inst "/bin/cut" "/bin/cut"
inst "/sbin/makedumpfile" "/sbin/makedumpfile" inst "/sbin/makedumpfile" "/sbin/makedumpfile"
inst "/tmp/$$-kdump.conf" "/etc/kdump.conf" inst "/tmp/$$-kdump.conf" "/etc/kdump.conf"
inst_hook pre-pivot 93 "$moddir/kdump.sh" inst_hook pre-pivot 0000 "$moddir/kdump.sh"
} }

View File

@ -10,6 +10,9 @@ KDUMP_COMMANDLINE=""
KEXEC_ARGS="" KEXEC_ARGS=""
KDUMP_CONFIG_FILE="/etc/kdump.conf" KDUMP_CONFIG_FILE="/etc/kdump.conf"
MKDUMPRD="/sbin/mkdumprd -d -f" MKDUMPRD="/sbin/mkdumprd -d -f"
SAVE_PATH=/var/crash
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
DUMP_TARGET=""
LOGGER="/usr/bin/logger -p info -t kdump" LOGGER="/usr/bin/logger -p info -t kdump"
@ -171,8 +174,56 @@ function load_kdump()
fi fi
} }
function check_ssh_config()
{
while read config_opt config_val; do
case "$config_opt" in
sshkey)
if [ -f "$config_val" ]; then
# canonicalize the path
SSH_KEY_LOCATION=$(/usr/bin/readlink -m $config_val)
else
echo "WARNING: '$config_val' doesn't exist, using default value '$SSH_KEY_LOCATION'"
fi
;;
path)
SAVE_PATH=$config_val
;;
net)
DUMP_TARGET=$config_val
;;
*)
;;
esac
done < $KDUMP_CONFIG_FILE
#make sure they've configured kdump.conf for ssh dumps
local SSH_TARGET=`echo -n $DUMP_TARGET|sed '/.*@/p'`
if [ -z "$SSH_TARGET" ]; then
return 1
fi
return 0
}
function check_ssh_target()
{
ssh -q -i $SSH_KEY_LOCATION -o BatchMode=yes $DUMP_TARGET mkdir -p $SAVE_PATH
if [ $? -ne 0 ]; then
echo "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"service kdump propagate\""
exit $?
fi
return 0
}
function propagate_ssh_key() function propagate_ssh_key()
{ {
check_ssh_config
if [ $? -ne 0 ]; 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 if selinux is on... must flip to permissive mode #Check if selinux is on... must flip to permissive mode
#for the moment to create key, then flip back... #for the moment to create key, then flip back...
se_enforce=`/usr/sbin/sestatus | grep -c "^Current mode.*enforcing"` se_enforce=`/usr/sbin/sestatus | grep -c "^Current mode.*enforcing"`
@ -180,33 +231,15 @@ function propagate_ssh_key()
/usr/sbin/setenforce 0 2>&1 > /dev/null /usr/sbin/setenforce 0 2>&1 > /dev/null
fi fi
#Use dedicated key for kdump local KEYFILE=$SSH_KEY_LOCATION
if [ ! -d /root/.ssh ]; then
mkdir /root/.ssh
chmod 700 /root/.ssh
fi
if [ ! -e /root/.ssh/config ]; then
echo "IdentityFile ~/.ssh/kdump_id_rsa" >> /root/.ssh/config
elif [ `grep -c kdump_id_rsa /root/.ssh/config` -eq 0 ]; then
echo "IdentityFile ~/.ssh/kdump_id_rsa" >> /root/.ssh/config
fi
local KEYFILE=/root/.ssh/kdump_id_rsa.pub
local errmsg="Failed to propagate ssh key" 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. #Check to see if we already created key, if not, create it.
if [ -f $KEYFILE ]; then if [ -f $KEYFILE ]; then
echo "Using existing keys..." echo "Using existing keys..."
else else
echo -n "Generating new ssh keys... " echo -n "Generating new ssh keys... "
/usr/bin/ssh-keygen -t rsa -f /root/.ssh/kdump_id_rsa -N "" 2>&1 > /dev/null /usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/null
echo "done." echo "done."
fi fi
@ -216,11 +249,11 @@ function propagate_ssh_key()
fi fi
#now find the target ssh user and server to contact. #now find the target ssh user and server to contact.
SSH_USER=`echo $SSH_TARGET | cut -d\ -f2 | cut -d@ -f1` SSH_USER=`echo $DUMP_TARGET | cut -d\ -f2 | cut -d@ -f1`
SSH_SERVER=`echo $SSH_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'` SSH_SERVER=`echo $DUMP_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'`
#now send the found key to the found server #now send the found key to the found server
ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER &>/dev/null ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER
RET=$? RET=$?
if [ $RET == 0 ]; then if [ $RET == 0 ]; then
echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER
@ -262,6 +295,9 @@ function start()
return 0 return 0
fi fi
fi fi
check_ssh_config && check_ssh_target
check_config check_config
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo -n "Starting kdump:"; echo echo -n "Starting kdump:"; echo

View File

@ -1,6 +1,6 @@
Name: kexec-tools Name: kexec-tools
Version: 2.0.3 Version: 2.0.3
Release: 38%{?dist} Release: 39%{?dist}
License: GPLv2 License: GPLv2
Group: Applications/System Group: Applications/System
Summary: The kexec/kdump userspace component. Summary: The kexec/kdump userspace component.
@ -287,6 +287,9 @@ done
%changelog %changelog
* Wed Feb 22 2012 Dave Young <ruyang@redhat.com> - 2.0.2-39
- Add ssh dump support, resolve bug 789253.
* Fri Jan 27 2012 Cong Wang <xiyou.wangcong@gmail.com> - 2.0.2-38 * Fri Jan 27 2012 Cong Wang <xiyou.wangcong@gmail.com> - 2.0.2-38
- Pull the latest makedumpfile release, 1.4.2. - Pull the latest makedumpfile release, 1.4.2.

View File

@ -9,6 +9,7 @@
export IN_KDUMP=1 export IN_KDUMP=1
conf_file="/etc/kdump.conf" conf_file="/etc/kdump.conf"
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
extra_modules="" extra_modules=""
dracut_args=("-m" "kdumpbase" "--add" "dash" "--add" "fstab-sys" "--add" "kernel-modules" "-c" "/dev/null" "-I" "/sbin/makedumpfile") dracut_args=("-m" "kdumpbase" "--add" "dash" "--add" "fstab-sys" "--add" "kernel-modules" "-c" "/dev/null" "-I" "/sbin/makedumpfile")
@ -28,6 +29,10 @@ add_dracut_mount() {
add_dracut_arg "--mount" "$1" add_dracut_arg "--mount" "$1"
} }
add_dracut_sshkey() {
add_dracut_arg "--sshkey" "$1"
}
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
-d) -d)
@ -94,6 +99,13 @@ add_mount() {
add_dracut_mount "$(to_mount "$(get_rootdev)")" add_dracut_mount "$(to_mount "$(get_rootdev)")"
if [ -n "$conf_file" ]; then if [ -n "$conf_file" ]; then
# 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
while read config_opt config_val; while read config_opt config_val;
do do
case "$config_opt" in case "$config_opt" in
@ -115,6 +127,7 @@ if [ -n "$conf_file" ]; then
if strstr "$config_val" "@"; if strstr "$config_val" "@";
then then
add_dracut_module "ssh-client" add_dracut_module "ssh-client"
add_dracut_sshkey "$SSH_KEY_LOCATION"
else else
add_dracut_module "nfs" add_dracut_module "nfs"
add_mount "$config_val" add_mount "$config_val"