How to detect when networking initialized in /etc/init.d script?

17.8k views Asked by At

I have an /etc/init.d/ script that starts on boot and requires networking to be in place. I have the rc start set to 99, so it's the last thing that loads, but the networking doesn't load immediately and I'm currently having to rely on a 30 second sleep command to wait for network loading.

The OS is Ubuntu modified for embedded systems (Yocto Project). The filesystem is the same, but there are very limited services so it's using Sysvinit.

Is there a way to check that all networking has finished loading?

Here is the script if it is of help:

#!/bin/sh
#
# Daemon Name: blerd
#  
# chkconfig: - 3 99 1
# description: M3 Bluetooth Low Energy Relay Daemon

# Source function library.
. /etc/init.d/functions

PROGRAM=bler
LOCKFILE=/var/lock/subsys/$PROGRAM

start() { 
    [ -x $EXE ] || exit 5

    echo -n "Starting $PROGRAM: ";

    if [ -e $LOCKFILE ]; then
        echo "Instance of $PROGRAM exists."
        return 0;
    fi

    sleep 30
    $PROGRAM
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
        echo "Success"
    else
        echo "Failed"
    fi

    [ $RETVAL -eq 0 ] && touch $LOCKFILE
    return $RETVAL
}

stop() {
    echo -n "Stopping $PROGRAM: "

    if [ ! -e $LOCKFILE ]; then
        echo "No instance of $PROGRAM exists."
        return 0;
    fi

    killproc $PROGRAM
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
        echo "Success"
    else
        echo "Failed"
    fi

    [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
    return $RETVAL
}

status() {
    echo -n "Status $PROGRAM: "
    if [ -e $LOCKFILE ]; then
        echo "Running"
    else
        echo "Stopped"
    fi
    return 0;
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    status)
        status
        ;;
    *)
        echo "Usage: $0 {start|stop|status|restart}"
        exit 2
        ;;
esac
2

There are 2 answers

0
hek2mgl On BEST ANSWER

The basic Debian way:

Basically /etc/network/if-up.d is the place for such scripts. These scripts are called when an interface get's up on a Debian system or derivate - like Ubuntu. Here you can find a list of environment variables passed to these scripts. Using these variables you can decide which interface get's up and details of the interface's configuration. You may find examples of such scipts when looking into /etc/network/if-up.d

A sample script could look like this (derived from samba package. Just to explain how things work. If you are using Ubuntu you should use upstart will be explained later)

/etc/network/if-up.d/your-service

#!/bin/sh
# Try to bring nmbd up when an interface comes up, if smbd is already running.

# Don't bother to do anything for lo.
if [ "$IFACE" = lo ]; then
    exit 0
fi

# Only run from ifup.
if [ "$MODE" != start ]; then
    exit 0
fi

# we only care about inet and inet6.
case $ADDRFAM in
    inet|inet6|NetworkManager)
        ;;  
    *)  
        exit 0
        ;;  
esac


# start the service
invoke-rc.d your-service start >/dev/null

exit 0

Note that you need to

chmod +x /etc/network/if-up.d/your-service

Ubuntu / Upstart:

Ubuntu is using upstart as a sysvinit replacement. If you are looking into /etc/network/if-up.d/ you see that upstart has placed a hook there as well. This hook is the base of the more elaborated upstart mechanism that provides the possibility to start a service not unless a certain network interface has been brought up. The upstart hook will trigger the event net-device-up and passes the IFACE, LOGICAL, ADDRFAM and METHOD as parameters. You use this hook in the upstart script for your service (like @Guy mentioned):

start on net-device-up IFACE=eth0
0
Guy Gavriely On

if you are on Ubuntu, as this question was tagged, consider using Ubuntu upstart

beside the great simplicity you'll also be able to:

start on net-device-up IFACE=eth0

for more info see entire upstart cookbook