agent v0.36.6: shared parent make-private before make-shared (ROOT CAUSE of double-bind)

The self-bind inherited /'s shared peer group, so binds under /mnt/felhom-drives
propagated back and doubled. make-private (own group) before make-shared fixes it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 20:28:57 +02:00
parent 2da4c38773
commit 2b17419e60
3 changed files with 19 additions and 1 deletions
+8
View File
@@ -3,6 +3,14 @@
All notable changes to **felhom-agent** are recorded here. Update on every code All notable changes to **felhom-agent** are recorded here. Update on every code
change that gets pushed. change that gets pushed.
## v0.36.6 — shared parent gets its OWN peer group (make-private first) — ROOT CAUSE of double-bind (2026-06-15)
The shared-parent self-bind INHERITED the root mount`s shared peer group (`/mnt/felhom-drives` was
`shared:1` same as `/`), so every drive bind under it propagated back via the root peer and DOUBLED
(2 stacked binds per drive — the real cause behind v0.36.3-.5). EnsureSharedParent + the boot script now
`make-private` (detach from the root group) BEFORE `make-shared` (own group whose only slave is the
guest), so a drive bind propagates to the guest exactly once.
## v0.36.5 — AttachDrive normalizes to exactly one bind (2026-06-15) ## v0.36.5 — AttachDrive normalizes to exactly one bind (2026-06-15)
AttachDrive now COUNTS the binds at a stable path (countHostMounts) and normalizes to exactly one: it is AttachDrive now COUNTS the binds at a stable path (countHostMounts) and normalizes to exactly one: it is
+1 -1
View File
@@ -44,7 +44,7 @@ import (
// version is the agent version. Overridable at build time with // version is the agent version. Overridable at build time with
// -ldflags "-X main.version=<v>"; defaults to the in-repo CHANGELOG version. // -ldflags "-X main.version=<v>"; defaults to the in-repo CHANGELOG version.
var version = "0.36.5" var version = "0.36.6"
// runGuestHook is the PVE pre-start hook body (`felhom-agent guest-hook <vmid> <phase>`). On the // 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 // pre-start phase it creates placeholder dirs for any absent bind-mount source so the guest always boots
+10
View File
@@ -33,6 +33,10 @@ const sharedParentScript = `#!/bin/sh
set -e set -e
mkdir -p ` + StableParentDir + ` mkdir -p ` + StableParentDir + `
mountpoint -q ` + StableParentDir + ` || mount --bind ` + StableParentDir + ` ` + StableParentDir + ` mountpoint -q ` + StableParentDir + ` || mount --bind ` + StableParentDir + ` ` + StableParentDir + `
# make-PRIVATE first: the self-bind inherits the root mount's shared peer group, so without detaching it
# every drive bind under the parent would propagate back (and DOUBLE). Then make-shared = its OWN group,
# whose only slave is the guest's parent bind binds propagate to the guest exactly once.
mount --make-private ` + StableParentDir + `
mount --make-shared ` + StableParentDir + ` mount --make-shared ` + StableParentDir + `
` `
@@ -95,6 +99,12 @@ func (b *GuestBinder) EnsureSharedParent(ctx context.Context) error {
return fmt.Errorf("shared-parent: self-bind: %w", err) return fmt.Errorf("shared-parent: self-bind: %w", err)
} }
} }
// make-PRIVATE first to detach from the root mount's shared peer group (the self-bind inherits it),
// THEN make-shared so the parent owns its OWN group — otherwise binds under it propagate back via the
// root peer and DOUBLE (observed live as 2 stacked binds per drive).
if err := b.run(ctx, "mount", "--make-private", StableParentDir); err != nil {
return fmt.Errorf("shared-parent: make-private: %w", err)
}
if err := b.run(ctx, "mount", "--make-shared", StableParentDir); err != nil { if err := b.run(ctx, "mount", "--make-shared", StableParentDir); err != nil {
return fmt.Errorf("shared-parent: make-shared: %w", err) return fmt.Errorf("shared-parent: make-shared: %w", err)
} }