From 445db9a625bfd97d1d55ed7093206d2f95cc6d9c Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 22 Jun 2026 20:55:10 +0200 Subject: [PATCH] =?UTF-8?q?docs(controller):=20storage=20doc=20=E2=80=94?= =?UTF-8?q?=20v0.75.0=20drive-absent=20userdata=20MkdirAll=20gate=20(1c)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../controller/storage-monitoring-metrics.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/documentation/controller/storage-monitoring-metrics.md b/documentation/controller/storage-monitoring-metrics.md index 7ecc1fc..6a21538 100644 --- a/documentation/controller/storage-monitoring-metrics.md +++ b/documentation/controller/storage-monitoring-metrics.md @@ -56,6 +56,29 @@ Classification is the agent's; the controller **displays** it. The UI is driven `DiskInfo.Role`: `system`/`backup` get a lock badge and no destructive controls; `user-data` is customer-manageable (`client.go:235-237`). +### 1c. Drive-absent gate: `userdata` MkdirAll only on a live mountpoint (v0.75.0) + +The runtime drive gate `planDriveGates` (`web/intermediary.go`) stops apps when an external drive +(under `StableParentDir = /mnt/felhom-drives`) is absent and re-attaches them on return (system/local +paths excluded). **Two `MkdirAll`-into-`/userdata` sites are now consistent with that gate** so +they never write into an unmounted mountpoint (which would land app data on the guest **rootfs**, +shadowed when the drive returns): + +- **Deploy belt** — `stacks.ensureUserdataMounts` skips when `HDD_PATH` is an external root + (`!= sysDataPath`) that is **not** a live mountpoint (`Manager.isMountPoint`, defaults to + `system.IsMountPoint`). The app is held by `planDriveGates`. +- **FileBrowser sync** — `web.syncFileBrowserMounts` skips (and does not mount) a registered path under + `StableParentDir` that is not a live mountpoint (pure helper `web.skipFileBrowserPath`). + +The system/local path is **never** gated (it is legitimately not a mountpoint, so `EnsureUserdataDir` +must always run there). This eliminated the campaign-#2 `mkdir …/userdata: permission denied` + +transient `Created` flapping during a drive-absent window. + +> **Boot-time caveat (separate cause):** a `mkdir … permission denied` at daemon boot is NOT the belt — +> docker's boot-restore auto-starts drive-backed containers (`restart: unless-stopped`) before the agent +> mounts the drives; `planDriveGates` recovers them after mount convergence. Decision deferred (see the +> tests/ finding-1 diagnosis doc). + --- ## 2. Disk operations are delegated to the agent