v0.57.0: re-assert a raw drive's guest-bind (ReassertGuestBinds mount-table fallback)

ReassertGuestBinds mapped durable-id->mount from Observe() only, so a raw enrolled
drive was never found and its in-guest bind wasn't re-asserted after reboot/re-mount
(drive showed "Leválasztva"). Augment the map from the mount table (raw /mnt/<name>
-> device fs-UUID via HostReader), skipping the /mnt/felhom-drives bind; Observe
failure no longer aborts. Completes v0.56.0's raw-drive durability.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 18:37:31 +02:00
parent e593fb277a
commit 67e2144f11
3 changed files with 39 additions and 7 deletions
+17 -4
View File
@@ -1,3 +1,19 @@
## v0.57.0 — re-assert a RAW drive's guest-bind (ReassertGuestBinds mount-table fallback) (2026-07-01)
Completes the raw-drive durability the v0.56.0 fix started. `ReassertGuestBinds` (the startup / drive-
returned reconcile that re-binds an enrolled drive's felhom-data under the shared parent so it's live in
the guest) built its durable-id→mount map from `Observe()` only — so a RAW enrolled drive was never found
("enrolled drive not present"), and its in-guest bind was not re-asserted after a reboot or a watchdog
re-mount (the drive would show "Leválasztva" in the controller).
- **`internal/localapi/disks.go` `ReassertGuestBinds`:** augment the durable-id→mount map from the mount
table — each raw `/mnt/<name>` mount → its device fs-UUID (`HostReader.Mounts`+`ResolveUUID`), skipping
the `/mnt/felhom-drives` bind (AttachDrive wants the raw path). Observe entries still win. Also: an
Observe failure is no longer fatal (fall through to the mount-table scan) so raw drives re-assert even
if the PVE view is momentarily unavailable.
- `go build/vet/test ./...` clean. With v0.56.0 (guest-bind now RECORDED for raw drives) this closes the
reboot/reconnect guest-bind durability gap for raw drives end-to-end.
## v0.56.0 — record intent/guest-bind for a RAW enrolled drive (durableIDForMount fallback) (2026-07-01)
Surfaced by the first live raw enrollment (Impl-2b): a raw drive is not a PVE storage, so
@@ -12,10 +28,7 @@ its guest-bind wasn't persisted.
intent keys stay consistent). Fixes intent recording (enroll/eject) AND guest-bind recording for raw
drives; the PVE-storage path is unchanged.
- Test `TestDurableIDForMount_RawFallback` (+ red-proof: Observe-only → ""). `go build/vet/test ./...` clean.
- **KNOWN residual (follow-up):** `ReassertGuestBinds` still builds its durable-id→mount map from Observe,
so a raw drive's guest-BIND is not re-asserted after a full host reboot (the drive still auto-mounts via
its `.mount` unit + is watchdog-tracked; only the in-guest bind re-assert is missed). Same Observe-
dependency class as the Impl-2a watchdog decoupling — to be extended to the guest-bind reconcile.
- **(Residual noted here fixed in v0.57.0:** `ReassertGuestBinds` raw-drive guest-bind re-assert.)
## v0.55.0 — raw-device discovery + registry-sourced drive tracking (Impl-2a) (2026-07-01)
+1 -1
View File
@@ -45,7 +45,7 @@ import (
// version is the agent version. Overridable at build time with
// -ldflags "-X main.version=<v>"; defaults to the in-repo CHANGELOG version.
var version = "0.56.0"
var version = "0.57.0"
// runGuestHook is the PVE pre-start hook body (`felhom-agent guest-hook <vmid> <phase>`). On the
// pre-start phase it creates placeholder dirs for any absent bind-mount source so the guest always boots
+21 -2
View File
@@ -852,8 +852,27 @@ func (s *Server) ReassertGuestBinds(ctx context.Context) {
}
}
} else {
s.logger.Warn("reconcile: storage view unavailable — skipping", "err", err)
return
// Observe failing is not fatal — a RAW enrolled drive wouldn't be in it anyway; fall through to
// the mount-table scan below so raw drives still get re-asserted.
s.logger.Warn("reconcile: storage view unavailable — using mount-table only", "err", err)
}
// Impl-2b: a RAW enrolled drive is NOT a PVE storage, so Observe misses it and its guest-bind would
// never be re-asserted (post-reboot/reconnect). Augment the map from the mount table: each raw
// /mnt/<name> mount → its device fs-UUID (uuid:<…>). Skip the /mnt/felhom-drives bind (AttachDrive
// wants the RAW mount path). Observe entries win (already set).
if s.host != nil {
if mounts, err := s.host.Mounts(); err == nil {
for _, m := range mounts {
if strings.HasPrefix(m.MountPoint, "/mnt/felhom-drives") {
continue // the bind, not the raw mount
}
if uuid, ok := s.host.ResolveUUID(m.Device); ok && uuid != "" {
if _, exists := mountByDurable["uuid:"+uuid]; !exists {
mountByDurable["uuid:"+uuid] = m.MountPoint
}
}
}
}
}
for vmid, ids := range s.guestBinds.Guests() {
for _, id := range ids {