network fixes for link waiting
v3 cover network fixes for link waiting
Hi,
This is the v2 patch set for some network cleanup and fixes:
01-network-move-wait-for-if-function-to-net-lib.patch 02-network-add-function-linkup.patch 03-network-use-linkup-function.patch 04-network-wait-for-link-ready-before-use.patch 05-network-get-ifaces-for-udev-rule-use.patch 06-network-wait-interface-up-at-early-stage.patch
Tested kdump with a nic which delay abouth 60s while initializing. V2 patch updated 05 and 06 to fix some issues with bonding device.
v2->v3:
refresh based on latest mater branch
patch 3/6: fix merge conflict
patch 5/6: fix a typo: s/-n/-z
--
Thanks
Dave
PATCH v3 1/6 Move wait for if functions to net lib
net-lib.sh are created for net related functions, move the wait_for_if* to net-lib.sh naturally.
--- modules.d/40network/dhclient-script.sh | 1 + modules.d/40network/net-lib.sh | 23 +++++++++++++++++++++++ modules.d/95fcoe/fcoe-up.sh | 1 + modules.d/99base/dracut-lib.sh | 23 ----------------------- 4 files changed, 25 insertions(+), 23 deletions(-)
modules.d/99base/dracut-lib.sh +0 -23
@@ -481,29 +481,6 @@ else } fi -wait_for_if_up() { - local cnt=0 - local li - while [ $cnt -lt 200 ]; do - li=$(ip -o link show up dev $1) - [ -n "$li" ] && return 0 - sleep 0.1 - cnt=$(($cnt+1)) - done - return 1 -} - -wait_for_route_ok() { - local cnt=0 - while [ $cnt -lt 200 ]; do - li=$(ip route show) - [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0 - sleep 0.1 - cnt=$(($cnt+1)) - done - return 1 -} - # root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>] # root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>] nfsroot_to_var() {
modules.d/40network/net-lib.sh +23 -0
@@ -322,3 +322,26 @@ parse_ifname_opts() { esac } + +wait_for_if_up() { + local cnt=0 + local li + while [ $cnt -lt 200 ]; do + li=$(ip -o link show up dev $1) + [ -n "$li" ] && return 0 + sleep 0.1 + cnt=$(($cnt+1)) + done + return 1 +} + +wait_for_route_ok() { + local cnt=0 + while [ $cnt -lt 200 ]; do + li=$(ip route show) + [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0 + sleep 0.1 + cnt=$(($cnt+1)) + done + return 1 +}
modules.d/40network/dhclient-script.sh +1 -0
@@ -51,6 +51,7 @@ PATH=/usr/sbin:/usr/bin:/sbin:/bin export PS4="dhclient.$interface.$$ + " exec >>/run/initramfs/loginit.pipe 2>>/run/initramfs/loginit.pipe type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh +type ip_to_var >/dev/null 2>&1 || . /lib/net-lib.sh # We already need a set netif here netif=$interface
modules.d/95fcoe/fcoe-up.sh +1 -0
@@ -16,6 +16,7 @@ PATH=/usr/sbin:/usr/bin:/sbin:/bin export PS4="fcoe-up.$1.$$ + " exec >>/run/initramfs/loginit.pipe 2>>/run/initramfs/loginit.pipe type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh +type ip_to_var >/dev/null 2>&1 || . /lib/net-lib.sh netif=$1 dcb=$2
PATCH v3 2/6 Add function linkup
In reply to [email protected]set link up usually include two steps, ip link set <dev> up and wait_for_if_up <dev>. Now do these two steps in one function linkup. Later patch will add other code into it.
--- modules.d/40network/net-lib.sh | 5 +++++ 1 file changed, 5 insertions(+)
modules.d/40network/net-lib.sh +5 -0
@@ -345,3 +345,8 @@ wait_for_route_ok() { done return 1 } + +linkup() { + ip link set $1 up 2>/dev/null && wait_for_if_up $1 2>/dev/null +} +
PATCH v3 3/6 Change to use linkup function in network scripts
In reply to [email protected]Update ifup.sh and fcoe-up.sh, use linkup function instead of directly call ip command.
--- modules.d/40network/ifup.sh | 17 ++++++----------- modules.d/95fcoe/fcoe-up.sh | 3 +-- 2 files changed, 7 insertions(+), 13 deletions(-)
modules.d/40network/ifup.sh +6 -11
@@ -84,8 +84,7 @@ do_ipv6auto() { echo 0 > /proc/sys/net/ipv6/conf/$netif/forwarding echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_ra echo 1 > /proc/sys/net/ipv6/conf/$netif/accept_redirects - ip link set $netif up - wait_for_if_up $netif + linkup $netif [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname
@@ -96,8 +95,7 @@ do_ipv6auto() { do_static() { strstr $ip '*:*:*' && load_ipv6 - ip link set dev $netif up - wait_for_if_up $netif + linkup $netif [ -n "$macaddr" ] && ip link set address $macaddr dev $netif [ -n "$mtu" ] && ip link set mtu $mtu dev $netif if strstr $ip '*:*:*'; then
@@ -147,13 +145,12 @@ if [ -e /tmp/bond.info ]; then fi done - ip link set $netif up + linkup $netif for slave in $bondslaves ; do ip link set $slave down echo "+$slave" > /sys/class/net/$bondname/bonding/slaves - ip link set $slave up - wait_for_if_up $slave + linkup $slave done # add the bits to setup the needed post enslavement parameters
@@ -180,9 +177,8 @@ if [ -e /tmp/bridge.info ]; then if [ "$ethname" = "$bondname" ] ; then DO_BOND_SETUP=yes ifup $bondname -m else - ip link set $ethname up + linkup $ethname fi - wait_for_if_up $ethname brctl addif $bridgename $ethname done fi
@@ -204,9 +200,8 @@ if [ "$netif" = "$vlanname" ] && [ ! -e if [ "$phydevice" = "$bondname" ] ; then DO_BOND_SETUP=yes ifup $phydevice -m else - ip link set "$phydevice" up + linkup "$phydevice" fi - wait_for_if_up "$phydevice" ip link add dev "$vlanname" link "$phydevice" type vlan id "$(get_vid $vlanname; echo $?)" fi
modules.d/95fcoe/fcoe-up.sh +1 -2
@@ -21,8 +21,7 @@ type ip_to_var >/dev/null 2>&1 || . /lib netif=$1 dcb=$2 -ip link set "$netif" up -wait_for_if_up "$netif" +linkup "$netif" netdriver=$(readlink -f /sys/class/net/$netif/device/driver) netdriver=${netdriver##*/}
PATCH v3 4/6 Wait for link ready before use the interface
In reply to [email protected]Some network driver will take long time to initialize. We have an example in a HP machine which take about one minute for this. The callback such as "ip link set <dev> up" will fail, afterwards setup for network will also fail.
Fix this by add a new function wait_for_if_link, wait the link ready before use it.
--- modules.d/40network/net-lib.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
modules.d/40network/net-lib.sh +16 -1
@@ -323,6 +323,19 @@ parse_ifname_opts() { } +# some network driver need long time to initialize, wait before it's ready. +wait_for_if_link() { + local cnt=0 + local li + while [ $cnt -lt 600 ]; do + li=$(ip -o link show dev $1 2>/dev/null) + [ -n "$li" ] && return 0 + sleep 0.1 + cnt=$(($cnt+1)) + done + return 1 +} + wait_for_if_up() { local cnt=0 local li
@@ -347,6 +360,8 @@ wait_for_route_ok() { } linkup() { - ip link set $1 up 2>/dev/null && wait_for_if_up $1 2>/dev/null + wait_for_if_link $1 2>/dev/null\ + && ip link set $1 up 2>/dev/null\ + && wait_for_if_up $1 2>/dev/null }
PATCH v3 5/6 Get ifaces for udev rule use
In reply to [email protected]In case BOOTIF is not set and IFACES are not set in bonding/vlan/bridge code, net-genrule.sh will fall to bring up all net interfaces.
Here add a failsafe option to read IFACES from /tmp/net.ifaces
[v1->v2]: move IFACES reading from net.ifaces after bonding/vlan/bridge info code chunks.
[v2->v3]: [ -n "$IFACES" ] should be [ -z "$IFACES" ]
--- modules.d/40network/net-genrules.sh | 4 ++++ 1 file changed, 4 insertions(+)
modules.d/40network/net-genrules.sh +4 -0
@@ -39,6 +39,10 @@ fi IFACES+=" $phydevice" fi + if [ -z "$IFACES" ]; then + [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces + fi + ifup='/sbin/ifup $env{INTERFACE}' [ -z "$netroot" ] && ifup="$ifup -m"
PATCH v3 6/6 Wait for interface up at the early stage
In reply to [email protected]In case long delay of network driver initqueue will exit before net dev is ready. We have no chance to setup it then.
For dhcp, when we finish the setup there will be a setup_net_<dev>.ok. Doing same for static ip case. Also add a check to initqueue when we generate udev rules to ensure it's early enough.
[v1->v2]: only wait for bootdev or it's possible to cause boot fail for waiting for non-bootdev. For example bond0->eth0, set bond0 as bootdev and dhcp, we only need to wait bond0 setup ok.
--- modules.d/40network/ifup.sh | 1 + modules.d/40network/net-genrules.sh | 9 +++++++++ 2 files changed, 10 insertions(+)
modules.d/40network/net-genrules.sh +9 -0
@@ -43,6 +43,10 @@ fi [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces fi + if [ -e /tmp/net.bootdev ]; then + bootdev=$(cat /tmp/net.bootdev) + fi + ifup='/sbin/ifup $env{INTERFACE}' [ -z "$netroot" ] && ifup="$ifup -m"
@@ -51,14 +55,19 @@ fi if [ -n "$BOOTIF" ] ; then BOOTIF=$(fix_bootif "$BOOTIF") printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="%s"\n' "$BOOTIF" "/sbin/initqueue --onetime $ifup" + echo "[ -f /tmp/setup_net_${BOOTIF}.ok ]" >$hookdir/initqueue/finished/wait-${BOOTIF}.sh # If we have to handle multiple interfaces, handle only them. elif [ -n "$IFACES" ] ; then for iface in $IFACES ; do printf 'SUBSYSTEM=="net", ENV{INTERFACE}=="%s", RUN+="%s"\n' "$iface" "/sbin/initqueue --onetime $ifup" + if [ "$bootdev" = "$iface" ]; then + echo "[ -f /tmp/setup_net_${iface}.ok ]" >$hookdir/initqueue/finished/wait-$iface.sh + fi done # Default: We don't know the interface to use, handle all + # Fixme: waiting for the interface as well. else # if you change the name of "91-default-net.rules", also change modules.d/80cms/cmssetup.sh printf 'SUBSYSTEM=="net", RUN+="%s"\n' "/sbin/initqueue --onetime $ifup" > /etc/udev/rules.d/91-default-net.rules
modules.d/40network/ifup.sh +1 -0
@@ -109,6 +109,7 @@ do_static() { [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > /tmp/net.$netif.hostname + > /tmp/setup_net_${netif}.ok return 0 }