1

I have a service that is started by a script /etc/init.d/foo. When a certain CIFS share (//fileserver/multimedia on /home/username/multimedia type cifs) becomes unavailable for any reason (unmounted, network down, cosmic rays,...), then I want the service foo to be stopped automatically. When the share is available again, then I want the service foo to (re)start automatically. My criterium for "available" is: being able to access the files on the share.

How do I do that?

2 Answers2

1

My criterium for "available" is: being able to access the files on the share.

You can create a test file on the mount like so:

touch /home/username/multimedia/testfile

Then run a bash script to check for the accessibility of that test file every 60 seconds like so:

#!/bin/bash
# Set the full path to the test file between " " in the next line
file="/home/username/multimedia/testfile"
while true; do
    if [ -f "$file" ]; then
        echo "File is available"
        # Your command/s here when the files on the mount are accessible.
    elif [ ! -f "$file" ]; then
        echo "File is NOT available"
        # Your command/s here when the files on the mount are NOT accessible.
    fi
    sleep 60
done
Raffa
  • 32,237
  • Would inotifywait be a more lightweight solution than a sleep/stat? – doneal24 Apr 15 '22 at 17:59
  • @doneal24 inotifywait is good for monitoring and reporting file events i.e. (read, write, modify, create, delete ... etc.) and although it has a unmount event but that is not how the OP defines availability ... so in this case, IMO, the bash script is a more proper solution ... and a sleep 60 call in this context should be close if not equal to inotifywait regarding the system load. – Raffa Apr 15 '22 at 18:24
  • @Raffa you are correct, when the network connection to the fileserver goes down (when the cleaning lady unplugs the server to plug in the vacuum cleaner) then that's not an unmount event if I'm not mistaken. The client still has a network connection, there just isn't a server alive at the other side. – Amedee Van Gasse Apr 15 '22 at 19:25
  • Your solution is what I had also thought of myself before I asked my question. I'm going to leave the question open for a bit longer in case anyone else has another solution. If not, then I'll accept your answer in a few days. – Amedee Van Gasse Apr 15 '22 at 19:27
  • 1
    @AmedeeVanGasse “if I'm not mistaken. The client still has a network connection, there just isn't a server alive at the other side.” … You are right, the mount will just become stale. – Raffa Apr 15 '22 at 19:34
  • 1
    I tried with both sleep/stat and inotify, and I can confirm that there is no inotify event when I shut down my NAS or unplug the network cable. I'll update my question with my final script. – Amedee Van Gasse Apr 21 '22 at 12:11
1

Final solution based on @Raffa's accepted answer:

#!/bin/bash
file_list="/home/amedee/bin/file_list.txt"

all_files_exist () { while read -r line; do [ -f "$line" ] status=$? if ! (exit $status); then echo "$line not found!" return $status fi done < "$file_list" }

start_crashplan () { echo "Starting CrashPlan" #/etc/init.d/code42 start }

stop_crashplan () { echo "Stopping CrashPlan" #/etc/init.d/code42 stop }

while true; do if all_files_exist; then echo "All files are available" start_crashplan else echo "Not all files are available" stop_crashplan fi sleep 60 done

  • I want to test more than one share, so I moved the file test to a function all_files_exist.
  • file_list.txt contains a list of testfiles on different shares that I want to check. They all have to be present, if even only one of them is missing or can't be reached, then the service must be stopped.
/home/amedee/Downloads/.testfile
/home/amedee/Multimedia/.testfile
/home/amedee/backup/.testfile
  • I can add or remove shares without needing to modify the script, I only need to edit file_list.txt - even while the script is still running.
  • Starting (or stopping) the service if it is already started (or stopped) is very much ok. The actual startup script itself takes care of checking if it has already started (or stopped).
  • This is the version I used for debugging as an unprivileged user. In my live version I uncommented the /etc/init.d/ lines and I removed all echo lines except echo "$line not found!". The startup script already provides enough console output, and by using functions, I have made the script already very much human readable. You only need to read the while true loop at the bottom to understand what's going on.
  • This script needs to be run at startup as root, so I call it from cron (sudo crontab -u root -e):
@reboot /home/amedee/bin/test_cifs_shares.sh