From: Seewer Philippe <philippe.seewer-omB+W0Dpw2o@public.gmane.org>
To: David Dillow <dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
Cc: initramfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [RFC ONLY 5/5] PROOF-OF-CONCEPT: wait for spanning tree timeout via arping
Date: Tue, 7 Jul 2009 10:08:55 +0200 [thread overview]
Message-ID: <4A530297.1020906@bfh.ch> (raw)
In-Reply-To: <8cf3d034e4611fbe661d4585fbfd1a03a6fd094b.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
David Dillow wrote:
> When operating on a switch running a spanning tree, it can take up to
> 100 seconds for our port to start forwarding traffic after comming up.
> Normally, this can be eaten by DHCP's request for an IP, but if we have
> a static configuration or need to down the interface to change the MTU, we
> will have to eat the timeout again.
>
> Most of the network root protocols will timeout while waiting for traffic
> to flow again in this case, so we use ARP pings to determine when the
> link is available prior to trying the mount/disk login.
For the record: I've had a (much simpler, but not as generic as this
one) arping solution active in our production environment for a week and
the few cases that actually still use slow STP are solved.
So yes, this works.
(Some comments below)
> ---
> modules.d/40network/dhclient-script | 11 ++++--
> modules.d/40network/ifup | 8 +++-
> modules.d/40network/install | 2 +-
> modules.d/40network/netroot | 67 +++++++++++++++++++++++++++++------
> modules.d/95iscsi/iscsiroot | 28 +++++++++-----
> modules.d/95nbd/nbdroot | 12 +++++--
> modules.d/95nfs/nfsroot | 9 +++--
> 7 files changed, 104 insertions(+), 33 deletions(-)
>
> diff --git a/modules.d/40network/dhclient-script b/modules.d/40network/dhclient-script
> index 5b36a40..e440df9 100755
> --- a/modules.d/40network/dhclient-script
> +++ b/modules.d/40network/dhclient-script
> @@ -13,15 +13,20 @@ setup_interface() {
>
> [ -f /tmp/net.$netif.override ] && . /tmp/net.$netif.override
>
> + echo mynet=$ip/$mask > /tmp/net.$netif.up
> +
Please don't do this. $ip/$mask is in .override so we don't need
more variables.
> if [ -n "$mtu" ] ; then
> echo ip link set $netif down
> echo ip link set $netif mtu $mtu
> echo ip link set $netif up
> - fi > /tmp/net.$netif.up
> + fi >> /tmp/net.$netif.up
>
> - echo ip addr add $ip${mask:+/$mask} ${bcast:+broadcast $bcast} dev $netif >> /tmp/net.$netif.up
> + echo ip addr add $ip/$mask ${bcast:+broadcast $bcast} dev $netif >> /tmp/net.$netif.up
>
> - [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
> + if [ -n "$gw" ]; then
> + echo gw=$gw > /tmp/net.$netif.gw
> + echo ip route add default via $gw dev $netif >> /tmp/net.$netif.gw
> + fi
Same here, this information is in .dhcpopts There's no need to store
them twice
>
> [ -n "${search}${domain}" ] && echo search $search $domain > /tmp/net.$netif.resolv.conf
> if [ -n "$namesrv" ] ; then
> diff --git a/modules.d/40network/ifup b/modules.d/40network/ifup
> index 89017bb..404d6d8 100755
> --- a/modules.d/40network/ifup
> +++ b/modules.d/40network/ifup
> @@ -32,13 +32,17 @@ do_dhcp() {
>
> # Handle static ip configuration
> do_static() {
> -{
> + {
> + echo mynet=$ip/$mask
And again...
> echo ip link set $netif up
> echo ip addr flush dev $netif
> echo ip addr add $ip/$mask dev $netif
> } > /tmp/net.$netif.up
>
> - [ -n "$gw" ] && echo ip route add default via $gw dev $netif > /tmp/net.$netif.gw
> + if [ -n "$gw" ]; then
> + echo gw=$gw > /tmp/net.$netif.gw
> + echo ip route add default via $gw dev $netif >> /tmp/net.$netif.gw
> + fi
> [ -n "$hostname" ] && echo hostname $hostname > /tmp/net.$netif.hostname
>
> echo online > /sys/class/net/$netif/uevent
> diff --git a/modules.d/40network/install b/modules.d/40network/install
> index 0b76cbd..20e8963 100755
> --- a/modules.d/40network/install
> +++ b/modules.d/40network/install
> @@ -1,5 +1,5 @@
> #!/bin/bash
> -dracut_install ip dhclient hostname
> +dracut_install ip dhclient hostname arping date
> # Include wired net drivers, excluding wireless
> for modname in $(find "/lib/modules/$kernel/kernel/drivers" -name '*.ko'); do
> if nm -uPA $modname | grep -q eth_type_trans; then
> diff --git a/modules.d/40network/netroot b/modules.d/40network/netroot
> index 2cf51fa..58bbd2e 100755
> --- a/modules.d/40network/netroot
> +++ b/modules.d/40network/netroot
> @@ -1,5 +1,29 @@
> #!/bin/sh
>
> +apply_mask() {
> + local ip=$1
> + local mask=$2
> + local out i
> +
> + for i in 1 2 3 4; do
> + out=$out.$(( ${ip%%.*} & ${mask%%.*} ))
> + ip=${ip#*.}
> + mask=${mask#*.}
> + done
> + echo ${out#.}
> +}
> +
> +is_local() {
> + local server=$1
> + local mynet=$2
> + local mask net
> +
> + mask=${mynet#*/}
> + mynet=$(apply_mask ${mynet%/*} $mask)
> + net=$(apply_mask $server $mask)
> + [ "$net" = "$mynet" ]
> +}
> +
> PATH=$PATH:/sbin:/usr/sbin
>
> . /lib/dracut-lib.sh
> @@ -75,8 +99,10 @@ if [ -z "$netroot" ] || [ ! -e "$handler" ] ; then
> die "No handler for netroot type '$netroot'"
> fi
>
> -# Now that we have DHCP information, we can fully validate netroot
> -$handler checkdhcp $netroot "$server_id" "$new_root_path" || exit 1
> +# Now that we have DHCP information, we can get our server
> +$handler server $netroot "$server_id" "$new_root_path" || exit 1
> +[ -s /tmp/server ] || die "Bug in $handler: did not create /tmp/server"
> +read target < /tmp/server
>
> # We're here, so we can assume that upping interfaces is now ok
> [ -z "$IFACES" ] && IFACES="$netif"
> @@ -88,8 +114,21 @@ done
> [ -e /tmp/net.$netif.hostname ] && . /tmp/net.$netif.hostname
> [ -e /tmp/net.$netif.resolv.conf ] && cp -f /tmp/net.$netif.resolv.conf /etc/resolv.conf
>
> +# Wait for traffic to be passable before we continue
> +is_local $target $mynet || target=$gw
> +
> +# FIXME make 120 configurable
> +TIMEOUT=$(( $(date +%s) + 120 ))
Is 120 seconds really necessary? I've worked with 60 seconds and haven't
had any problems, even when specifically provoking STP with ip down/up
before issuing arping.
Something else: If we really have to use 120 seconds and/or do this on
multiple interface we might run into the default udev event timeout of
180 seconds. Netroot should be moved into the new initqueue in that case.
> +while [ -z "$proceed" -a $(date +%s) -lt $TIMEOUT ]; do
> + for iface in $IFACES; do
> + arping -q -f -c 1 -I $iface $target && proceed=1 && break
> + done
> +done
Just so that I understand you correctly: You're trying to arping on all
interfaces until one says OK?
If we have multiple interface to up before mount/login, we should take care
to try and enable all interfaces:
for iface in $IFACES; do
is_local $gw $mask && local_target=$gw
is_local $server $mask && local_target=$server
[ -z "local_target" ] && continue;
arping -q -f -w $TIMEOUT -I $iface $local_target || die "Unable to ARP ping $local_target via "$iface"
done
> +
> # Run the handler to mount/login into the root device
> -if $handler mount "$netroot" "$server_id" "$new_root_path" $NEWROOT; then
> +if [ -n "$proceed" ] &&
> + $handler mount "$netroot" "$server_id" "$new_root_path" $NEWROOT;
> +then
> # Network rootfs mount successful
> for iface in $IFACES ; do
> [ -f /tmp/dhclient.$iface.lease ] && cp /tmp/dhclient.$iface.lease /tmp/net.$iface.lease
> @@ -98,14 +137,20 @@ if $handler mount "$netroot" "$server_id" "$new_root_path" $NEWROOT; then
>
> # Save used netif for later use
> [ ! -f /tmp/net.ifaces ] && echo $netif > /tmp/net.ifaces
> -else
> + exit 0
> +fi
> +
> +if [ -n "$proceed" ]; then
> warn "Mounting root via '$netif' failed"
> - # If we're trying with multiple interfaces, put that one down.
> - # ip down/flush ensures that routeing info goes away as well
> - if [ -z "$BOOTDEV" ] ; then
> - ip link set $netif down
> - ip addr flush dev $netif
> - echo "#empty" > /etc/resolv.conf
> - fi
> +else
> + warn "Unable to ARP ping $target via $netif"
> +fi
> +
> +# If we're trying with multiple interfaces, put that one down.
> +# ip down/flush ensures that routeing info goes away as well
> +if [ -z "$BOOTDEV" ] ; then
> + ip link set $netif down
> + ip addr flush dev $netif
> + echo "#empty" > /etc/resolv.conf
> fi
> exit 0
I'd suggest to move [ -n "$proceed" ] to before mount/login and just do
[ -z "$proceed" ] && die "..."
that way loose the if/else.
> diff --git a/modules.d/95iscsi/iscsiroot b/modules.d/95iscsi/iscsiroot
> index d79b663..7f2efa2 100755
> --- a/modules.d/95iscsi/iscsiroot
> +++ b/modules.d/95iscsi/iscsiroot
> @@ -17,9 +17,10 @@ if getarg rdnetdebug; then
> fi
>
> case "$1" in
> - check|checkdhcp) check_only=1 ;;
> - mount) ;;
> - *) die "$0 called with invalid command '$1'" ;;
> + check) check_only=1 ;;
> + server) server_only=1 ;;
> + mount) ;;
> + *) die "$0 called with invalid command '$1'" ;;
> esac
>
> # root is in the form
> @@ -55,13 +56,6 @@ if [ ! -e /sys/devices/virtual/iscsi_transport ]; then
> fi
> fi
>
> -[ -n "$check_only" ] && exit 0
> -
> -if getarg iscsi_firmware ; then
> - iscsistart -b
> - exit 0
> -fi
> -
> # override conf settings by command line options
> arg=$(getarg iscsi_initiator)
> [ -n "$arg" ] && iscsi_initiator=$arg
> @@ -100,6 +94,20 @@ iscsi_lun=$1; shift
> iscsi_target_name=$*
> IFS="$OLDIFS"
>
> +[ -n "$check_only" ] && exit 0
> +
> +# FIXME need support for service discovery if no server given, or
> +# parsing the firmware tables for an IP if iscsi_firmware is in effect
> +if [ -n "$server_only" ]; then
> + echo $iscsi_target_ip > /tmp/server
> + exit 0
> +fi
> +
> +if getarg iscsi_firmware ; then
> + iscsistart -b
> + exit 0
> +fi
> +
> # XXX is this needed?
> getarg ro && iscsirw=ro
> getarg rw && iscsirw=rw
> diff --git a/modules.d/95nbd/nbdroot b/modules.d/95nbd/nbdroot
> index 55c1b88..9450b84 100755
> --- a/modules.d/95nbd/nbdroot
> +++ b/modules.d/95nbd/nbdroot
> @@ -11,9 +11,10 @@ if getarg rdnetdebug; then
> fi
>
> case "$1" in
> - check|checkdhcp) check_only=1 ;;
> - mount) ;;
> - *) die "$0 called with invalid command '$1'" ;;
> + check) check_only=1 ;;
> + server) server_only=1 ;;
> + mount) ;;
> + *) die "$0 called with invalid command '$1'" ;;
> esac
>
> # root is in the form root=nbd:srv:port[:fstype[:rootflags[:nbdopts]]]
> @@ -52,6 +53,11 @@ incol2 /proc/devices nbd || modprobe nbd ||
> [ -z "$nbdport" ] && die "NBD root configuration missing port"
> [ -n "$check_only" ] && exit 0
>
> +if [ -n "$server_only" ]; then
> + echo $nbdserver > /tmp/server
> + exit 0
> +fi
> +
> # look through the NBD options and pull out the ones that need to
> # go before the host etc. Append a ',' so we know we terminate the loop
> nbdopts=${nbdopts},
> diff --git a/modules.d/95nfs/nfsroot b/modules.d/95nfs/nfsroot
> index 8cbfbb8..acfd6b5 100755
> --- a/modules.d/95nfs/nfsroot
> +++ b/modules.d/95nfs/nfsroot
> @@ -12,7 +12,7 @@ fi
>
> case "$1" in
> check) basic_check=1 ;;
> - checkdhcp) full_check=1 ;;
> + server) server_only=1 ;;
> mount) ;;
> *) die "$0 called with invalid command '$1'" ;;
> esac
> @@ -101,8 +101,11 @@ fi
> [ -z "$server" ] && die "Required parameter 'server' is missing"
> [ -z "$path" ] && die "NFS root requires a path"
>
> -# If we're just validating our options, we're done
> -[ -n "$full_check" ] && exit 0
> +# If we're just looking for the server...
> +if [ -n "$server_only" ]; then
> + echo $server > /tmp/server
> + exit 0
> +fi
>
> # Kernel replaces first %s with host name, and falls back to the ip address
> # if it isn't set. Only the first %s is substituted.
--
To unsubscribe from this list: send the line "unsubscribe initramfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2009-07-07 8:08 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-03 21:40 [RFC ONLY 0/5] Move argument validation to root handlers David Dillow
[not found] ` <cover.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-03 21:40 ` [RFC ONLY 1/5] netroot: remove unused hook David Dillow
[not found] ` <bd4d79bc048ad3944156f86eafb62cf4bc29b1f9.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-06 12:56 ` Seewer Philippe
2009-07-03 21:40 ` [RFC ONLY 2/5] netroot: remove unhelpful argument checks David Dillow
[not found] ` <0535c73bd25fdcaa9bf4de0bc4b041b74d11e547.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-06 13:00 ` Seewer Philippe
2009-07-03 21:40 ` [RFC ONLY 3/5] netroot: remove netif from handler invocation David Dillow
[not found] ` <44494af931ad839908cb4542f7c35ae59a4ef65e.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-06 13:56 ` Seewer Philippe
[not found] ` <4A520291.7010203-omB+W0Dpw2o@public.gmane.org>
2009-07-06 14:43 ` David Dillow
[not found] ` <1246891382.24010.6.camel-FqX9LgGZnHWDB2HL1qBt2PIbXMQ5te18@public.gmane.org>
2009-07-06 15:02 ` Seewer Philippe
[not found] ` <4A521208.2050605-omB+W0Dpw2o@public.gmane.org>
2009-07-06 16:06 ` David Dillow
[not found] ` <1246896365.24010.14.camel-FqX9LgGZnHWDB2HL1qBt2PIbXMQ5te18@public.gmane.org>
2009-07-07 8:10 ` Seewer Philippe
2009-07-03 21:40 ` [RFC ONLY 4/5] netroot: move dracut syntax validation to root handlers David Dillow
[not found] ` <d1aed501ae771d769efcd370f47184f12b9800d6.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-07 7:47 ` Seewer Philippe
[not found] ` <4A52FD93.3000406-omB+W0Dpw2o@public.gmane.org>
2009-07-07 14:57 ` David Dillow
2009-07-03 21:40 ` [RFC ONLY 5/5] PROOF-OF-CONCEPT: wait for spanning tree timeout via arping David Dillow
[not found] ` <8cf3d034e4611fbe661d4585fbfd1a03a6fd094b.1246656269.git.dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org>
2009-07-07 8:08 ` Seewer Philippe [this message]
[not found] ` <4A530297.1020906-omB+W0Dpw2o@public.gmane.org>
2009-07-07 15:09 ` David Dillow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A530297.1020906@bfh.ch \
--to=philippe.seewer-omb+w0dpw2o@public.gmane.org \
--cc=dave-i1Mk8JYDVaaSihdK6806/g@public.gmane.org \
--cc=initramfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox