v0.5.1: live-validation prep — fix unmounted-dir durable_id mis-id + watchdog UUID memory
Surfaced preparing the live USB validation on demo-felhom: - observe.go: an unmounted removable dir-storage no longer falls through to the ROOT fs for its backing device/UUID — durable_id was becoming uuid:<root-uuid> (a DR mis-id that would re-attach the wrong disk). Now derived only from the target's own mountpoint; unmounted → no device + stable store:<name> durable_id. Removed containingMountDevice. - watchdog.go: remember the fs-UUID observed while attached and backfill it onto the re-mount target, so re-mount works even if the known-set cache refreshed mid-drop (doc 03 §7 "sourced from the existing definition"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -147,12 +147,14 @@ func TestWatchdog_DebounceCoalescesFlaps(t *testing.T) {
|
||||
type fakeRemounter struct {
|
||||
mu sync.Mutex
|
||||
calls []string
|
||||
uuids []string
|
||||
}
|
||||
|
||||
func (r *fakeRemounter) Remount(_ context.Context, t KnownTarget) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.calls = append(r.calls, t.Name)
|
||||
r.uuids = append(r.uuids, t.UUID)
|
||||
}
|
||||
func (r *fakeRemounter) count() int {
|
||||
r.mu.Lock()
|
||||
@@ -208,6 +210,34 @@ func TestWatchdog_ReMountOnDeviceReturn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchdog_ReMountUsesRememberedUUID(t *testing.T) {
|
||||
// The re-mount key must survive the known-set cache losing the UUID mid-drop (an
|
||||
// unmounted dir-storage can't resolve its own UUID). The watchdog remembers the UUID
|
||||
// observed while attached and backfills it onto the re-mount target.
|
||||
known := &staticKnown{targets: []KnownTarget{{Name: "usb", MountBacked: true, UUID: "277a2179", MountPath: "/mnt/usb"}}}
|
||||
live := &mapLiveness{present: map[string]bool{"usb": true}, device: map[string]bool{"usb": true}}
|
||||
rem := &fakeRemounter{}
|
||||
w, _, _ := newTestWatchdog(known, live, 30*time.Second)
|
||||
w.remounter = rem
|
||||
w.spawn = func(f func()) { f() }
|
||||
ctx := context.Background()
|
||||
|
||||
w.tick(ctx) // baseline attached → remembers UUID 277a2179
|
||||
|
||||
// Cache refreshes during the drop and loses the UUID (the unmounted observe can't
|
||||
// resolve it); device still present, unmounted.
|
||||
known.targets = []KnownTarget{{Name: "usb", MountBacked: true, UUID: "", MountPath: "/mnt/usb"}}
|
||||
live.set("usb", false)
|
||||
w.tick(ctx)
|
||||
|
||||
if rem.count() != 1 {
|
||||
t.Fatalf("expected one re-mount, got %d", rem.count())
|
||||
}
|
||||
if rem.uuids[0] != "277a2179" {
|
||||
t.Fatalf("re-mount must use the remembered UUID, got %q", rem.uuids[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchdog_ReadErrorSkipsTick(t *testing.T) {
|
||||
known := &staticKnown{err: errors.New("proxmox blip")}
|
||||
live := &mapLiveness{present: map[string]bool{}}
|
||||
|
||||
Reference in New Issue
Block a user