docs(REPORT): FileBrowser was not recovered after host reboot — two gaps

Found FileBrowser down after the host-reboot drills (my 'all recovered' claim only
checked the 8 felhom-flash apps). Two distinct gaps:
(A) agent-side: felhom-usb did not re-mount after the host-reboot device-letter
    swap (mount unit inactive; agent reports present drive as durable-id absent) —
    a felhom-agent bug, out of controller scope.
(B) controller-side: FileBrowser is base-infra (no HDD_PATH) so processGuestBootChange
    skips it; its SyncFileBrowserMounts runs once at startup, racing the bind, not
    retried. Recommended fix: call SyncFileBrowserMounts after the live-bind poll.

Recovered FileBrowser live (started felhom-usb mount unit -> agent bound it ->
restarted controller -> FB Up healthy). felhom-usb userdata was intact, just hidden
behind the unmounted placeholder. Corrected the host-reboot trust caveat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 16:56:01 +02:00
parent 6b9603ed26
commit 14f200c9a1
+32
View File
@@ -105,8 +105,40 @@ drive gate + boot recovery silently died, on **both** reboot paths. (My v0.70.0
preserved `local_api`.) `ensureLocalAPI` re-merges `local_api` on every startup, closing the regression
permanently.
## Follow-up — FileBrowser was NOT recovered (host-reboot recovery was incomplete)
After the host-reboot drills, **FileBrowser was found down** (`state=created, exit=128, RestartCount=0`,
`mkdir /mnt/felhom-drives/felhom-usb/userdata: permission denied`). My "all recovered" claim above was
**incomplete**: it only checked the 8 app stacks, which are all on **felhom-flash**. Two distinct gaps:
- **(A) Agent-side — felhom-usb did not re-mount after the host reboot.** The host reboot swapped the USB
device letters (`sdb↔sdc`); felhom-flash re-mounted (now `sdc1`), but **felhom-usb (`sdb1`,
`da9e7089`) did not** — its systemd mount unit (`mnt-felhom\x2dusb.mount`) existed and the by-uuid
symlink resolved, yet the unit was **not active**, so the agent reported the (present) drive as
`enrolled drive not present (durable-id absent)` every reconcile and never bound it. So the
host-reboot recovery covered felhom-flash apps but left **felhom-usb entirely unmounted** — a
**felhom-agent** bug (it must re-activate/retry the mount once the USB enumerates after a host reboot,
not give up on "absent"). **Out of the controller's scope.**
- **(B) Controller-side — FileBrowser is not covered by the boot-recovery.** FileBrowser binds all three
drives' `userdata` but is **base-infra (no `HDD_PATH`)**, so `processGuestBootChange`/`shouldRecreateOnBoot`
skip it. Its recovery relies on `SyncFileBrowserMounts`, which runs once at controller startup — racing
the bind exactly like the app boot-race — and is not retried after the binds go live. So FileBrowser is
stranded by a guest/host reboot independently of (A). **Recommended fix (separate, small): have
`processGuestBootChange` call `SyncFileBrowserMounts` after the live-bind poll confirms the binds, so
FileBrowser converges with the apps.** Not done here (it's a code change + version bump; flagged for a
follow-up slice). Note it would only fully help once (A) is fixed — on this reboot felhom-usb was absent,
so FB could not bind it regardless.
**Recovered live (non-destructive):** started the felhom-usb mount unit (`systemctl start /mnt/felhom-usb`)
→ agent bound it into the guest → restarted the controller → `SyncFileBrowserMounts` synced 3 storage
paths → **FileBrowser `Up (healthy)`**. felhom-usb's real `userdata` (`drwxrwsr-x root:1000`) was intact
all along — only hidden behind the unmounted placeholder.
## Notes
- The Komga healthcheck quirk is pre-existing and out of scope.
- The `local_api`-merge gap affected the **whole drive gate** on this golden, not just boot recovery —
`ensureLocalAPI` restores the agent path generally.
- **Trust caveat:** the reboot drills prove the **felhom-flash app** recovery path (guest ×2, host ×2).
They do **not** yet prove a clean felhom-usb host-reboot remount (gap A) or FileBrowser auto-recovery
(gap B) — both are now documented and recommended for follow-up.