# cifs-watch ## Overview `cifs-watch` is a lightweight Bash watchdog that automatically monitors and repairs **CIFS/SMB network mounts** defined in `/etc/fstab`. It keeps your NAS/file-server shares mounted and healthy even after network hiccups or reboots. Designed for **homelab** and **server** environments. Script file is named `cifs-watch` (no `.sh` extension). --- ## Features - Smart discovery of CIFS lines in `/etc/fstab` (supports 4–6 fields; skips `noauto`). - Network-aware checks (DNS resolution, optional ping, **TCP/445**). - Health probe with a short timeout to catch stale mounts. - Repair flow: `mount -o remount` → fallback `umount` + clean `mount`. - Logs to syslog and optional file (`/var/log/cifs-remount.log`). - `--dry-run`, `--verbose` flags for safe testing. - Works with cron or a systemd timer. - **Per-server backoff** to reduce noisy retries when a host is offline. --- ## How It Works 1. **Discovery** — scans `/etc/fstab` for uncommented `cifs` entries like: ```ini //nas.local/media /mnt/media cifs vers=3.0,credentials=/root/.smbcreds 0 0 //192.168.1.50/share /mnt/share cifs credentials=/root/.creds,iocharset=utf8 0 0 ``` 2. **Reachability** — ensures the server resolves, optionally pings, and has TCP/445 open. 3. **Health probe** — times a quick `ls` against the mountpoint. 4. **Repair** — remount or unmount/remount as needed, with retries and logging. --- ## First-Run Setup 1. **Install prerequisites** ```bash sudo apt install cifs-utils ``` 2. **Credentials file** ```bash sudo nano /root/.smbcreds ``` ```ini username=myuser password=mypassword domain=MYDOMAIN # optional ``` ```bash sudo chmod 600 /root/.smbcreds ``` 3. **Add to `/etc/fstab`** ```ini //192.168.1.10/media /mnt/media cifs vers=3.0,credentials=/root/.smbcreds,uid=1000,gid=1000,file_mode=0644,dir_mode=0755 0 0 ``` > Avoid `noauto` if you want the script to manage the mount. 4. **Test manually** ```bash sudo mount -a sudo ls /mnt/media ``` 5. **Verify connectivity** ```bash ping -c 2 192.168.1.10 nc -zv 192.168.1.10 445 ``` --- ## Installation ```bash sudo install -m 0755 cifs-watch /usr/local/sbin/cifs-watch sudo touch /var/log/cifs-remount.log && sudo chmod 600 /var/log/cifs-remount.log ``` **Test it:** ```bash sudo /usr/local/sbin/cifs-watch --dry-run --verbose sudo /usr/local/sbin/cifs-watch --verbose ``` Logs: - `/var/log/cifs-remount.log` - `journalctl -t cifs-watch` or `journalctl -u cifs-watch.service` --- ## Automating with systemd Create the following two files: **`/etc/systemd/system/cifs-watch.service`** ```ini [Unit] Description=Monitor and repair CIFS mounts [Service] Type=oneshot ExecStart=/usr/local/sbin/cifs-watch Nice=10 ``` **`/etc/systemd/system/cifs-watch.timer`** ```ini [Unit] Description=Run cifs-watch periodically [Timer] OnBootSec=2min OnUnitActiveSec=5min AccuracySec=30s Unit=cifs-watch.service [Install] WantedBy=timers.target ``` Enable and start: ```bash sudo systemctl daemon-reload sudo systemctl enable --now cifs-watch.timer ``` --- ## Command-Line Options | Option | Description | |--------|-------------| | `-n`, `--dry-run` | Simulate actions (no remounts) | | `-v`, `--verbose` | Detailed output | | `--logfile PATH` | Override/disable file logging (empty string disables) | | `-h`, `--help` | Show usage | --- ## Optional: Per-Server Backoff Prevents hammering an offline NAS with constant retries. - State file: `/var/tmp/cifs-watch-backoff.json` (line-delimited JSON; last row for a host wins). - Window: `BACKOFF_MINUTES=10` by default. Set to `0` to disable. - Backoff state is reset on reboot (uses `/var/tmp`). Example log flow: ```log [WARN] Server NOT reachable: nas.local (skipping /mnt/media) [INFO] Backoff started: will not retry nas.local for 10 minutes ... [INFO] Backoff expired: rechecking nas.local [INFO] Server reachable: nas.local — attempting repair ``` --- ## Exit Codes | Code | Meaning | |------|---------| | `0` | All mounts healthy | | `1` | One or more mounts failed or unreachable | | `2` | Usage/dependency error | --- ## Cron Alternative ```ini */5 * * * * /usr/local/sbin/cifs-watch >/dev/null 2>&1 ``` --- ## Troubleshooting - Mount works manually but not via script → check credentials path/permissions and DNS (`getent ahosts servername`). - “Transport endpoint not connected” → script will unmount/remount automatically. - No CIFS entries found → ensure `cifs` type and not commented lines in `/etc/fstab`. - NAS offline noise → ensure backoff is enabled (default 10 minutes). --- ## License Released under the [Unlicense](https://unlicense.org/). You can do whatever you want with this code. No warranty provided.