Set up kdump network by directly copying NM connection profile to initrd
Resolves: bz2076416
Upstream: Fedora
Conflict: None
commit 63c3805c48
Author: Coiby Xu <coxu@redhat.com>
Date: Fri Sep 17 13:02:07 2021 +0800
Set up kdump network by directly copying NM connection profile to initrd
This patch setup kdump network by directly copying NM connection profile(s)
for different network setup including bond, bridge, vlan, and team. For
vlan network, rename phydev to parent_netif to improve code readability.
With the new approach, the related code to build up dracut cmdline
parameter such rd.route, ip and etc can be cleaned up. And there is no
need to setup dns when copying .nmconnection directly to initrd
either. Note the bootdev dracut command line parameter is only used by
dracut's 35network-legacy and network-manager doesn't use it, remove
related code as well.
Note
1. kdump_setup_vlan/bond/... are no longer called in subshells in order
to modify global variables like unique_netifs
2. The original kdump_install_net is renamed to better reflect its
current function
Signed-off-by: Coiby Xu <coxu@redhat.com>
Reviewed-by: Thomas Haller <thaller@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Coiby Xu <coxu@redhat.com>
This commit is contained in:
parent
1141e03fa1
commit
420f55c096
@ -2,6 +2,14 @@
|
||||
|
||||
_DRACUT_KDUMP_NM_TMP_DIR="/tmp/$$-DRACUT_KDUMP_NM"
|
||||
|
||||
_save_kdump_netifs() {
|
||||
unique_netifs[$1]=1
|
||||
}
|
||||
|
||||
_get_kdump_netifs() {
|
||||
echo -n "${!unique_netifs[@]}"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$_DRACUT_KDUMP_NM_TMP_DIR"
|
||||
}
|
||||
@ -103,39 +111,6 @@ source_ifcfg_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
kdump_setup_dns() {
|
||||
local _netdev="$1"
|
||||
local _conpath="$2"
|
||||
local _nameserver _dns _tmp array
|
||||
local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
|
||||
|
||||
_tmp=$(get_nmcli_field_by_conpath "IP4.DNS" "$_conpath")
|
||||
# shellcheck disable=SC2206
|
||||
array=(${_tmp//|/ })
|
||||
if [[ ${array[*]} ]]; then
|
||||
for _dns in "${array[@]}"; do
|
||||
echo "nameserver=$_dns" >> "$_dnsfile"
|
||||
done
|
||||
else
|
||||
dwarning "Failed to get DNS info via nmcli output. Now try sourcing ifcfg script"
|
||||
source_ifcfg_file "$_netdev"
|
||||
[[ -n $DNS1 ]] && echo "nameserver=$DNS1" > "$_dnsfile"
|
||||
[[ -n $DNS2 ]] && echo "nameserver=$DNS2" >> "$_dnsfile"
|
||||
fi
|
||||
|
||||
while read -r content; do
|
||||
_nameserver=$(echo "$content" | grep ^nameserver)
|
||||
[[ -z $_nameserver ]] && continue
|
||||
|
||||
_dns=$(echo "$_nameserver" | awk '{print $2}')
|
||||
[[ -z $_dns ]] && continue
|
||||
|
||||
if [[ ! -f $_dnsfile ]] || ! grep -q "$_dns" "$_dnsfile"; then
|
||||
echo "nameserver=$_dns" >> "$_dnsfile"
|
||||
fi
|
||||
done < "/etc/resolv.conf"
|
||||
}
|
||||
|
||||
# $1: repeat times
|
||||
# $2: string to be repeated
|
||||
# $3: separator
|
||||
@ -246,89 +221,6 @@ cal_netmask_by_prefix() {
|
||||
fi
|
||||
}
|
||||
|
||||
#$1: netdev name
|
||||
#$2: srcaddr
|
||||
#if it use static ip echo it, or echo null
|
||||
kdump_static_ip() {
|
||||
local _netdev="$1" _srcaddr="$2" kdumpnic="$3" _ipv6_flag
|
||||
local _netmask _gateway _ipaddr _target _nexthop _prefix
|
||||
|
||||
_ipaddr=$(ip addr show dev "$_netdev" permanent | awk "/ $_srcaddr\/.* /{print \$2}")
|
||||
|
||||
if is_ipv6_address "$_srcaddr"; then
|
||||
_ipv6_flag="-6"
|
||||
fi
|
||||
|
||||
if [[ -n $_ipaddr ]]; then
|
||||
_gateway=$(ip $_ipv6_flag route list dev "$_netdev" \
|
||||
| awk '/^default /{print $3}' | head -n 1)
|
||||
|
||||
if [[ "x" != "x"$_ipv6_flag ]]; then
|
||||
# _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/"
|
||||
_netmask=${_ipaddr#*\/}
|
||||
_srcaddr="[$_srcaddr]"
|
||||
_gateway="[$_gateway]"
|
||||
else
|
||||
_prefix=$(cut -d'/' -f2 <<< "$_ipaddr")
|
||||
if ! _netmask=$(cal_netmask_by_prefix "$_prefix" "$_ipv6_flag"); then
|
||||
derror "Failed to calculate netmask for $_ipaddr"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
|
||||
fi
|
||||
|
||||
/sbin/ip $_ipv6_flag route show | grep -v default \
|
||||
| grep ".*via.* $_netdev " | grep -v "^[[:space:]]*nexthop" \
|
||||
| while read -r _route; do
|
||||
_target=$(echo "$_route" | awk '{print $1}')
|
||||
_nexthop=$(echo "$_route" | awk '{print $3}')
|
||||
if [[ "x" != "x"$_ipv6_flag ]]; then
|
||||
_target="[$_target]"
|
||||
_nexthop="[$_nexthop]"
|
||||
fi
|
||||
echo "rd.route=$_target:$_nexthop:$kdumpnic"
|
||||
done >> "${initdir}/etc/cmdline.d/45route-static.conf"
|
||||
|
||||
kdump_handle_mulitpath_route "$_netdev" "$_srcaddr" "$kdumpnic"
|
||||
}
|
||||
|
||||
kdump_handle_mulitpath_route() {
|
||||
local _netdev="$1" _srcaddr="$2" kdumpnic="$3" _ipv6_flag
|
||||
local _target _nexthop _route _weight _max_weight _rule
|
||||
|
||||
if is_ipv6_address "$_srcaddr"; then
|
||||
_ipv6_flag="-6"
|
||||
fi
|
||||
|
||||
while IFS="" read -r _route; do
|
||||
if [[ $_route =~ [[:space:]]+nexthop ]]; then
|
||||
_route=${_route##[[:space:]]}
|
||||
# Parse multipath route, using previous _target
|
||||
[[ $_target == 'default' ]] && continue
|
||||
[[ $_route =~ .*via.*\ $_netdev ]] || continue
|
||||
|
||||
_weight=$(echo "$_route" | cut -d ' ' -f7)
|
||||
if [[ $_weight -gt $_max_weight ]]; then
|
||||
_nexthop=$(echo "$_route" | cut -d ' ' -f3)
|
||||
_max_weight=$_weight
|
||||
if [[ "x" != "x"$_ipv6_flag ]]; then
|
||||
_rule="rd.route=[$_target]:[$_nexthop]:$kdumpnic"
|
||||
else
|
||||
_rule="rd.route=$_target:$_nexthop:$kdumpnic"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
[[ -n $_rule ]] && echo "$_rule"
|
||||
_target=$(echo "$_route" | cut -d ' ' -f1)
|
||||
_rule="" _max_weight=0 _weight=0
|
||||
fi
|
||||
done >> "${initdir}/etc/cmdline.d/45route-static.conf" \
|
||||
<<< "$(/sbin/ip $_ipv6_flag route show)"
|
||||
|
||||
[[ -n $_rule ]] && echo "$_rule" >> "${initdir}/etc/cmdline.d/45route-static.conf"
|
||||
}
|
||||
|
||||
kdump_get_mac_addr() {
|
||||
cat "/sys/class/net/$1/address"
|
||||
}
|
||||
@ -474,102 +366,55 @@ kdump_install_nmconnections() {
|
||||
|
||||
kdump_setup_bridge() {
|
||||
local _netdev=$1
|
||||
local _brif _dev _mac _kdumpdev
|
||||
local _dev
|
||||
for _dev in "/sys/class/net/$_netdev/brif/"*; do
|
||||
[[ -e $_dev ]] || continue
|
||||
_dev=${_dev##*/}
|
||||
_kdumpdev=$_dev
|
||||
if kdump_is_bond "$_dev"; then
|
||||
(kdump_setup_bond "$_dev" "$(get_nmcli_connection_apath_by_ifname "$_dev")") || exit 1
|
||||
kdump_setup_bond "$_dev" || return 1
|
||||
elif kdump_is_team "$_dev"; then
|
||||
kdump_setup_team "$_dev"
|
||||
elif kdump_is_vlan "$_dev"; then
|
||||
kdump_setup_vlan "$_dev"
|
||||
else
|
||||
_mac=$(kdump_get_mac_addr "$_dev")
|
||||
_kdumpdev=$(kdump_setup_ifname "$_dev")
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/41bridge.conf"
|
||||
fi
|
||||
_brif+="$_kdumpdev,"
|
||||
_save_kdump_netifs "$_dev"
|
||||
done
|
||||
echo " bridge=$_netdev:${_brif%,}" >> "${initdir}/etc/cmdline.d/41bridge.conf"
|
||||
}
|
||||
|
||||
# drauct takes bond=<bondname>[:<bondslaves>:[:<options>]] syntax to parse
|
||||
# bond. For example:
|
||||
# bond=bond0:eth0,eth1:mode=balance-rr
|
||||
kdump_setup_bond() {
|
||||
local _netdev="$1"
|
||||
local _conpath="$2"
|
||||
local _dev _mac _slaves _kdumpdev _bondoptions
|
||||
for _dev in $(cat "/sys/class/net/$_netdev/bonding/slaves"); do
|
||||
_mac=$(kdump_get_perm_addr "$_dev")
|
||||
_kdumpdev=$(kdump_setup_ifname "$_dev")
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/42bond.conf"
|
||||
_slaves+="$_kdumpdev,"
|
||||
local _dev
|
||||
|
||||
for _dev in $(< "/sys/class/net/$_netdev/bonding/slaves"); do
|
||||
_save_kdump_netifs "$_dev"
|
||||
done
|
||||
echo -n " bond=$_netdev:${_slaves%,}" >> "${initdir}/etc/cmdline.d/42bond.conf"
|
||||
|
||||
_bondoptions=$(get_nmcli_field_by_conpath "bond.options" "$_conpath")
|
||||
|
||||
if [[ -z $_bondoptions ]]; then
|
||||
dwarning "Failed to get bond configuration via nmlci output. Now try sourcing ifcfg script."
|
||||
source_ifcfg_file "$_netdev"
|
||||
_bondoptions="$(echo "$BONDING_OPTS" | xargs echo | tr " " ",")"
|
||||
fi
|
||||
|
||||
if [[ -z $_bondoptions ]]; then
|
||||
derror "Get empty bond options"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ":$_bondoptions" >> "${initdir}/etc/cmdline.d/42bond.conf"
|
||||
}
|
||||
|
||||
kdump_setup_team() {
|
||||
local _netdev=$1
|
||||
local _dev _mac _slaves _kdumpdev
|
||||
local _dev
|
||||
for _dev in $(teamnl "$_netdev" ports | awk -F':' '{print $2}'); do
|
||||
_mac=$(kdump_get_perm_addr "$_dev")
|
||||
_kdumpdev=$(kdump_setup_ifname "$_dev")
|
||||
echo -n " ifname=$_kdumpdev:$_mac" >> "${initdir}/etc/cmdline.d/44team.conf"
|
||||
_slaves+="$_kdumpdev,"
|
||||
_save_kdump_netifs "$_dev"
|
||||
done
|
||||
echo " team=$_netdev:${_slaves%,}" >> "${initdir}/etc/cmdline.d/44team.conf"
|
||||
#Buggy version teamdctl outputs to stderr!
|
||||
#Try to use the latest version of teamd.
|
||||
if ! teamdctl "$_netdev" config dump > "${initdir}/tmp/$$-$_netdev.conf"; then
|
||||
derror "teamdctl failed."
|
||||
exit 1
|
||||
fi
|
||||
inst_dir /etc/teamd
|
||||
inst_simple "${initdir}/tmp/$$-$_netdev.conf" "/etc/teamd/$_netdev.conf"
|
||||
rm -f "${initdir}/tmp/$$-$_netdev.conf"
|
||||
}
|
||||
|
||||
kdump_setup_vlan() {
|
||||
local _netdev=$1
|
||||
local _phydev
|
||||
local _netmac
|
||||
local _kdumpdev
|
||||
local _parent_netif
|
||||
|
||||
_phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
|
||||
_netmac="$(kdump_get_mac_addr "$_phydev")"
|
||||
_parent_netif="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
|
||||
|
||||
#Just support vlan over bond and team
|
||||
if kdump_is_bridge "$_phydev"; then
|
||||
if kdump_is_bridge "$_parent_netif"; then
|
||||
derror "Vlan over bridge is not supported!"
|
||||
exit 1
|
||||
elif kdump_is_bond "$_phydev"; then
|
||||
(kdump_setup_bond "$_phydev" "$(get_nmcli_connection_apath_by_ifname "$_phydev")") || exit 1
|
||||
echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf"
|
||||
elif kdump_is_team "$_phydev"; then
|
||||
(kdump_setup_team "$_phydev") || exit 1
|
||||
echo " vlan=$(kdump_setup_ifname "$_netdev"):$_phydev" > "${initdir}/etc/cmdline.d/43vlan.conf"
|
||||
else
|
||||
_kdumpdev="$(kdump_setup_ifname "$_phydev")"
|
||||
echo " vlan=$(kdump_setup_ifname "$_netdev"):$_kdumpdev ifname=$_kdumpdev:$_netmac" > "${initdir}/etc/cmdline.d/43vlan.conf"
|
||||
elif kdump_is_bond "$_parent_netif"; then
|
||||
kdump_setup_bond "$_parent_netif" || return 1
|
||||
elif kdump_is_team "$_parent_netif"; then
|
||||
kdump_setup_team "$_parent_netif" || return 1
|
||||
fi
|
||||
|
||||
_save_kdump_netifs "$_parent_netif"
|
||||
}
|
||||
|
||||
# find online znet device
|
||||
@ -656,20 +501,16 @@ kdump_get_remote_ip() {
|
||||
echo "$_remote"
|
||||
}
|
||||
|
||||
# Setup dracut to bring up network interface that enable
|
||||
# initramfs accessing giving destination
|
||||
# Collect netifs needed by kdump
|
||||
# $1: destination host
|
||||
kdump_install_net() {
|
||||
local _destaddr _srcaddr _route _netdev _conpath kdumpnic
|
||||
local _static _proto _ip_conf _ip_opts _ifname_opts
|
||||
kdump_collect_netif_usage() {
|
||||
local _destaddr _srcaddr _route _netdev kdumpnic
|
||||
local _znet_netdev _znet_conpath
|
||||
|
||||
_destaddr=$(kdump_get_remote_ip "$1")
|
||||
_route=$(kdump_get_ip_route "$_destaddr")
|
||||
_srcaddr=$(kdump_get_ip_route_field "$_route" "src")
|
||||
_netdev=$(kdump_get_ip_route_field "$_route" "dev")
|
||||
_conpath=$(get_nmcli_connection_apath_by_ifname "$_netdev")
|
||||
_netmac=$(kdump_get_mac_addr "$_netdev")
|
||||
kdumpnic=$(kdump_setup_ifname "$_netdev")
|
||||
|
||||
_znet_netdev=$(find_online_znet_device)
|
||||
@ -681,58 +522,42 @@ kdump_install_net() {
|
||||
fi
|
||||
fi
|
||||
|
||||
_static=$(kdump_static_ip "$_netdev" "$_srcaddr" "$kdumpnic")
|
||||
if [[ -n $_static ]]; then
|
||||
_proto=none
|
||||
elif is_ipv6_address "$_srcaddr"; then
|
||||
_proto=auto6
|
||||
else
|
||||
_proto=dhcp
|
||||
fi
|
||||
|
||||
_ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
|
||||
_ip_opts=" ip=${_static}$kdumpnic:${_proto}"
|
||||
|
||||
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same.
|
||||
# so we have to avoid adding duplicates
|
||||
# We should also check /proc/cmdline for existing ip=xx arg.
|
||||
# For example, iscsi boot will specify ip=xxx arg in cmdline.
|
||||
if [[ ! -f $_ip_conf ]] || ! grep -q "$_ip_opts" "$_ip_conf" \
|
||||
&& ! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
|
||||
echo "$_ip_opts" >> "$_ip_conf"
|
||||
fi
|
||||
|
||||
if kdump_is_bridge "$_netdev"; then
|
||||
kdump_setup_bridge "$_netdev"
|
||||
elif kdump_is_bond "$_netdev"; then
|
||||
(kdump_setup_bond "$_netdev" "$_conpath") || exit 1
|
||||
kdump_setup_bond "$_netdev" || return 1
|
||||
elif kdump_is_team "$_netdev"; then
|
||||
kdump_setup_team "$_netdev"
|
||||
elif kdump_is_vlan "$_netdev"; then
|
||||
kdump_setup_vlan "$_netdev"
|
||||
else
|
||||
_ifname_opts=" ifname=$kdumpnic:$_netmac"
|
||||
echo "$_ifname_opts" >> "$_ip_conf"
|
||||
fi
|
||||
|
||||
kdump_setup_dns "$_netdev" "$_conpath"
|
||||
_save_kdump_netifs "$_netdev"
|
||||
|
||||
if [[ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]]; then
|
||||
# network-manager module needs this parameter
|
||||
echo "rd.neednet" >> "${initdir}/etc/cmdline.d/50neednet.conf"
|
||||
fi
|
||||
|
||||
# Save netdev used for kdump as cmdline
|
||||
# Whoever calling kdump_install_net() is setting up the default gateway,
|
||||
# ie. bootdev/kdumpnic. So don't override the setting if calling
|
||||
# kdump_install_net() for another time. For example, after setting eth0 as
|
||||
# the default gate way for network dump, eth1 in the fence kdump path will
|
||||
# call kdump_install_net again and we don't want eth1 to be the default
|
||||
# gateway.
|
||||
if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]] \
|
||||
&& [[ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]]; then
|
||||
if [[ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ]]; then
|
||||
echo "kdumpnic=$kdumpnic" > "${initdir}/etc/cmdline.d/60kdumpnic.conf"
|
||||
echo "bootdev=$kdumpnic" > "${initdir}/etc/cmdline.d/70bootdev.conf"
|
||||
fi
|
||||
|
||||
if is_ipv6_address "$_srcaddr"; then
|
||||
ipv6_usage[$_netdev]=1
|
||||
else
|
||||
ipv4_usage[$_netdev]=1
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup dracut to bring up network interface that enable
|
||||
# initramfs accessing giving destination
|
||||
kdump_install_net() {
|
||||
local _netifs
|
||||
|
||||
_netifs=$(_get_kdump_netifs)
|
||||
if [[ -n "$_netifs" ]]; then
|
||||
kdump_install_nmconnections
|
||||
apply_nm_initrd_generator_timeouts
|
||||
fi
|
||||
}
|
||||
|
||||
@ -771,7 +596,7 @@ default_dump_target_install_conf() {
|
||||
|
||||
_fstype=$(get_fs_type_from_target "$_target")
|
||||
if is_fs_type_nfs "$_fstype"; then
|
||||
kdump_install_net "$_target"
|
||||
kdump_collect_netif_usage "$_target"
|
||||
_fstype="nfs"
|
||||
else
|
||||
_target=$(kdump_get_persistent_dev "$_target")
|
||||
@ -807,11 +632,11 @@ kdump_install_conf() {
|
||||
sed -i -e "s#^${_opt}[[:space:]]\+$_val#$_opt $_pdev#" "${initdir}/tmp/$$-kdump.conf"
|
||||
;;
|
||||
ssh | nfs)
|
||||
kdump_install_net "$_val"
|
||||
kdump_collect_netif_usage "$_val"
|
||||
;;
|
||||
dracut_args)
|
||||
if [[ $(get_dracut_args_fstype "$_val") == nfs* ]]; then
|
||||
kdump_install_net "$(get_dracut_args_target "$_val")"
|
||||
kdump_collect_netif_usage "$(get_dracut_args_target "$_val")"
|
||||
fi
|
||||
;;
|
||||
kdump_pre | kdump_post | extra_bins)
|
||||
@ -933,7 +758,7 @@ kdump_setup_iscsi_device() {
|
||||
|
||||
[[ -n $username_in ]] && userpwd_in_str=":$username_in:$password_in"
|
||||
|
||||
kdump_install_net "$tgt_ipaddr"
|
||||
kdump_collect_netif_usage "$tgt_ipaddr"
|
||||
|
||||
# prepare netroot= command line
|
||||
# FIXME: Do we need to parse and set other parameters like protocol, port
|
||||
@ -1097,7 +922,7 @@ kdump_configure_fence_kdump() {
|
||||
|
||||
# setup network for each node
|
||||
for node in ${nodes}; do
|
||||
kdump_install_net "$node"
|
||||
kdump_collect_netif_usage "$node"
|
||||
done
|
||||
|
||||
dracut_install /etc/hosts
|
||||
@ -1206,6 +1031,8 @@ install() {
|
||||
inst "ip"
|
||||
fi
|
||||
|
||||
kdump_install_net
|
||||
|
||||
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
|
||||
# safely replace "reserved_memory=XXXX"(default value is 8192) with
|
||||
# "reserved_memory=1024" to lower memory pressure under kdump. We do
|
||||
|
Loading…
Reference in New Issue
Block a user