Description:
Currently kdump doesn't support ipv6 nfs/ssh dump. Ipv6 is the latest version
of the Internet Protocal. so it is a significant feture for kdump to enhance
to support ipv6.
Solutions:
Since dracut has supported ipv6 now, it is easy to change the kdump code to
support ipv6. Just need pass the right _ip_opts to the second kernle. What is
the main difference in userspace bettwen ipv4 and ipv6 is the ip address format.
For ipv6 nfs dump:
if ipv6 address type is link scope, /etc/kdump.conf should be edited like
"nfs [fe80::5054:ff:fe48:ca80%eth0]:/mnt"
else /etc/kdump.conf should be edited like "nfs [2001:db8:0:f101::2]:/mnt"
For ipv6 ssh dump
if ipv6 address type is link scope, /etc/kdump.conf should be edited like
"ssh root at fe80::5054:ff:fe48:ca80%eth0"
else /etc/kdump.conf should be edited like "ssh root at 2001:db8:0:f101::2"
What this patch do is:
a): Add a function is_ipv6_target to tell what version of Internet Protocal
(ipv4/ipv6) kdump will use to dump to remote target.
b): Modify kdump_install_net to handle ipv6 configuration in /etc/kdump.conf
correctly. Get the ipv6 address from /etc/kdump.conf is more complicated
than ipv4 because the difference configuration format mentioned above.
c): Based on the ip address type, using corresponding ip address as HOST_IP
in second kernel.
It was tested for IPV6 and IPV4 address in beaker machine and passed.
Note:
1): Currntly only f19 support remount a nfs target in ipv6. detail in https:
//bugzilla.redhat.com/show_bug.cgi?id=1099761. If using in f20, you can
comment out "mount -o remount,rw $_mp || return 1" in kdump.sh line
105.
2): If Using static ipv6 address and configuring nfs/ssh with hostname of
remote target, MUST add a ipv6 DNS in ifcfg-devname.
How to create a ipv6 enviromnet.
1): Reserving two beaker machine with family fedora.
2): Choosing a beaker machine as a nfs/ssh server and delete it's ipv4 address
by "ip address del ipv4-address dev nicname"
3): Configuring the /etc/kdump.conf like mentioned above.
Signed-off-by: Arthur Zou <zzou(a)redhat.com>
Signed-off-by: Minfei Huang <mhuang(a)redhat.com>
---
dracut-kdump.sh | 8 ++-
dracut-module-setup.sh | 142 +++++++++++++++++++++++++++++++++++++------------
kdump-lib.sh | 2 +-
mkdumprd | 14 ++++-
4 files changed, 127 insertions(+), 39 deletions(-)
diff --git a/dracut-kdump.sh b/dracut-kdump.sh
index cbfe7c6..2d4551d 100755
--- a/dracut-kdump.sh
+++ b/dracut-kdump.sh
@@ -121,9 +121,13 @@ get_host_ip()
then
kdumpnic=$(getarg kdumpnic=)
[ -z "$kdumpnic" ] && echo "kdump: failed to get
kdumpnic!" && return 1
- _host=`ip addr show dev $kdumpnic|grep 'inet '`
+ if is_ipv6_target; then
+ _host=`ip -6 addr show dev $kdumpnic|grep 'inet6'`
+ else
+ _host=`ip addr show dev $kdumpnic|grep 'inet '`
+ fi
[ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic"
&& return 1
- _host="${_host##*inet }"
+ _host=`echo $_host | cut -d' ' -f2`
_host="${_host%%/*}"
[ -z "$_host" ] && echo "kdump: wrong kdumpnic:
$kdumpnic" && return 1
HOST_IP=$_host
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 0f0e83f..03fd87e 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -70,14 +70,24 @@ kdump_setup_dns() {
#$2: srcaddr
#if it use static ip echo it, or echo null
kdump_static_ip() {
- local _netmask _gateway
+ local _netmask _gateway _ipaddr
local _netdev="$1" _srcaddr="$2"
- local _ipaddr=$(ip addr show dev $_netdev permanent | \
+
+ if is_ipv6_target; then
+ _ipaddr=$(ip -6 addr show dev $_netdev permanent | \
+ awk "/ $_srcaddr\/.* /{print \$2}")
+ if [ -n "$_ipaddr" ]; then
+ _gateway=$(ip -6 route list dev $_netdev | awk '/^default /{print
$3}')
+ echo -n "[${_srcaddr}]::[${_gateway}]:64::"
+ fi
+ else
+ _ipaddr=$(ip addr show dev $_netdev permanent | \
awk "/ $_srcaddr\/.* $_netdev\$/{print \$2}")
- if [ -n "$_ipaddr" ]; then
- _netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
- _gateway=$(ip route list dev $_netdev | awk '/^default /{print $3}')
- echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
+ if [ -n "$_ipaddr" ]; then
+ _netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
+ _gateway=$(ip route list dev $_netdev | awk '/^default /{print $3}')
+ echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
+ fi
fi
}
@@ -195,20 +205,36 @@ get_routes() {
local _netdev="$1" _target="$2"
local _route
- _route=`/sbin/ip route get to $_target 2>&1`
- if /sbin/ip route get to $_target | grep -q "via";
- then
- # route going to a different subnet via a router
- _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $5}'))
- echo $_route | awk '{printf("rd.route=%s:%s:%s\n", $1, $3,
_netdev)}' _netdev=$_netdev \
- >> ${initdir}/etc/cmdline.d/45route-static.conf
+ if is_ipv6_target; then
+ _route=`/sbin/ip -6 route get to $_target 2>&1`
+
+ if /sbin/ip -6 route get to $_target | grep -q "via"; then
+ # route going to a different subnet via a router
+ _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $7}'))
+
+ echo $_route | awk '{printf("rd.route=[%s]:[%s]:%s\n", $1, $5,
_netdev)}' _netdev=$_netdev \
+ >> ${initdir}/etc/cmdline.d/45route-static.conf
+ else
+ # route going to a different subnet though directly connected
+ _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $5}'))
+
+ echo $_route | awk '{printf("rd.route=[%s]::%s\n", $1,
_netdev)}' _netdev=$_netdev \
+ >> ${initdir}/etc/cmdline.d/45route-static.conf
+ fi
else
- # route going to a different subnet though directly connected
- _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $3}'))
- echo $_route | awk '{printf("rd.route=%s::%s\n", $1, _netdev)}'
_netdev=$_netdev \
- >> ${initdir}/etc/cmdline.d/45route-static.conf
+ _route=`/sbin/ip route get to $_target 2>&1`
+ if /sbin/ip route get to $_target | grep -q "via"; then
+ # route going to a different subnet via a router
+ _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $5}'))
+ echo $_route | awk '{printf("rd.route=%s:%s:%s\n", $1, $3,
_netdev)}' _netdev=$_netdev \
+ >> ${initdir}/etc/cmdline.d/45route-static.conf
+ else
+ # route going to a different subnet though directly connected
+ _netdev=$(kdump_setup_ifname $(echo $_route | awk '{print $3}'))
+ echo $_route | awk '{printf("rd.route=%s::%s\n", $1,
_netdev)}' _netdev=$_netdev \
+ >> ${initdir}/etc/cmdline.d/45route-static.conf
+ fi
fi
-
}
# Setup dracut to bringup a given network interface
@@ -265,24 +291,44 @@ kdump_install_net() {
local _server _netdev _srcaddr
local config_val="$1"
- _server=`echo $config_val | sed 's/.*@//' | cut -d':' -f1`
-
- _need_dns=`echo $_server|grep "[a-zA-Z]"`
- [ -n "$_need_dns" ] && _server=`getent hosts $_server|cut -d'
' -f1`
+ _server=`get_remote_host $config_val`
- _netdev=`/sbin/ip route get to $_server 2>&1`
- [ $? != 0 ] && echo "Bad kdump location: $config_val" &&
exit 1
+ if is_ipv6_target; then
+ _need_dns=`echo $_server|grep "[:]"`
+ [ -z "$_need_dns" ] && _server=`getent hosts $_server| head -n
1 | cut -d' ' -f1`
+ else
+ _need_dns=`echo $_server|grep "[a-zA-Z]"`
+ [ -n "$_need_dns" ] && _server=`getent hosts $_server| head -n
1 | cut -d' ' -f1`
+ fi
- #the field in the ip output changes if we go to another subnet
- if [ -n "`echo $_netdev | grep via`" ]
- then
- # we are going to a different subnet
- _srcaddr=`echo $_netdev|awk '{print $7}'|head -n 1`
- _netdev=`echo $_netdev|awk '{print $5;}'|head -n 1`
+ if is_ipv6_target; then
+ _netdev=`/sbin/ip -6 route get to $_server 2>&1`
+ [ $? != 0 ] && echo "Bad kdump location: $config_val"
&& exit 1
+ #the field in the ip output changes if we go to another subnet
+ if [ -n "`echo $_netdev | grep via`" ]
+ then
+ # we are going to a different subnet
+ _srcaddr=`echo $_netdev|awk '{print $9}'|head -n 1`
+ _netdev=`echo $_netdev|awk '{print $7;}'|head -n 1`
+ else
+ # we are on the same subnet
+ _srcaddr=`echo $_netdev|awk '{print $7}'|head -n 1`
+ _netdev=`echo $_netdev|awk '{print $5}'|head -n 1`
+ fi
else
- # we are on the same subnet
- _srcaddr=`echo $_netdev|awk '{print $5}'|head -n 1`
- _netdev=`echo $_netdev|awk '{print $3}'|head -n 1`
+ _netdev=`/sbin/ip route get to $_server 2>&1`
+ [ $? != 0 ] && echo "Bad kdump location: $config_val"
&& exit 1
+ #the field in the ip output changes if we go to another subnet
+ if [ -n "`echo $_netdev | grep via`" ]
+ then
+ # we are going to a different subnet
+ _srcaddr=`echo $_netdev|awk '{print $7}'|head -n 1`
+ _netdev=`echo $_netdev|awk '{print $5;}'|head -n 1`
+ else
+ # we are on the same subnet
+ _srcaddr=`echo $_netdev|awk '{print $5}'|head -n 1`
+ _netdev=`echo $_netdev|awk '{print $3}'|head -n 1`
+ fi
fi
kdump_setup_netdev "${_netdev}" "${_srcaddr}"
"${_server}"
@@ -360,6 +406,25 @@ kdump_install_conf() {
default_dump_target_install_conf
kdump_configure_fence_kdump "/tmp/$$-kdump.conf"
+
+ if is_ipv6_target; then
+ local _srcaddr
+ if is_ssh_dump_target; then
+ _srcaddr=$(get_option_value ssh)
+ elif is_nfs_dump_target; then
+ _srcaddr=$(get_option_value nfs)
+ fi
+
+ if [ "x" != "x"$_srcaddr ] && `echo $_srcaddr | grep
-q "%"`; then
+ local _netdev=${_srcaddr#*\%}
+ _netdev=${_netdev%]*}
+ local _pre_netdev=$(kdump_setup_ifname $_netdev)
+ if [ "x"$_netdev != "x"$_pre_netdev ]; then
+ sed -i "s#$_netdev#$_pre_netdev#"
"/tmp/$$-kdump.conf"
+ fi
+ fi
+ fi
+
inst "/tmp/$$-kdump.conf" "/etc/kdump.conf"
rm -f /tmp/$$-kdump.conf
}
@@ -438,8 +503,13 @@ kdump_setup_iscsi_device() {
[ -n "$username_in" ] &&
userpwd_in_str=":$username_in:$password_in"
- netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \
- sed 's|.*dev \(.*\).*|\1|g')
+ if is_ipv6_target; then
+ netdev=$(/sbin/ip -6 route get to ${tgt_ipaddr} | \
+ sed 's|.*dev \(.*\).*|\1|g')
+ else
+ netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \
+ sed 's|.*dev \(.*\).*|\1|g')
+ fi
srcaddr=$(echo $netdev | awk '{ print $3; exit }')
netdev=$(echo $netdev | awk '{ print $1; exit }')
@@ -582,6 +652,8 @@ install() {
inst "/bin/dd" "/bin/dd"
inst "/bin/tail" "/bin/tail"
inst "/bin/date" "/bin/date"
+ inst "/bin/getent" "/bin/getent"
+ inst "/bin/head" "/bin/head"
inst "/bin/sync" "/bin/sync"
inst "/bin/cut" "/bin/cut"
inst "/sbin/makedumpfile" "/sbin/makedumpfile"
diff --git a/kdump-lib.sh b/kdump-lib.sh
index f24f08d..b886c5d 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -146,7 +146,7 @@ check_save_path_fs()
kdump_setup_ifname() {
local _ifname
- if [[ $1 =~ eth* ]]; then
+ if [[ "$1" =~ eth* ]]; then
_ifname="kdump-$1"
else
_ifname="$1"
diff --git a/mkdumprd b/mkdumprd
index a30d9ca..d7b5752 100644
--- a/mkdumprd
+++ b/mkdumprd
@@ -79,7 +79,19 @@ add_dracut_module() {
}
add_dracut_mount() {
- add_dracut_arg "--mount" "$1"
+ local _val="$1"
+
+ if is_ipv6_target && is_nfs_dump_target; then
+ local _srcaddr=$(get_option_value nfs)
+ if `echo "$_val" | grep -q "^\[fe80"`; then
+ local _prefix="${_val%%\%*}"
+ local _netdev="${_val#*\%}"
+ _netdev=$(kdump_setup_ifname "$_netdev")
+ _val="$_prefix"%"$_netdev"
+ fi
+ fi
+
+ add_dracut_arg "--mount" "$_val"
}
add_dracut_sshkey() {
--
1.8.3.1