Address the cases where a NIC has a different name in kdump kernel
A NIC may get a different name in the kdump kernel from 1st kernel in cases like, - kernel assigned network interface names are not persistent e.g. [1] - there is an udev rule to rename the NIC in the 1st kernel but the kdump initrd may not have that rule e.g. [2] If NM tries to match a NIC with a connection profile based on NIC name i.e. connection.interface-name, it will fail the above bases. A simple solution is to ask NM to match a connection profile by MAC address. Note we don't need to do this for user-created NICs like vlan, bridge and bond. An remaining issue is passing the name of a NIC via the kdumpnic dracut command line parameter which requires passing ifname=<interface>:<MAC> to have fixed NIC name. But we can simply drop this requirement. kdumpnic is needed because kdump needs to get the IP by NIC name and use the IP to created a dumping folder named "{IP}-{DATE}". We can simply pass the IP to the kdump kernel directly via a new dracut command line parameter kdumpip instead. In addition to the benefit of simplifying the code, there are other three benefits brought by this approach, - make use of whatever network to transfer the vmcore. Because as long as we have the network to we don't care which NIC is active. - if obtained IP in the kdump kernel is different from the one in the 1st kernel. "{IP}-{DATE}" would better tell where the dumped vmcore comes from. - without passing ifname=<interface>:<MAC> to kdump initrd, the issue of there are two interfaces with the same MAC address for Azure Hyper-V NIC SR-IOV [3] is resolved automatically. [1] https://bugzilla.redhat.com/show_bug.cgi?id=1121778 [2] https://bugzilla.redhat.com/show_bug.cgi?id=810107 [3] https://bugzilla.redhat.com/show_bug.cgi?id=1962421 Signed-off-by: Coiby Xu <coxu@redhat.com> Reviewed-by: Thomas Haller <thaller@redhat.com> Reviewed-by: Philipp Rudo <prudo@redhat.com>
This commit is contained in:
parent
a65dde2d10
commit
568623e69a
@ -484,25 +484,28 @@ save_vmcore_dmesg_ssh()
|
|||||||
|
|
||||||
get_host_ip()
|
get_host_ip()
|
||||||
{
|
{
|
||||||
if is_nfs_dump_target || is_ssh_dump_target; then
|
|
||||||
kdumpnic=$(getarg kdumpnic=)
|
if ! is_nfs_dump_target && ! is_ssh_dump_target; then
|
||||||
if [ -z "$kdumpnic" ]; then
|
return 0
|
||||||
derror "failed to get kdumpnic!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if ! kdumphost=$(ip addr show dev "$kdumpnic" | grep '[ ]*inet'); then
|
|
||||||
derror "wrong kdumpnic: $kdumpnic"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
kdumphost=$(echo "$kdumphost" | head -n 1 | awk '{print $2}')
|
|
||||||
kdumphost="${kdumphost%%/*}"
|
|
||||||
if [ -z "$kdumphost" ]; then
|
|
||||||
derror "wrong kdumpnic: $kdumpnic"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
HOST_IP=$kdumphost
|
|
||||||
fi
|
fi
|
||||||
return 0
|
|
||||||
|
_kdump_remote_ip=$(getarg kdump_remote_ip=)
|
||||||
|
|
||||||
|
if [ -z "$_kdump_remote_ip" ]; then
|
||||||
|
derror "failed to get remote IP address!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_route=$(kdump_get_ip_route "$_kdump_remote_ip")
|
||||||
|
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
|
||||||
|
|
||||||
|
if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then
|
||||||
|
derror "Failed to get IP of $_netdev"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}')
|
||||||
|
_kdumpip="${_kdumpip%%/*}"
|
||||||
|
HOST_IP=$_kdumpip
|
||||||
}
|
}
|
||||||
|
|
||||||
read_kdump_confs()
|
read_kdump_confs()
|
||||||
|
@ -237,26 +237,6 @@ kdump_get_perm_addr() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0
|
|
||||||
# Because kernel assigned names are not persistent between 1st and 2nd
|
|
||||||
# kernel. We could probably end up with eth0 being eth1, eth0 being
|
|
||||||
# eth1, and naming conflict happens.
|
|
||||||
kdump_setup_ifname() {
|
|
||||||
local _ifname
|
|
||||||
|
|
||||||
# If ifname already has 'kdump-' prefix, we must be switching from
|
|
||||||
# fadump to kdump. Skip prefixing 'kdump-' in this case as adding
|
|
||||||
# another prefix may truncate the ifname. Since an ifname with
|
|
||||||
# 'kdump-' is already persistent, this should be fine.
|
|
||||||
if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
|
|
||||||
_ifname="kdump-$1"
|
|
||||||
else
|
|
||||||
_ifname="$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$_ifname"
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_nm_initrd_generator_timeouts() {
|
apply_nm_initrd_generator_timeouts() {
|
||||||
local _timeout_conf
|
local _timeout_conf
|
||||||
|
|
||||||
@ -304,6 +284,19 @@ _clone_nmconnection() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_match_nmconnection_by_mac() {
|
||||||
|
local _unique_id _dev _mac _mac_field
|
||||||
|
|
||||||
|
_unique_id=$1
|
||||||
|
_dev=$2
|
||||||
|
|
||||||
|
_mac=$(kdump_get_perm_addr "$_dev")
|
||||||
|
[[ $_mac != 'not set' ]] || return
|
||||||
|
_mac_field=$(nmcli --get-values connection.type connection show "$_unique_id").mac-address
|
||||||
|
nmcli connection modify --temporary "$_unique_id" "$_mac_field" "$_mac" &> >(ddebug)
|
||||||
|
nmcli connection modify --temporary "$_unique_id" "connection.interface-name" "" &> >(ddebug)
|
||||||
|
}
|
||||||
|
|
||||||
# Clone and modify NM connection profiles
|
# Clone and modify NM connection profiles
|
||||||
#
|
#
|
||||||
# This function makes use of "nmcli clone" to automatically convert ifcfg-*
|
# This function makes use of "nmcli clone" to automatically convert ifcfg-*
|
||||||
@ -325,6 +318,10 @@ clone_and_modify_nmconnection() {
|
|||||||
use_ipv4_or_ipv6 "$_dev" "$_uuid"
|
use_ipv4_or_ipv6 "$_dev" "$_uuid"
|
||||||
|
|
||||||
nmcli connection modify --temporary uuid "$_uuid" connection.wait-device-timeout 60000 &> >(ddebug)
|
nmcli connection modify --temporary uuid "$_uuid" connection.wait-device-timeout 60000 &> >(ddebug)
|
||||||
|
# For physical NIC i.e. non-user created NIC, ask NM to match a
|
||||||
|
# connection profile based on MAC address
|
||||||
|
_match_nmconnection_by_mac "$_uuid" "$_dev"
|
||||||
|
|
||||||
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p")
|
_cloned_nmconnection_file_path=$(nmcli --get-values UUID,FILENAME connection show | sed -n "s/^${_uuid}://p")
|
||||||
_tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path")
|
_tmp_nmconnection_file_path=$_DRACUT_KDUMP_NM_TMP_DIR/$(basename "$_nmconnection_file_path")
|
||||||
cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
|
cp "$_cloned_nmconnection_file_path" "$_tmp_nmconnection_file_path"
|
||||||
@ -528,19 +525,6 @@ kdump_setup_znet() {
|
|||||||
echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf"
|
echo "rd.znet=${NETTYPE},${SUBCHANNELS},${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS}" > "${initdir}/etc/cmdline.d/30znet.conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
kdump_get_ip_route() {
|
|
||||||
local _route
|
|
||||||
if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
|
|
||||||
derror "Bad kdump network destination: $1"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "$_route"
|
|
||||||
}
|
|
||||||
|
|
||||||
kdump_get_ip_route_field() {
|
|
||||||
echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p"
|
|
||||||
}
|
|
||||||
|
|
||||||
kdump_get_remote_ip() {
|
kdump_get_remote_ip() {
|
||||||
local _remote _remote_temp
|
local _remote _remote_temp
|
||||||
_remote=$(get_remote_host "$1")
|
_remote=$(get_remote_host "$1")
|
||||||
@ -557,14 +541,13 @@ kdump_get_remote_ip() {
|
|||||||
# Collect netifs needed by kdump
|
# Collect netifs needed by kdump
|
||||||
# $1: destination host
|
# $1: destination host
|
||||||
kdump_collect_netif_usage() {
|
kdump_collect_netif_usage() {
|
||||||
local _destaddr _srcaddr _route _netdev kdumpnic
|
local _destaddr _srcaddr _route _netdev
|
||||||
local _znet_netdev _znet_conpath
|
local _znet_netdev _znet_conpath
|
||||||
|
|
||||||
_destaddr=$(kdump_get_remote_ip "$1")
|
_destaddr=$(kdump_get_remote_ip "$1")
|
||||||
_route=$(kdump_get_ip_route "$_destaddr")
|
_route=$(kdump_get_ip_route "$_destaddr")
|
||||||
_srcaddr=$(kdump_get_ip_route_field "$_route" "src")
|
_srcaddr=$(kdump_get_ip_route_field "$_route" "src")
|
||||||
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
|
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
|
||||||
kdumpnic=$(kdump_setup_ifname "$_netdev")
|
|
||||||
|
|
||||||
_znet_netdev=$(find_online_znet_device)
|
_znet_netdev=$(find_online_znet_device)
|
||||||
if [[ -n $_znet_netdev ]]; then
|
if [[ -n $_znet_netdev ]]; then
|
||||||
@ -591,8 +574,8 @@ kdump_collect_netif_usage() {
|
|||||||
echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf"
|
echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then
|
if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpip.conf ]]; then
|
||||||
echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf"
|
echo "kdump_remote_ip=$_destaddr" > "${initdir}/etc/cmdline.d/60kdumpip.conf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if is_ipv6_address "$_srcaddr"; then
|
if is_ipv6_address "$_srcaddr"; then
|
||||||
|
@ -163,3 +163,17 @@ is_lvm2_thinp_device()
|
|||||||
|
|
||||||
[ -n "$_lvm2_thin_device" ]
|
[ -n "$_lvm2_thin_device" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kdump_get_ip_route()
|
||||||
|
{
|
||||||
|
if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then
|
||||||
|
derror "Bad kdump network destination: $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$_route"
|
||||||
|
}
|
||||||
|
|
||||||
|
kdump_get_ip_route_field()
|
||||||
|
{
|
||||||
|
echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p"
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user