#!/bin/bash
set -u

declare ThisScript=${0##*/}
declare -i ErrorCount=0
declare -i WaitPerIteration=5
declare -i MaxIterations=36

function msg () { echo -e "$*"; }
function errmsg () { msg "\\nError: ${1:-Unknown Error}\\n"; ErrorCount+=1; }
function bail () { errmsg "${1:-Unknown Error}"; exit "$ErrorCount"; }

# This script is intended to be useful as a systemd ExecStartPre script to ensure the
# necessary mounts, are available prior to making the ExecStart call to start a service.
# This simply uses a wait loop to give the mount point time to come online. Unlike the
# standard systemd mechanism for waiting for a mount point, this mechanism works 
# regardless of whether the given directory is a "real" mount point or just a regular
# directory, e.g. as may be the case in a test environment or perhaps during a recovery
# situtaion.

declare MountPoint="${1:-}"

# Make sure require utils are available.
for util in ls mountpoint seq; do
   command -v "$util" >/dev/null ||\
      errmsg "$ThisScript: Missing required utility: $util (perhaps PATH is wrong?)"
done

[[ "$ErrorCount" -eq 0 ]] || bail "Aborting $ThisScript due to lack of required utilities."

[[ -n "$MountPoint" ]] ||\
   bail "Missing required '<MountPoint>' parameter. Usage: $ThisScrpt <MountPoint>"

[[ -d "$MountPoint" ]] || bail "Mount point directory does not exist: $MountPoint"

# If the "mount point" isn't actually a mounted volume, skip the wait and just exit
# quickly and happily with a zero exit code.
mountpoint -q "$MountPoint" || exit 0

for i in $(seq 1 "$MaxIterations"); do
   if ls -ld "$MountPoint/" >/dev/null 2>&1; then
      exit 0
   fi
   msg "Waiting for mount $MountPoint to become responsive ($i/36)"
   sleep "$WaitPerIteration"
done

bail "Error: Mount point $MountPoint still not responsive after 3 minutes."

