Message ID | 1443879105-3036-1-git-send-email-yann.morin.1998@free.fr |
---|---|
State | Accepted |
Commit | 49964858f45d2243c513e6d362e992ad89ec7a45 |
Headers | show |
On 03-10-15 14:31, Yann E. MORIN wrote: > On some machines, the network interface is slow to appear. For example, > on the Raspberry Pi, the network interface eth0 is an ethernet-over-USB, > and our standard boot process is too fast, so our network startup script > is called before the USB bus is compeltely enumerated, thus it can't > configure eth0. > > If Buildroot is configured to do a DHCP on an interface, install a > startup script, just before S40network, that waits for that interface. > > Since Buildroot can only be configured to run DHCP on a single interface, > we do not need a script that waits for more than one interface. > > Closes #8116. > > Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> > --- > package/skeleton/S39wait-for-network-if | 43 +++++++++++++++++++++++++++++++++ Argh, you're adding an init script to skeleton! That's evil(TM)! :-) Seriously, this should be part of package/initscripts/init.d/S40network instead. > package/skeleton/skeleton.mk | 2 ++ > 2 files changed, 45 insertions(+) > create mode 100644 package/skeleton/S39wait-for-network-if > > diff --git a/package/skeleton/S39wait-for-network-if b/package/skeleton/S39wait-for-network-if > new file mode 100644 > index 0000000..010026e > --- /dev/null > +++ b/package/skeleton/S39wait-for-network-if > @@ -0,0 +1,43 @@ > +#!/bin/sh > + > +# In case we have a slow-to-appear interface (e.g. eth-over-USB), > +# and we need to configure it, wait until it appears. But not too > +# long either. WAIT_DELAY is in seconds. > +WAIT_DELAY=15 > + > +wait_for_IF() { > + IF="$(sed -r -e '/^auto lo/d;' \ I believe the ; are redundant when you use -e (at least that's what we do in other cases). > + -e '/^auto (.+)$/!d;' \ > + -e 's//\1/;' \ This one got me looking at the sed man page and I'm still surprised that it works. Basically, this s command is reusing the same address as given on the previous line, but without the ! modifier, right? Regards, Arnout > + /etc/network/interfaces > + )" > + if [ -z "${IF}" -o -e "/sys/class/net/${IF}" ]; then > + return 0 > + fi > + printf "Waiting for interface %s to appear" "${IF}" > + wait=${WAIT_DELAY} > + while [ ${wait} -gt 0 ]; do > + if [ -e "/sys/class/net/${IF}" ]; then > + printf " yes\n" > + return 0 > + fi > + sleep 1 > + printf "." > + : $((wait--)) > + done > + printf " no.\n" > + return 1 > +} > + > +case "$1" in > + start) > + wait_for_IF > + ;; > + stop) > + ;; > + restart) > + "$0" start > + ;; > + *) > + echo "Usage: $0 {start|stop|restart}" > +esac > diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk > index 48e7085..733b86f 100644 > --- a/package/skeleton/skeleton.mk > +++ b/package/skeleton/skeleton.mk > @@ -76,6 +76,8 @@ define SET_NETWORK_DHCP > echo "auto $(NETWORK_DHCP_IFACE)"; \ > echo "iface $(NETWORK_DHCP_IFACE) inet dhcp"; \ > ) >> $(TARGET_DIR)/etc/network/interfaces > + $(INSTALL) -D -m 0755 package/skeleton/S39wait-for-network-if \ > + $(TARGET_DIR)/etc/init.d/S39wait-for-network-if > endef > endif > >
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes: > On some machines, the network interface is slow to appear. For example, > on the Raspberry Pi, the network interface eth0 is an ethernet-over-USB, > and our standard boot process is too fast, so our network startup script > is called before the USB bus is compeltely enumerated, thus it can't > configure eth0. > If Buildroot is configured to do a DHCP on an interface, install a > startup script, just before S40network, that waits for that interface. > Since Buildroot can only be configured to run DHCP on a single interface, > we do not need a script that waits for more than one interface. > Closes #8116. A more generic solution for dynamic changes to network interfaces is to NOT mark them as auto and instead use ifplugd -M <interface>. > Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> > --- > package/skeleton/S39wait-for-network-if | 43 +++++++++++++++++++++++++++++++++ > package/skeleton/skeleton.mk | 2 ++ > 2 files changed, 45 insertions(+) > create mode 100644 package/skeleton/S39wait-for-network-if > diff --git a/package/skeleton/S39wait-for-network-if b/package/skeleton/S39wait-for-network-if > new file mode 100644 > index 0000000..010026e > --- /dev/null > +++ b/package/skeleton/S39wait-for-network-if > @@ -0,0 +1,43 @@ > +#!/bin/sh > + > +# In case we have a slow-to-appear interface (e.g. eth-over-USB), > +# and we need to configure it, wait until it appears. But not too > +# long either. WAIT_DELAY is in seconds. > +WAIT_DELAY=15 > + > +wait_for_IF() { > + IF="$(sed -r -e '/^auto lo/d;' \ > + -e '/^auto (.+)$/!d;' \ > + -e 's//\1/;' \ > + /etc/network/interfaces > + )" This assumes we have at most 1 interface to wait for. Perhaps we could instead do something like (untested): IFACES=$(awk '/^auto/ { print $2 }' /tmp/interfaces) for i in $(seq $WAIT_DELAY); do for IFACE in $IFACES; do if [ ! -e "/tmp/$IFACE" ]; then sleep 1 continue 2 fi done echo "ok"; exit 0 done echo "timeout"; exit 1
>>>>> "Peter" == Peter Korsgaard <peter@korsgaard.com> writes: >> +wait_for_IF() { >> + IF="$(sed -r -e '/^auto lo/d;' \ >> + -e '/^auto (.+)$/!d;' \ >> + -e 's//\1/;' \ >> + /etc/network/interfaces >> + )" > This assumes we have at most 1 interface to wait for. > Perhaps we could instead do something like (untested): > IFACES=$(awk '/^auto/ { print $2 }' /tmp/interfaces) That should naturally be /etc/network/interfaces > for i in $(seq $WAIT_DELAY); do > for IFACE in $IFACES; do > if [ ! -e "/tmp/$IFACE" ]; then and /sys/class/net/$IFACE See, I did actually do a quick test after all ;)
Hello, On Sat, 3 Oct 2015 14:31:45 +0100, Yann E. MORIN wrote: > + printf "Waiting for interface %s to appear" "${IF}" > + wait=${WAIT_DELAY} > + while [ ${wait} -gt 0 ]; do > + if [ -e "/sys/class/net/${IF}" ]; then > + printf " yes\n" > + return 0 > + fi > + sleep 1 > + printf "." > + : $((wait--)) > + done One thing that I really like in Buildroot is that by default, it generates you a system that boots really fast. People often don't have to do anything special with Buildroot to make it boot fast. So having a shell script that is installed by default and does a "sleep 1" in a loop is not very nice :-/ Though I agree that it will only slow the boot on systems where the network interfaces are not available immediately at boot time. Thomas
On Sat, Oct 3, 2015 at 5:47 PM, Thomas Petazzoni < thomas.petazzoni@free-electrons.com> wrote: > Hello, > > On Sat, 3 Oct 2015 14:31:45 +0100, Yann E. MORIN wrote: > > > + printf "Waiting for interface %s to appear" "${IF}" > > + wait=${WAIT_DELAY} > > + while [ ${wait} -gt 0 ]; do > > + if [ -e "/sys/class/net/${IF}" ]; then > > + printf " yes\n" > > + return 0 > > + fi > > + sleep 1 > > + printf "." > > + : $((wait--)) > > + done > > One thing that I really like in Buildroot is that by default, it > generates you a system that boots really fast. People often don't have > to do anything special with Buildroot to make it boot fast. So having a > shell script that is installed by default and does a "sleep 1" in a > loop is not very nice :-/ > > Though I agree that it will only slow the boot on systems where the > network interfaces are not available immediately at boot time. > I have that trouble too but instead of doing a sleep 1, I "hammer" the system with sleep 0.1 or usleep 25 if it's available (even usleep 1 can work, since it's not RT, it takes around 10ms). This way it's almost transparent and add the necessary requirements before going on with the boot. > > Thomas > -- > Thomas Petazzoni, CTO, Free Electrons > Embedded Linux, Kernel and Android engineering > http://free-electrons.com > _______________________________________________ > buildroot mailing list > buildroot@busybox.net > http://lists.busybox.net/mailman/listinfo/buildroot >
On 03-10-15 19:29, Maxime Hadjinlian wrote: > > > On Sat, Oct 3, 2015 at 5:47 PM, Thomas Petazzoni > <thomas.petazzoni@free-electrons.com > <mailto:thomas.petazzoni@free-electrons.com>> wrote: > > Hello, > > On Sat, 3 Oct 2015 14:31:45 +0100, Yann E. MORIN wrote: > > > + printf "Waiting for interface %s to appear" "${IF}" > > + wait=${WAIT_DELAY} > > + while [ ${wait} -gt 0 ]; do > > + if [ -e "/sys/class/net/${IF}" ]; then > > + printf " yes\n" > > + return 0 > > + fi > > + sleep 1 > > + printf "." > > + : $((wait--)) > > + done > > One thing that I really like in Buildroot is that by default, it > generates you a system that boots really fast. People often don't have > to do anything special with Buildroot to make it boot fast. So having a > shell script that is installed by default and does a "sleep 1" in a > loop is not very nice :-/ > > Though I agree that it will only slow the boot on systems where the > network interfaces are not available immediately at boot time. > > I have that trouble too but instead of doing a sleep 1, I "hammer" the system > with sleep 0.1 or usleep 25 if it's available (even usleep 1 can work, since > it's not RT, it takes around 10ms). Since sysv init is not parallel, you're not even hammering the system since nothing else is going on except perhaps some hotplug callbacks. Regards, Arnout > This way it's almost transparent and add the necessary requirements before going > on with the boot. > > > Thomas > -- > Thomas Petazzoni, CTO, Free Electrons > Embedded Linux, Kernel and Android engineering > http://free-electrons.com > _______________________________________________ > buildroot mailing list > buildroot@busybox.net <mailto:buildroot@busybox.net> > http://lists.busybox.net/mailman/listinfo/buildroot > > > > > _______________________________________________ > buildroot mailing list > buildroot@busybox.net > http://lists.busybox.net/mailman/listinfo/buildroot >
On Sat, Oct 3, 2015 at 8:43 PM, Arnout Vandecappelle <arnout@mind.be> wrote: > On 03-10-15 19:29, Maxime Hadjinlian wrote: > > > > > > On Sat, Oct 3, 2015 at 5:47 PM, Thomas Petazzoni > > <thomas.petazzoni@free-electrons.com > > <mailto:thomas.petazzoni@free-electrons.com>> wrote: > > > > Hello, > > > > On Sat, 3 Oct 2015 14:31:45 +0100, Yann E. MORIN wrote: > > > > > + printf "Waiting for interface %s to appear" "${IF}" > > > + wait=${WAIT_DELAY} > > > + while [ ${wait} -gt 0 ]; do > > > + if [ -e "/sys/class/net/${IF}" ]; then > > > + printf " yes\n" > > > + return 0 > > > + fi > > > + sleep 1 > > > + printf "." > > > + : $((wait--)) > > > + done > > > > One thing that I really like in Buildroot is that by default, it > > generates you a system that boots really fast. People often don't > have > > to do anything special with Buildroot to make it boot fast. So > having a > > shell script that is installed by default and does a "sleep 1" in a > > loop is not very nice :-/ > > > > Though I agree that it will only slow the boot on systems where the > > network interfaces are not available immediately at boot time. > > > > I have that trouble too but instead of doing a sleep 1, I "hammer" the > system > > with sleep 0.1 or usleep 25 if it's available (even usleep 1 can work, > since > > it's not RT, it takes around 10ms). > > Since sysv init is not parallel, you're not even hammering the system > since > nothing else is going on except perhaps some hotplug callbacks. > sysv is not, but the shell is. The scripts are started in background and then I simply use wait > > Regards, > Arnout > > > This way it's almost transparent and add the necessary requirements > before going > > on with the boot. > > > > > > Thomas > > -- > > Thomas Petazzoni, CTO, Free Electrons > > Embedded Linux, Kernel and Android engineering > > http://free-electrons.com > > _______________________________________________ > > buildroot mailing list > > buildroot@busybox.net <mailto:buildroot@busybox.net> > > http://lists.busybox.net/mailman/listinfo/buildroot > > > > > > > > > > _______________________________________________ > > buildroot mailing list > > buildroot@busybox.net > > http://lists.busybox.net/mailman/listinfo/buildroot > > > > > -- > Arnout Vandecappelle arnout at mind be > Senior Embedded Software Architect +32-16-286500 > Essensium/Mind http://www.mind.be > G.Geenslaan 9, 3001 Leuven, Belgium BE 872 984 063 RPR Leuven > LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle > GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF >
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@free-electrons.com> writes: > Hello, > On Sat, 3 Oct 2015 14:31:45 +0100, Yann E. MORIN wrote: >> + printf "Waiting for interface %s to appear" "${IF}" >> + wait=${WAIT_DELAY} >> + while [ ${wait} -gt 0 ]; do >> + if [ -e "/sys/class/net/${IF}" ]; then >> + printf " yes\n" >> + return 0 >> + fi >> + sleep 1 >> + printf "." >> + : $((wait--)) >> + done > One thing that I really like in Buildroot is that by default, it > generates you a system that boots really fast. People often don't have > to do anything special with Buildroot to make it boot fast. So having a > shell script that is installed by default and does a "sleep 1" in a > loop is not very nice :-/ > Though I agree that it will only slow the boot on systems where the > network interfaces are not available immediately at boot time. Or where you misconfigured /etc/network/interfaces or forgot to enable the needed drivers in the kernel, but yeah. But yes, using something like ifplugd to handle the interface when it shows up (or link state changes) is certainly nicer than just waiting.
>>>>> "Peter" == Peter Korsgaard <peter@korsgaard.com> writes: >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes: >> On some machines, the network interface is slow to appear. For example, >> on the Raspberry Pi, the network interface eth0 is an ethernet-over-USB, >> and our standard boot process is too fast, so our network startup script >> is called before the USB bus is compeltely enumerated, thus it can't >> configure eth0. >> If Buildroot is configured to do a DHCP on an interface, install a >> startup script, just before S40network, that waits for that interface. >> Since Buildroot can only be configured to run DHCP on a single interface, >> we do not need a script that waits for more than one interface. >> Closes #8116. > This assumes we have at most 1 interface to wait for. > Perhaps we could instead do something like (untested): > IFACES=$(awk '/^auto/ { print $2 }' /tmp/interfaces) > for i in $(seq $WAIT_DELAY); do > for IFACE in $IFACES; do > if [ ! -e "/tmp/$IFACE" ]; then > sleep 1 > continue 2 > fi > done > echo "ok"; exit 0 > done > echo "timeout"; exit 1 Committed after moving it to S40network and changing the implementation to support multiple interaces, thanks.
Hello Yann, On Saturday 03 October 2015 14:31:45 Yann E. MORIN wrote: > On some machines, the network interface is slow to appear. For > example, on the Raspberry Pi, the network interface eth0 is an > ethernet-over-USB, and our standard boot process is too fast, so our > network startup script is called before the USB bus is compeltely > enumerated, thus it can't configure eth0. > > If Buildroot is configured to do a DHCP on an interface, install a > startup script, just before S40network, that waits for that interface. > > Since Buildroot can only be configured to run DHCP on a single > interface, we do not need a script that waits for more than one > interface. > > Closes #8116. > > Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> > --- > package/skeleton/S39wait-for-network-if | 43 > +++++++++++++++++++++++++++++++++ package/skeleton/skeleton.mk > | 2 ++ > 2 files changed, 45 insertions(+) > create mode 100644 package/skeleton/S39wait-for-network-if > > diff --git a/package/skeleton/S39wait-for-network-if > b/package/skeleton/S39wait-for-network-if new file mode 100644 > index 0000000..010026e > --- /dev/null > +++ b/package/skeleton/S39wait-for-network-if > @@ -0,0 +1,43 @@ > +#!/bin/sh > + > +# In case we have a slow-to-appear interface (e.g. eth-over-USB), > +# and we need to configure it, wait until it appears. But not too > +# long either. WAIT_DELAY is in seconds. > +WAIT_DELAY=15 > + > +wait_for_IF() { > + IF="$(sed -r -e '/^auto lo/d;' \ > + -e '/^auto (.+)$/!d;' \ > + -e 's//\1/;' \ > + /etc/network/interfaces > + )" > + if [ -z "${IF}" -o -e "/sys/class/net/${IF}" ]; then > + return 0 > + fi > + printf "Waiting for interface %s to appear" "${IF}" > + wait=${WAIT_DELAY} > + while [ ${wait} -gt 0 ]; do > + if [ -e "/sys/class/net/${IF}" ]; then > + printf " yes\n" > + return 0 > + fi > + sleep 1 > + printf "." > + : $((wait--)) > + done > + printf " no.\n" > + return 1 > +} > + > +case "$1" in > + start) > + wait_for_IF > + ;; > + stop) > + ;; > + restart) > + "$0" start > + ;; > + *) > + echo "Usage: $0 {start|stop|restart}" > +esac I am a bit late to do the review, but why not add a script in /etc/network/if-pre-up.d ? For example (notice $IFACE and $IF_MAXWAIT are set by ifupdown): #! /bin/sh if [ "${IF_MAXWAIT}" ]; then printf "Waiting for interface %s to appear" "${IFACE}" while [ ${IF_MAXWAIT} -gt 0 ]; do if [ -e "/sys/class/net/${IFACE}" ]; then printf " yes\n" exit 0 fi sleep 1 printf "." : $((wait--)) done printf " no.\n" exit 1 fi Next, interface would use "maxwait" property in /etc/network/interface: auto eth0 iface eth0 inet dhcp maxwait 15 BR,
>>>>> "Jérôme" == Jérôme Pouiller <jezz@sysmic.org> writes: Hi, > I am a bit late to do the review, but why not add a script in > /etc/network/if-pre-up.d ? For example (notice $IFACE and $IF_MAXWAIT > are set by ifupdown): > #! /bin/sh > if [ "${IF_MAXWAIT}" ]; then > printf "Waiting for interface %s to appear" "${IFACE}" > while [ ${IF_MAXWAIT} -gt 0 ]; do > if [ -e "/sys/class/net/${IFACE}" ]; then > printf " yes\n" > exit 0 > fi > sleep 1 > printf "." > : $((wait--)) > done > printf " no.\n" > exit 1 > fi That's certainly also an option. Care to send a patch reworking the logic in S40network to a pre-up.d hook? > Next, interface would use "maxwait" property in /etc/network/interface: > auto eth0 > iface eth0 inet dhcp > maxwait 15 Then our BR2_SYSTEM_DHCP logic should probably also be adapted to add 'maxwait 15' by default. Thanks!
On Monday 19 October 2015 12:15:40 Peter Korsgaard wrote: > >>>>> "Jérôme" == Jérôme Pouiller <jezz@sysmic.org> writes: > Hi, > > > I am a bit late to do the review, but why not add a script in > > > > /etc/network/if-pre-up.d ? For example (notice $IFACE and > > $IF_MAXWAIT > > are set by ifupdown): > > > > #! /bin/sh > > if [ "${IF_MAXWAIT}" ]; then > > > > printf "Waiting for interface %s to appear" "${IFACE}" > > while [ ${IF_MAXWAIT} -gt 0 ]; do > > > > if [ -e "/sys/class/net/${IFACE}" ]; then > > > > printf " yes\n" > > exit 0 > > > > fi > > sleep 1 > > printf "." > > > > : $((wait--)) > > > > done > > printf " no.\n" > > exit 1 > > > > fi > > That's certainly also an option. Care to send a patch reworking the > logic in S40network to a pre-up.d hook? Ok, I will.
diff --git a/package/skeleton/S39wait-for-network-if b/package/skeleton/S39wait-for-network-if new file mode 100644 index 0000000..010026e --- /dev/null +++ b/package/skeleton/S39wait-for-network-if @@ -0,0 +1,43 @@ +#!/bin/sh + +# In case we have a slow-to-appear interface (e.g. eth-over-USB), +# and we need to configure it, wait until it appears. But not too +# long either. WAIT_DELAY is in seconds. +WAIT_DELAY=15 + +wait_for_IF() { + IF="$(sed -r -e '/^auto lo/d;' \ + -e '/^auto (.+)$/!d;' \ + -e 's//\1/;' \ + /etc/network/interfaces + )" + if [ -z "${IF}" -o -e "/sys/class/net/${IF}" ]; then + return 0 + fi + printf "Waiting for interface %s to appear" "${IF}" + wait=${WAIT_DELAY} + while [ ${wait} -gt 0 ]; do + if [ -e "/sys/class/net/${IF}" ]; then + printf " yes\n" + return 0 + fi + sleep 1 + printf "." + : $((wait--)) + done + printf " no.\n" + return 1 +} + +case "$1" in + start) + wait_for_IF + ;; + stop) + ;; + restart) + "$0" start + ;; + *) + echo "Usage: $0 {start|stop|restart}" +esac diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk index 48e7085..733b86f 100644 --- a/package/skeleton/skeleton.mk +++ b/package/skeleton/skeleton.mk @@ -76,6 +76,8 @@ define SET_NETWORK_DHCP echo "auto $(NETWORK_DHCP_IFACE)"; \ echo "iface $(NETWORK_DHCP_IFACE) inet dhcp"; \ ) >> $(TARGET_DIR)/etc/network/interfaces + $(INSTALL) -D -m 0755 package/skeleton/S39wait-for-network-if \ + $(TARGET_DIR)/etc/init.d/S39wait-for-network-if endef endif
On some machines, the network interface is slow to appear. For example, on the Raspberry Pi, the network interface eth0 is an ethernet-over-USB, and our standard boot process is too fast, so our network startup script is called before the USB bus is compeltely enumerated, thus it can't configure eth0. If Buildroot is configured to do a DHCP on an interface, install a startup script, just before S40network, that waits for that interface. Since Buildroot can only be configured to run DHCP on a single interface, we do not need a script that waits for more than one interface. Closes #8116. Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> --- package/skeleton/S39wait-for-network-if | 43 +++++++++++++++++++++++++++++++++ package/skeleton/skeleton.mk | 2 ++ 2 files changed, 45 insertions(+) create mode 100644 package/skeleton/S39wait-for-network-if