Name a filesystem by its UUID, its kernel id or its source, and keep nothing that has no name (hq ADR 0325 fifth review)

NFS and FUSE report a zero f_fsid, so another export or another FUSE mount at the
same point was named alike and kept without a warrant; xfs's f_fsid follows the
device number. A filesystem is now named by its UUID (its device matched in
/dev/disk/by-uuid), else a nonzero f_fsid, else mountinfo's source; one that cannot
be named is never kept or taken. Entries left on a filesystem not back within 30 days
are forgotten, said once, and the naming read is shared per mount.
This commit is contained in:
2026-10-12 19:14:42 +02:00
parent f00f9c2a2f
commit 46c16e18fe
6 changed files with 313 additions and 52 deletions
+22 -3
View File
@@ -75,6 +75,9 @@ func ReconcileKept(ctx context.Context) []string {
return said
}
// LeftFor is how long entries left on a filesystem are kept recorded, and said, while it is not back.
var LeftFor = 30 * 24 * time.Hour
// dropLeft takes out the entries the mesh left on a filesystem no longer at the folder, once that filesystem holds
// it again (§8): exactly those users' entries, nothing else. Left on the filesystem the folder is kept on now, they
// are that folder's own, and its walk takes out whichever are no longer wanted. Until then they stay recorded, and
@@ -95,7 +98,20 @@ func dropLeft(path string, f store.KeptFolder) []string {
var still []store.KeptLeft
var mine []store.KeptUser
for _, l := range f.Left {
same := l.Mount == f.Mount && (l.Placed == "" || l.Placed == f.Placed)
// On the folder's own filesystem now: the same name, or a name of an earlier build's form at the same
// mount point (which cannot be compared, and is never walked away).
same := l.Mount == f.Mount && (l.Placed == "" || l.Placed == f.Placed || l.Fs == "")
back := l.Mount == holding && (l.Placed == "" || l.Placed == holdingID)
if l.Since.IsZero() {
l.Since = time.Now().UTC()
}
if !same && !back && time.Since(l.Since) > LeftFor {
// **A filesystem not back within LeftFor is gone** (a disk replaced, a pool destroyed): what was left
// on it is forgotten, said once, rather than said unhealthy for ever.
said = append(said, fmt.Sprintf("the kept folder %s: the entries left on a filesystem not back for %s "+
"are forgotten: it is taken for gone", path, LeftFor))
continue
}
switch {
case f.Kept && same:
// Left on the filesystem the folder is kept on now: the folder's own entries.
@@ -104,7 +120,7 @@ func dropLeft(path string, f store.KeptFolder) []string {
// On the filesystem the folder is on now, not kept yet: never walked away; they are the folder's
// once it is kept there again.
still = append(still, l)
case l.Mount != holding || (l.Placed != "" && l.Placed != holdingID):
case !back:
still = append(still, l)
default:
drop := map[uint32]bool{}
@@ -253,6 +269,8 @@ func TakeFolder(ctx context.Context, d *declaration.Declaration, id, path, warra
return nil, "", errors.New(RootWords(v.why))
case v.kind == folderMake:
return nil, "", errors.New("the folder is not there; the next apply makes it, and asks nobody")
case v.unnamed:
return nil, "", errors.New(v.why + ", so a warrant could name no filesystem it was given for")
}
lock := folderLock(path)
if !lock.TryLock() {
@@ -283,7 +301,8 @@ func TakeFolder(ctx context.Context, d *declaration.Declaration, id, path, warra
}
f.Warrant, f.By, f.Mount, f.Want, f.IDs = warrant, by, v.mount, users, want.ids
// The warrant is for the filesystem it was carried out on (§8), named as a wait names it.
f.Placed, f.TakenOn = PlacedID(v.mount), PlacedID(v.mount)
f.Placed, f.Fs = placeOf(v.mount)
f.TakenOn = f.Placed
f.Act = &store.KeptAct{Act: "take", Warrant: warrant, By: by, State: "running", Started: started}
return true
})