Skip to main content
Topic solved
This topic has been marked as solved and requires no further attention.
Topic: [SOLVED] how to wait on network (Read 1906 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

[SOLVED] how to wait on network

I am setting up armtix runit on a rpi4; since the board has no rtc I have installed ntp and that works OK. I have a run that looks like

Code: [Select]
# cat /etc/runit/sv/ntpd/run
#!/bin/sh
ntpd -g -q #run once and quit
exec ntpd -g -u ntp:ntp -n >/dev/null 2>&1

and this works, but leaves messages about not being able to connect.  I guess I need to wait on the network, but I'm not sure how to do that. Currently the network is setup OK using dhcpcd so  I could use

sv check dhcpcd >/dev/null || exit 1

but that will fail if I switch to another network setup. Are there more general ways to wait on the network?

Re: how to wait on network

Reply #1
I used this script
Code: [Select]
$ cat /bin/have-net
#/bin/sh
for d in /sys/class/net/*;do
[ `basename $d` = lo ] && continue
[ "`cat $d/operstate`" = "up" ] && echo "connected" && exit 0
done
echo "disconnected"
exit 1

and /bin/have-net > /dev/null || exit 1 in the scripts that need to wait on the network

Re: how to wait on network

Reply #2
That's a pretty clever idea. runit and s6 could definitely use a script like that. Thanks!

Re: how to wait on network

Reply #3
That's a pretty clever idea. runit and s6 could definitely use a script like that. Thanks!
I cannot claim too much credit. I think the idea of using /sys/class/net/eth0/operstate came from stack overflow. I just added the loop and this script is probably not robust enough against devices without operstate etc etc.
Also it's not obvious which  devices actually connect to the outside;



Re: how to wait on network

Reply #4
Also it's not obvious which  devices actually connect to the outside;
I have personal script for similar purpose, this is how i find actual interface inside it:
Code: [Select]
DEFAULT_ROUTE=
DEFAULT_ROUTE_IFACE=
while [ -z $DEFAULT_ROUTE -o -z $DEFAULT_ROUTE_IFACE ]; do
    DEFAULT_ROUTE=$(ip route|grep default|awk '{print $3}')
    DEFAULT_ROUTE_IFACE=$(ip route|grep default|awk '{print $5}')
    sleep 1
 done
ARMtix

Re: how to wait on network

Reply #5
So in the context of the runit loop that would just be

Code: [Select]
#/bin/sh
[ "`ip route|grep default|awk '{print ($3!="")+($5!="")}'`" = "2" ] && echo "connected" && exit 0
echo "disconnected"
exit 1

Re: how to wait on network

Reply #6
Depending on your actual need you can simplify regex. The part of script i've posted defines which interface to check. In my case its gateway address is obtained to periodically ping gateway later and check if connection is present (but sometimes it still fails). If you're only interested to check network on boot, just checking if default route is present could be enough
ARMtix

Re: how to wait on network

Reply #7
In the end following phoenix_king_rus' suggestion I made the have-net script look like

Code: [Select]
#/bin/sh
if [ -x /usr/bin/ip -a -x /usr/bin/awk ]; then
[ "`ip route|awk '/^default/{print ($3!="")+($5!="")}'`" = "2" ] && echo "connected" && exit 0
else
for d in /sys/class/net/*;do
[ `basename $d` = lo ] && continue
[ "`cat $d/operstate`" = "up" ] && echo "connected" && exit 0
done
fi
echo "disconnected"
exit 1

Re: how to wait on network

Reply #8
If you don't mind, I can include it on our runit scripts that require network (instead of running separate bin) and give proper credits. I'm sure the ip route and awk is enough (although the shell for loop is actually neat) since Artix has iproute2 and awk in base anyway.

Thanks!
now only the dinit guy in artix

Re: [SOLVED] how to wait on network

Reply #9
If you don't mind, I can include it on our runit scripts that require network (instead of running separate bin) and give proper credits. I'm sure the ip route and awk is enough (although the shell for loop is actually neat) since Artix has iproute2 and awk in base anyway.

Thanks!
Thanks Konimex I saw the change in the ntp-runit run script, but after finding it was taking a long time to work I had to add back the initial
Code: [Select]
ntpd -g -q	#run once and quit
I'm not sure why the -g option in the exec line doesn't do the same thing, but I think if there's no real time clock on the board (eg for the rpi4 which I am messing with) then the exec line takes a very long time to slew the system time from Jan 1 1970 up to the modern era.  I think this might work

Code: [Select]
#!/bin/sh
[ "$(ip route | awk '/^default/{print ($3!="")+($5!="")}')" = "2" ] || exit 1
[ ! -c /dev/rtc ] && ntpd -g -q #run one large slew and quit if there's no hardware clock
exec ntpd -g -u ntp:ntp -n >/dev/null 2>&1

Re: [SOLVED] how to wait on network

Reply #10
I'm not sure why the -g option in the exec line doesn't do the same thing, but I think if there's no real time clock on the board (eg for the rpi4 which I am messing with) then the exec line takes a very long time to slew the system time from Jan 1 1970 up to the modern era.  I think this might work
I solve this problem by explicitly adding ntpdate into script:
Code: [Select]
ntpdate ru.pool.ntp.org || exit 1
exec ntpd -g -u ntp:ntp -n >/dev/null 2>&1
Replace pool with your preferred one. Works for me on both rpi4 and odroid n2
ARMtix

 

Re: [SOLVED] how to wait on network

Reply #11
Code: [Select]
ntpdate ru.pool.ntp.org || exit 1
exec ntpd -g -u ntp:ntp -n >/dev/null 2>&1

according to https://linux.die.net/man/8/ntpdate the ntpdate functionality is actually part of ntpd now. The ntpdate manual page is not present  on my rpi4, but that man page says the -q flag of ntpd does the same job and presumably the preferred pools are already set in /etc/ntp.conf