From 9b95f88e8c634cbdcb4a1656870875fc378d9d3d Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sat, 11 Jul 2026 15:43:26 +0200 Subject: [PATCH] audit(Q1c): NAS automount trigger does NOT survive a guest reboot (empty-dir FAIL) + follow-up Supervised live proof on the demo (agent 0.82.0 + controller 0.115.0): after pct reboot 9201 the autofs trigger does not re-propagate into the guest; an in-guest access sees an empty dir and does not trigger the host mount. Root cause: shared->slave propagation + no agent network-mount reassert on guest reboot. FAIL protocol honored (nothing repaired live); fix spec'd in backlog. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6 --- .../audits/SPIKE-nas-dsm-2026-07-11.md | 39 +++++++++++++++ ...WUP-nas-automount-guest-reboot-reassert.md | 49 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 documentation/backlog/FOLLOWUP-nas-automount-guest-reboot-reassert.md diff --git a/documentation/audits/SPIKE-nas-dsm-2026-07-11.md b/documentation/audits/SPIKE-nas-dsm-2026-07-11.md index 4f99598..2c04bad 100644 --- a/documentation/audits/SPIKE-nas-dsm-2026-07-11.md +++ b/documentation/audits/SPIKE-nas-dsm-2026-07-11.md @@ -59,6 +59,45 @@ the UI invokes — anti-F9). (192.168.0.180:/mnt/5_hdd/felhom-data, health ok) — untouched by this spike; it is the Part E (Q1c restart) subject. +## Q1c — NAS automount trigger survival across a guest restart: **FAIL (the dangerous empty-dir case)** + +**Supervised (operator GO 2026-07-11), on the fully-updated stack (agent 0.82.0 + controller +0.115.0), using the operator's own `nas-media` share (read-only).** This closes the open Q1c item +from SPIKE-nas-verify-2026-07-11 §Q1. + +**Method + result:** +1. Pre-state: `nas-media` idle (host autofs trigger active-waiting; **the trigger WAS visible in the + guest's /proc/mounts**, having propagated when the automount was enabled while the guest ran); + apps healthy. +2. `pct reboot 9201` (the sudoers-granted verb). +3. Post-boot, **no access yet** → `pct exec 9201 -- grep nas-media /proc/mounts` = **NO_GUEST_TRIGGER** + (the host trigger is intact + active, but it did NOT re-propagate into the guest's fresh namespace). +4. In-guest `ls /mnt/felhom-drives/nas-media` → **an EMPTY directory** (`nobody:nogroup`, just `./..`) + and the access **did NOT trigger the host mount** (no nfs4 host-side afterward). This is exactly + the WRONG outcome the June spike flagged: a media app (jellyfin/*arr) restarting after a guest + reboot sees an **empty library**, not the NAS content — and an app that "cleans up" a + suddenly-empty library could destroy metadata. +5. Apps recovered healthy (controller/traefik/cloudflared/filebrowser Up); the controller's NAS list + still reports `nas-media` **health: idle** because it reads the HOST automount state — so the UI + looks fine while the guest cannot actually reach the share (a silent, misleading gap). + +**Root cause:** `mp8 /mnt/felhom-drives` is `shared` (host) → `shared,slave` (guest). Slave +propagation only carries mount events that happen AFTER the slave relationship is (re)established. +The host's autofs trigger for `nas-media` was mounted BEFORE the guest's post-reboot bind, so it is +not present in the guest's new namespace; and the agent has **no network-mount reassert on guest +reboot** (no `netmount`/reassert lines in the boot journal) — unlike the drive path's +`ReassertGuestBinds`. + +**FAIL protocol honored — NOTHING repaired live.** State left as found: the `nas-media` host +automount stays configured + active; the guest sees the empty bind dir until the share is re-added +(remove+add re-runs `EnsureNetworkMount`; the fresh `enable --now` propagates the trigger into the +running guest) or an agent-side reassert lands. **Follow-up task** (evidence = this section): +felhom-agent should re-propagate/re-establish network automounts into the guest after a guest +restart — mirror `ReassertGuestBinds` for the network-storage class (a `ReassertNetworkMounts` on +the guest-reboot path). Until then, document that a customer guest reboot requires re-touching NAS +shares, and consider having the controller's per-share health cross-check the GUEST-visible mount, +not only the host automount, so the UI stops showing idle/ok for a guest-unreachable share. + ## Teardown — verified `dsmsmb`/`dsmnfs` removed via the real remove endpoint (list shows only `nas-media`); felhom-pve: diff --git a/documentation/backlog/FOLLOWUP-nas-automount-guest-reboot-reassert.md b/documentation/backlog/FOLLOWUP-nas-automount-guest-reboot-reassert.md new file mode 100644 index 0000000..5038df6 --- /dev/null +++ b/documentation/backlog/FOLLOWUP-nas-automount-guest-reboot-reassert.md @@ -0,0 +1,49 @@ +# FOLLOW-UP — NAS automount trigger does not survive a guest reboot (agent reassert gap) + +**Opened:** 2026-07-11 · **Severity:** HIGH (data-safety-adjacent for media apps) · **Class:** +implementation (felhom-agent, likely a small felhom-controller health-surface follow-on). +**Evidence:** `documentation/audits/SPIKE-nas-dsm-2026-07-11.md` §Q1c (supervised live proof on the +demo, agent 0.82.0 + controller 0.115.0, operator GO). + +## The bug + +After a **customer guest reboot**, a configured NAS share's autofs trigger is NOT present in the +guest's fresh mount namespace, and an in-guest access **does not** trigger the host mount — the app +sees an **empty directory** at the NAS path instead of the share content. The host-side automount is +intact and `active (waiting)`; the controller's per-share health still reads `idle`/`ok` (it inspects +the HOST automount, not the guest-visible mount), so the UI looks healthy while the guest cannot +reach the share. + +## Why + +`mp8 /mnt/felhom-drives` is `shared` (host) → `shared,slave` (guest). Slave propagation only carries +mount events that occur AFTER the slave bind is (re)established. The host autofs trigger was mounted +BEFORE the guest's post-reboot bind, so it is absent from the guest's new namespace. The agent has no +network-mount reassert on the guest-reboot path (contrast the drive path's `ReassertGuestBinds`). + +## Impact + +A media app (jellyfin/*arr/immich) restarting with the guest sees an empty library; an app that +prunes/cleans a suddenly-empty library could destroy metadata. Silent because the operator UI shows +the share healthy. + +## Proposed fix + +1. **felhom-agent — `ReassertNetworkMounts` on guest reboot** (mirror `ReassertGuestBinds`): after a + guest (re)start, re-establish each configured network automount so a fresh `enable --now` (or an + explicit re-propagation) lands the trigger in the running guest's namespace. This is the real fix. +2. **felhom-controller — health cross-check (follow-on):** per-share health should also verify the + GUEST-visible mount, not only the host automount, so the UI stops reporting idle/ok for a + guest-unreachable share. + +## Interim workaround (manual, until #1 ships) + +Re-add the share (remove + add via the UI): `EnsureNetworkMount` re-runs and the fresh automount +enable propagates the trigger into the running guest. A guest reboot on a customer box currently +requires re-touching NAS shares. + +## Current demo state (left as-found per the FAIL protocol — NOT repaired live) + +The demo's `nas-media` share (192.168.0.180:/mnt/5_hdd/felhom-data) has its host automount active but +the guest sees the empty bind dir. No media app is bound to it (experimental). Re-add to restore, or +leave for the fix's live validation.