docs: document the second nas_audiobooks flapping cause (oversized test file)

This commit is contained in:
2026-09-18 03:26:33 +00:00
parent c95fdef0e5
commit 8a983fe307
+2 -1
View File
@@ -112,7 +112,8 @@ Summary of how each service connects to the unRAID NAS (192.168.1.192 / 192.168.
- **Docker NFS named volumes**: The `nas_media` volume uses `soft,nolock,timeo=14,vers=3`. This is fragile — short timeout means EIO on spin-up. Plex/qBittorrent survive because they open/close handles per request. If either starts having I/O errors, migrate to the systemd permanent mount pattern. - **Docker NFS named volumes**: The `nas_media` volume uses `soft,nolock,timeo=14,vers=3`. This is fragile — short timeout means EIO on spin-up. Plex/qBittorrent survive because they open/close handles per request. If either starts having I/O errors, migrate to the systemd permanent mount pattern.
- **Docker's local NFS volume driver requires `host:/path` in `device`, and can't do NFSv4**: it calls `mount(2)` directly rather than shelling out to the `mount.nfs`/`mount.nfs4` userspace helper. Two consequences, both hit in the 2026-09-16 outage below: (1) nfs-utils 2.6.4 (Ubuntu 24.04) rejects the old `device=":/path"` + separate `o=addr=<ip>` split form - the host must be in the device string itself now (`device=<ip>:/path`); (2) `vers=4`/`nfsvers=4` fails with "protocol not supported" via the raw syscall even though a manual `mount -t nfs -o nfsvers=4 ...` succeeds (that goes through `mount.nfs`, which does version negotiation the raw syscall skips). Stick to `vers=3` for any Docker-managed NFS volume on this host. - **Docker's local NFS volume driver requires `host:/path` in `device`, and can't do NFSv4**: it calls `mount(2)` directly rather than shelling out to the `mount.nfs`/`mount.nfs4` userspace helper. Two consequences, both hit in the 2026-09-16 outage below: (1) nfs-utils 2.6.4 (Ubuntu 24.04) rejects the old `device=":/path"` + separate `o=addr=<ip>` split form - the host must be in the device string itself now (`device=<ip>:/path`); (2) `vers=4`/`nfsvers=4` fails with "protocol not supported" via the raw syscall even though a manual `mount -t nfs -o nfsvers=4 ...` succeeds (that goes through `mount.nfs`, which does version negotiation the raw syscall skips). Stick to `vers=3` for any Docker-managed NFS volume on this host.
- **Docker bind mounts + automount = stale handles**: Docker snapshots the mount reference at container start. If autofs cycles (unmount + remount) between container restarts, the container's bind mount goes stale while the host sees the path fine. Fix: use permanent `.mount` (no `.automount`) for any share that Docker containers bind-mount. **Hit in practice 2026-09-17**: `mnt-nas_audiobooks.mount` had been left on an `.automount` unit (autofs, `TimeoutIdleSec=0`) instead of the permanent-mount pattern used by every other Docker-bind-mounted NFS share. It flapped ESTALE on a recurring, multi-hour cadence over several days (self-healed every ~5 min by `nfs-mount-heal.sh`, but never actually fixed) even though `TimeoutIdleSec=0` should prevent autofs idle expiry - autofs can still cycle the underlying mount for reasons other than idle timeout, and any such cycle invalidates the container's bind-mounted reference exactly as this gotcha describes. Fix: `systemctl disable --now mnt-nas_audiobooks.automount`, delete the unit file, `systemctl enable --now mnt-nas_audiobooks.mount` directly (matching nas_family/nas_books/nas_owncloud exactly). Confirmed stable afterward. - **Docker bind mounts + automount = stale handles**: Docker snapshots the mount reference at container start. If autofs cycles (unmount + remount) between container restarts, the container's bind mount goes stale while the host sees the path fine. Fix: use permanent `.mount` (no `.automount`) for any share that Docker containers bind-mount. **Hit in practice 2026-09-17**: `mnt-nas_audiobooks.mount` had been left on an `.automount` unit (autofs, `TimeoutIdleSec=0`) instead of the permanent-mount pattern used by every other Docker-bind-mounted NFS share. It flapped ESTALE on a recurring, multi-hour cadence over several days (self-healed every ~5 min by `nfs-mount-heal.sh`, but never actually fixed) even though `TimeoutIdleSec=0` should prevent autofs idle expiry - autofs can still cycle the underlying mount for reasons other than idle timeout, and any such cycle invalidates the container's bind-mounted reference exactly as this gotcha describes. Fix: `systemctl disable --now mnt-nas_audiobooks.automount`, delete the unit file, `systemctl enable --now mnt-nas_audiobooks.mount` directly (matching nas_family/nas_books/nas_owncloud exactly).
- **`nfs-mount-heal.sh`'s own health check can generate false "stale" verdicts on shares with large files**: it `find`s the first file in the share and reads it to prove the mount is alive. Fine for immich (13-byte `.immich` marker) and oCIS (0-byte `.migrations.lock`), but `nas_audiobooks` has no small marker file, so `find` legitimately picked a real audiobook - **found 2026-09-18 to be 2.9GB**. The check `cat`'d the whole thing inside a 10s timeout, which can never finish regardless of mount health, producing `cat exit=124` "stale" verdicts on a mount that (after the automount fix above) was actually fine. This was the second, independent cause of the audiobooks flapping continuing after the automount fix - the two bugs were stacked. Fixed by reading only `head -c 65536` instead of the whole file; the script also now logs the real find/head error text instead of a generic guess. If a share's first-found file is ever large, this class of false positive can recur - the safer long-term fix would be to always test against a small dedicated marker file per share, matching immich/oCIS.
- **SQLite on NFS**: Never store SQLite databases (calibre `metadata.db`/`notes.db`, any app DB) on NFS. Even with `hard` mounts and NLM locking, transient NFS errors cause `SQLITE_IOERR`. Keep SQLite on local SSD; sync non-SQLite files to NAS if sharing is needed. - **SQLite on NFS**: Never store SQLite databases (calibre `metadata.db`/`notes.db`, any app DB) on NFS. Even with `hard` mounts and NLM locking, transient NFS errors cause `SQLITE_IOERR`. Keep SQLite on local SSD; sync non-SQLite files to NAS if sharing is needed.
- **CIFS vs NFS for file permissions**: CIFS enforces server-side ACLs based on the SMB user. Files created via NFS by uid=99 with mode 600 are inaccessible via CIFS. Use NFS when container needs uid-mapped access to NFS-created files. - **CIFS vs NFS for file permissions**: CIFS enforces server-side ACLs based on the SMB user. Files created via NFS by uid=99 with mode 600 are inaccessible via CIFS. Use NFS when container needs uid-mapped access to NFS-created files.
- **lsyncd for NAS sync**: inotify-based, syncs within ~15 seconds of any write. Config at `/etc/lsyncd/lsyncd.conf.lua`. Log at `/var/log/lsyncd.log`. - **lsyncd for NAS sync**: inotify-based, syncs within ~15 seconds of any write. Config at `/etc/lsyncd/lsyncd.conf.lua`. Log at `/var/log/lsyncd.log`.