Keeping a SMB share mounted on macOS (and alerting when it does down)
On my primary Mac Studio desktop, I like to keep 2 Samba shares from my home server/NAS mounted all the time. These mounts can be interrupted by network glitches, power outages, and the like, so I needed a solution that could remount them when necessary and would alert me if they went offline for more than a few minutes.
The solution uses a combination of launchd, AppleScript, Uptime Kuma, and runner (my task runner/retrier/failure notification tool).
Initial connection
First, mount the share via the Finder’s “Connect to Server” dialog (which you can open from the Finder via ⌘K).
If prompted, allow the Finder to save the share’s password. This will allow a launchd job to remount it automatically when necessary.
Maintenance script
May 16, 2024: I've since made this script more robust; see version 2 instead.
Create a script that:
- Checks whether the mount is working properly
- Remounts it if necessary
- Exits with a nonzero exit code if the mount is down and remounting it failed
I do this using this script, ~/code/maintain-general-smb-mount.sh
:
#!/usr/bin/env bash
set -euo pipefail
[ -f /Volumes/general/.liveness.txt ] || osascript -e 'mount volume "smb://cdzombak@jetstream.dzhome/general"'
This script checks that the share is mounted by checking for the (empty) file .liveness.txt
in it, and if it’s missing it uses AppleScript to tell the Finder to remount the share.
launchd job & monitoring
Finally, we’ll run that script every minute using launchd. This job definition runs the script, and it uses runner to notify an Uptime Kuma push monitor when the script succeeds.
If the script fails — meaning the share is missing and remounting it failed — Uptime Kuma will notify me via email.
~/Library/LaunchAgents/com.dzombak.maintain-general-smb-mount.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>com.dzombak.maintain-general-smb-mount</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/runner</string>
<string>-job-name</string>
<string>maintain-general-smb-mount</string>
<string>-success-notify</string>
<string>http://localhost:9001/api/push/TOKEN?status=up&msg=OK&ping=</string>
<string>-timeout</string>
<string>10</string>
<string>-retries</string>
<string>2</string>
<string>--</string>
<string>/Users/cdzombak/code/maintain-general-smb-mount.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Users/cdzombak/opt/log/launchd/maintain-general-smb-mount.err.txt</string>
<key>StandardOutPath</key>
<string>/Users/cdzombak/opt/log/launchd/maintain-general-smb-mount.out.txt</string>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>