4

After a reboot, I'm executing an application from a mounted network share (autofs) using an init.d script. The script starts by waiting 30 seconds before attempting to execute the command, in order to wait for the network/mount point to be up.

I would like to somehow detect that the network is definitively up and the mount has been definitively mounted, before executing the command.

What is your recommendation on how to achieve this (in CentOS 6.4) with this script?

This is what I have now:

#!/bin/bash
#
# chkconfig: 3 95 5
# description: My app
# processname: my-app
#

# Sleep for 30 seconds before attempting to execute command
sleep 30s

# Get function from functions library
. /etc/init.d/functions

# Start the service my-app from autofs mount
start() {
        echo -n "Starting my-app: "
        /share/path/my-app --log /tmp/log.log --supersede
        ### Create the lock file ###
        touch /var/lock/subsys/my-app
        success $"my-app startup"
        echo
}
# Restart the service my-app
stop() {
        echo -n "Stopping my-app: "
        killproc my-app
        ### Now, delete the lock file ###
        rm -f /var/lock/subsys/my-app
        echo
}
### main logic ###
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status my-app
        ;;
  restart|reload|condrestart)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|reload|status}"
        exit 1
esac
exit 0
fredrik
  • 671
  • 14
  • 20
  • possible duplicate of [How to change Linux services startup/boot order?](http://serverfault.com/questions/176055/how-to-change-linux-services-startup-boot-order) – Dennis Williamson Nov 03 '13 at 12:34
  • I believe what the OP means is the problem that some services start asynchronously, meaning the startup script can be done, but whatever it starts not be available right away. – Marki Nov 03 '13 at 14:28
  • @Marki No, I really like Alexis' answer. Making sure that the application is reachable is a great way of knowing that it can also be executed in my case. – fredrik Nov 03 '13 at 18:50
  • No? Well, my comment was about Dennis Williamson's comment. So, Yes! – Marki Nov 03 '13 at 19:37
  • @Marki Oh, yes of course. Sorry. Yes! – fredrik Nov 03 '13 at 20:02
  • To be pedantic, the mount point is a (empty) directory, and exists whether anything is mounted on it or not. – Falcon Momot Nov 04 '13 at 05:28
  • @FalconMomot is OP trying to detect the mount point before mounting the drive? Or trying to determine if the mount was successful? Also, automount does not mount the resource until you try to access it. And by default automount mounts all automounted partitions within a folder, and dynamically creates the mount points when it mounts the partition. But all of that happens, AFAIK, when the resource is accessed. – Jeter-work Nov 04 '16 at 17:12

2 Answers2

9

init scripts are started in order as defined by the S## numbers. Newer versions of Unix (at least on Linux) start the same ## numbers in parallel (Although you can turn that feature off...) All you have to do it use a ## that's after the network and fsmount number. Then it should work. However, if the fsmount starts in the background, the easiest is probably to probe for files on the mounted drive. Something like this:

while ! test -f /mnt/over-there/this/file/here
do
    sleep 1
done

This will wait until the file appears. If not there yet, sleep for a second then try again.

To avoid the potential problem of someone creating the file you are testing on the local computer, you may instead want to use the mountpoint command line as in:

while ! mountpoint -q /mnt/over-there
do
    sleep 1
done

(From comment below.) The -q is to make the command quiet.

--- Update: timeout after 30 attempts

In shell script you can also count and test numbers:

count=0
while ! test -f /mnt/over-there/this/file/here
do
    sleep 1
    count=`expr $count + 1`
    if test $count -eq 30
    then
        echo "timed out!"
        exit 1
    fi
done

This will stop if count reaches 30 (30 seconds of sleep plus the time it takes to check whether the file is available or not) after which it prints the error message "timed out!".

--- Update: in case you were to switch to systemd

With systemd, the Unit section supports:

ConditionPathIsMountPoint=/mnt/over-there

which does the same thing as the above script, without the timeout. This statement prevents starting your command until the mount exists.

Alexis Wilke
  • 2,057
  • 1
  • 18
  • 33
  • Absolutely right. Although I would add a timeout at some point that throws an error. – Marki Nov 03 '13 at 14:29
  • @Alexis-Wilke This is almost perfect. How can I throw an error/timeout after say 30 retries? – fredrik Nov 03 '13 at 18:49
  • @fredrik: Count to thirty and stop when 30 has been reached. – Marki Nov 03 '13 at 19:38
  • Also, instead of using `test -f` you could use `mountpoint -q` to ensure the mountpoint is actually mounted, and that file hasn't somehow appears on the local filesystem. – fukawi2 Nov 04 '13 at 05:54
5

Because the destination directory can be present but not mounted, I prefer simonpw test on /proc/mounts

if ! grep -qs '/the/mounted/dir' /proc/mounts; then
Orace
  • 151
  • 1
  • 2