Files
cifs-watch/README.md
2025-10-19 14:54:48 -05:00

211 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 46 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.