Skip to contentSkip to conversation

network fixes for link waiting

PATCH Superseded [email protected] 1 participant 7 messages Nov 30, 2012

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 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.

--
Thanks a lot
Dave

#1 lore raw

PATCH v2 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
@@ -315,3 +315,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
#2 lore raw

PATCH v2 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
@@ -338,3 +338,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
+}
+
#3 lore raw

PATCH v2 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 $netif up
-    wait_for_if_up $netif
+    linkup $netif
     [ -n "$macaddr" ] && ip link set address $macaddr
     [ -n "$mtu" ] && ip link set mtu $mtu
     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##*/}
#4 lore raw

PATCH v2 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
@@ -316,6 +316,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
@@ -340,6 +353,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
 }
 
#5 lore raw

PATCH v2 5/6 Get failsafe 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.

---
 modules.d/40network/net-genrules.sh |    2 ++
 1 file changed, 2 insertions(+)
modules.d/40network/net-genrules.sh +4 -0
@@ -39,6 +39,10 @@ fi
         IFACES+=" $phydevice"
     fi
 
+    if [ -n "$IFACES" ]; then
+        [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces
+    fi
+
     ifup='/sbin/ifup $env{INTERFACE}'
     [ -z "$netroot" ] && ifup="$ifup -m"
 
#6 lore raw

PATCH v2 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
         printf 'SUBSYSTEM=="net", RUN+="%s"\n' "/sbin/initqueue --onetime $ifup" > /etc/udev/rules.d/91-default-net.rules
     fi
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
 }