carlos / platform Public

tenant-iso-layout

Plan 4 (carlos layout migrate/revert), merged with main, the edge-unit openat2 blocker resolved, review F1-F3, re-check G1-G3, landing follow-ups 1-3, and the final check's aside-blocker fix

Branch tenant-iso-layout is isolated-exec-layout (plan 4, through its 2026-09-30 "final review") merged with main (last 530720c2), plus: the #126 blocker (02001067), F1-F3 (3a70d278), G1-G3 (3de902f6), the landing follow-ups (854cb4c8), and the final check's fix (468e4974). No history rewrite; CI green on every earlier tip. Ready to squash and land.

468e4974: a planted blocker at the aside directory is displaced, not a hold

/data/layout and /data/layout/aside are carlos 0700, writable by every flat tenant, so a tenant could plant a symlink at aside/ or a file at aside/<B> ahead of the pass; ensureAsideDir then failed inside DestinationCheck, which is a hold, and B (or every host) stayed down until an operator acted. ensureDirDisplacing (internal/layout/preflight.go) now renames a blocker that is not a real directory to a random, no-replace name under /data/layout (.<name>.blocker-<unix>-<hex>, visible to the operator) and makes the directory once more, at both levels; only the retry's failure is returned. Test: TestConvergeDisplacesABlockerAtTheAsideDirectory (a symlink at aside/; a file at aside/<host>), each ending in a migration with the quarantine in place and the one displaced blocker under /data/layout. Residual, same class, not changed: a symlink planted at /data/layout itself fails the journal write after the stop, which is a non-hold refusal (the fence lifts, the host runs flat until the next pass) that blocks every migration on the box until an operator removes it; it is loud in the log and in status.

854cb4c8: landing follow-ups

  1. Planted entries in a host's future directory are quarantined into /data/layout/aside/<host>/ (random .q- names, RENAME_NOREPLACE) in DestinationCheck and again in VerifyMoved, and the move goes on; logged and shown as a status note. The hold remains for nlink > 1 and a symlink at the instance directory.
  2. The hold is persisted as /data/layout/<host>.hold and restored at agent start by re-deriving it from the files (RestoreHolds); a marker whose reason is gone, or under a flat or absent intent, is dropped; unreadable holds. The marker is uid carlos's and so a hint to re-check, never the authority: a tenant that unlinks it gains one grace after one restart.
  3. The serial leg re-runs ten minutes after a held result as after a deferral.

Earlier commits

  • 02001067: carlos-edge.service drops RestrictSUIDSGID=; instancefs.SelfCheck is the nested gate's first question.
  • 3a70d278 (F1-F3): second names refused and re-verified before the row flips; awake deferral bounded (1h grace, 10 min retry, additive force); asides outside the instance tree; NoNewPrivileges= pinned on the other carlos-uid units.
  • 3de902f6 (G1-G3): a flat host stopped for a nested move and refused for a plantable reason stays fenced and down (held); mixed counts foreign/external rows; second-name refusals report the inode and find <data> -xdev -samefile.
  • 530720c2: second merge of main; status conflicts resolved by union; hostclaim/park/hostguard/hostfiles audited (foundations, no box-side caller; minting, fence, journal recovery and the hold untouched). For plan 1b: a --box-scoped intent does not cover a relocation target; /data/.installed and /data/hostguard are flat-tenant-writable until no flat tenant remains.

For operators

Reconcile's retire path fails closed on a fenced host. A fenced row whose reason begins "held down after a refused move to nested" is the hold: clear the named reason or revert the layout. A status note "migrated at <time>: kept aside <paths>" says what a move set aside under /data/layout/aside/<host>/; a .blocker- entry under /data/layout is something a tenant planted at the aside directory.

How tested

gofmt -l . clean, build, vet; internal/layout passes with the new tests; full make test and amadan CI run on 468e4974 (the previous tip was 64 packages ok locally plus the known environmental set, and CI-green). Under a TMPDIR inside $HOME the local gate fails only for environmental reasons reproduced on main (108-byte unix socket paths; the root package's ~/.carlos/config ancestor abort); GOFLAGS=-buildvcs=false needed locally (stray ~/.cache/tmp/.git).

Deliberately not done

Not merged; nothing run on any box; plan 5 unbuilt (force exposed there); new rows still minted flat (§8.6 step 5); squash left to whoever lands it.

Commits 0
Discussions 0 0 open
Tasks 0/0 done

Discussions

  • No discussions on this branch yet.

Tasks

  • No tasks yet.

Activity

  • No activity yet.