Repository navigation
toyos-metal: a bench's disks are known by what they hold, not by their node - #1064
Conversation
…r node The loop wrote /dev/sda unless --device said otherwise, and admitted it by size, vendor, model and removable alone. A second SanDisk Ultra on the T14, holding a live ISO, answers all four, so an enumeration that put it at sda would have been wiped. Neither the node nor the USB port is stable: sticks move between ports. One rule, `located`, now finds every disk a bench lends: the one /dev/sd<letter> disk that answers the recorded identity *and* carries what its role is marked by, out of one `lsblk --pairs` listing. None or more than one is refused, naming every disk considered; nothing falls back to a node. - The boot stick before a flash carries a ToyOS image's table: the ESP and TOYOS-LOG at the rule's numbers, one slot table, one or two slots and ROOTs. After the boot it is the disk carrying this image's own TOYOS-LOG GUID, wherever it enumerated, and the mount and raw read follow it. - A scratch disk, which destructive tests may erase, carries exactly one partition, of a new type `Guid::TOYOS_SCRATCH`. The two marks exclude each other, so neither role is ever taken for the other, even between two sticks of one model. Adoption is explicit and names the node by hand. A boot stick with no ToyOS image yet is adopted with --device /dev/sd<letter> (identity checked, content check skipped); a capture with no record needs --device too. --adopt-scratch /dev/sd<letter> refuses a disk carrying a ToyOS image, wipes the named disk, writes the scratch table, finds it again through `located` and adds its identity to the record's new `scratch` list. The record's `Stick` becomes `Disk`, shared by both roles; it is shaped so a card behind an SD host controller can be recorded later, which is not built. The sudoers rule names the stick as /dev/sd[a-z] (`Mask::Sd`, filled with the located letter), since the letter is enumeration's. It still names no NVMe disk, and no partition of one outside the install area. Each bench's rule has to be reinstalled with --install-sudoers. The internal install is unaffected: it writes nvme0n1, which no USB or card reader takes, recognised by its layout and refused if removable. Boot entries are matched on the ESP's freshly drawn partition GUID, which the collision check keeps off every other disk. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
r1 checks at ba94b33
Bench commands, in order (the owner runs these)
On the AMD, use the same command with its
|
|
Still open for the metal run: the listing was taken without |
Review r1 — #1064 at ba94b33ArchitectureThe design is right. I traced the cases the brief asked about:
Size: roughly +300 production and +245 test lines in Negative controls m1–m5 are real mutations: m1 is
FindingsBLOCKER B1 —
BLOCKER B2 —
BLOCKER B3 — evidence — the end-to-end path has not run on metal.
SUGGESTION S1 —
SUGGESTION S2 —
SUGGESTION S3 — SUGGESTION S4 — SUGGESTION S5 — PR description (for the orchestrator). Two corrections:
SEND BACK |
… disk's table - The record's scratch list is gone: nothing read it. A scratch disk's identity is the one TOYOS_SCRATCH partition only adoption writes, and what carries it is erasable by definition. Adoption reads the mark back off the named disk instead of recording it. `Stick` keeps its name, since the boot stick is the one disk a record names. - A disk a refusal considered is named with its partitions' types, so the operator choosing --device between two sticks of one identity can see which one is which. - `NoStick`/`Sticks` are `Unlocated`/`Ambiguous`, since they say the same of a scratch disk. - Adoption checks `removable` directly rather than checking an identity against itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
r2 at 477c14c: review r1 response
Checks:
Bench commands (B3), run from this worktree at 477c14c:
|
…ule goes
The owner gave each bench's account passwordless sudo for everything
(/etc/sudoers.d/90-toyos-nopasswd). What existed only to grant and check a
narrow root is deleted:
- `--install-sudoers`, the password on a pipe, the staged rule and its
`visudo -c`/`install`, and `sudo -n -l` over every line;
- the rendered rule: the `jobs!` table, `Mask` and its fills and samples,
`Word` and its sudoers escaping, `user_word`;
- the `Word`, `PartitionIndex` and `Rule` refusals, and the dry run's asking
sudo whether the rule permits a line (a dry run now prints the lines);
- the fixed ESP and TOYOS-LOG numbers the rule named: a ToyOS table is one
ESP, one TOYOS-LOG and one slot table wherever they sit, and the mount, raw
read and boot entry take the image's own numbers;
- issues/the-sudoers-rendering-has-no-host-side-judge.md, and the host-tool
row for staging the rule.
`Job` now carries what it acts on (`Flash(Sd)`, `Mount { sd, part }`,
`Retag(Vec<(Owned, Guid)>)`, ...), and `Target::argv` is still the one place
a root line is written. Capture, the record-writing half of the old install,
is `--record /dev/sd<letter>`, an action of its own like `--adopt-scratch`.
With sudo allowing anything, disk selection (`located`) is what stops a
wrong-disk write, and it is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
r3 at a732584: the narrow sudo rule removed (owner's direction; the bench account has passwordless sudo) Deleted, all of it machinery for granting and checking narrow root:
Line counts:
Kept:
Checks and evidence:
Commands at a732584 (from this worktree):
|
Review r2 — #1064 at a732584ArchitectureDeleting the narrow-root machinery is the right response to the owner's direction. Its only purpose was to grant and check a restricted sudo, and with passwordless sudo none of it guards anything. What replaces it is smaller and easier to follow:
Disk selection ( Size: against main, production in The deletion is complete.
No wrong-disk guard was lost. Root is now unrestricted, so I traced every root command line back to where its disk comes from:
The partition numbers taken from the image are validated three times.
r1 findings.
Negative controls. m1–m5 were rerun at this tree, and each failed its named test (logs in Host CI. It ran at a732584: 103 steps, exit 0. Identifiers. No serial or bench partition GUID was added:
FindingsBLOCKER B1 —
SUGGESTION S1 —
SUGGESTION S2 — evidence —
PR description (for the orchestrator).
SEND BACK |
`admit` now requires one or two TOYOS-BOOT partitions beside the one or two
ROOTs, which is what `Carrying::Layout` asks of a stick. Before this, an
image with no BOOT partition would flash and boot, and every later run would
then refuse the stick as unlocated. `Roots` becomes `Slots { what, matched }`
and covers both partition kinds.
The home refusal's doc no longer mentions the deleted rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
r4 at af4060f: review r2 response
Checks and evidence:
|
Problem
The metal loop wrote
/dev/sdaunless--devicesaid otherwise, and its only admission check was size, vendor, model and removable. The T14 now has a second SanDisk Ultra of the same model, holding an EndeavourOS ISO, and it answers all four checks. If enumeration put that stick atsda, the loop would wipe it. Neither the node nor the USB port is stable: sticks move between ports.The owner has since given each bench's
toyosaccount passwordless sudo. Disk selection is therefore the only thing that stops a wrong-disk write, and the narrow-root machinery has no remaining purpose.Resulting behaviour
Prerequisite: the bench account has passwordless sudo. The loop checks this with
sudo -n /usr/bin/trueand refuses (Sudo) without it.One rule,
located(tests/metal/src/lib.rs), selects the boot stick. It reads onelsblk --pairslisting and selects the one/dev/sd<letter>disk that both answers the recorded identity and carries the boot stick's mark. If no disk matches, or more than one does, the loop refuses (Unlocated/Ambiguous) and names every disk it considered, with that disk's partition types. It never falls back to a node.admitholds every image to the same table, so a flashed stick is always found again)Guid::TOYOS_SCRATCH(51CC09F9-7442-435B-BC03-0FD8718B0FB5); the mark is the whole of its identity--adopt-scratchnow; destructive tests laterThe marks exclude each other. Automatic selection can therefore never take one stick of a model for another of the same model, in either role, and never takes a blank or foreign disk. That guarantee is
located's. It does not cover a disk named by hand with--device, or the window described under risks.Actions, each of its own (beside only
--host/--key, plus--dry-runfor adoption):--record /dev/sd<letter>records a machine with that disk as its boot stick, or checks the disk against an existing record. This is the record-writing half of the old--install-sudoers.--adopt-scratch /dev/sd<letter>refuses a disk that carries a ToyOS image or is not removable. Otherwise it wipes the disk, writes a one-partition scratch table, and reads the mark back.--device /dev/sd<letter>, on a boot, adopts a boot stick that has no ToyOS image yet. The identity is checked; the content check is skipped.Deleted, everything that existed only to grant narrow root:
--install-sudoers, the password pipe, the staged rule,visudo -c/install, andsudo -n -lover every line;jobs!table,Mask, its fills and samples,Wordand its sudoers escaping,user_word;Word,PartitionIndexandRulerefusals, and the dry run's per-line sudo question (a dry run now prints the lines);issues/the-sudoers-rendering-has-no-host-side-judge.md, and the host-tool row for staging the rule.Jobnow carries what it acts on (Flash(Sd),Mount { sd, part },Retag(Vec<(Owned, Guid)>), …), andTarget::argvis still the one place a root line is written.Size against main:
lib.rsproduction is 2569 → 2515 lines (−54 net, with disk selection and adoption added); tests are 1226 → 1262. The rule removal alone was −363 production and −167 test lines.Unchanged:
nvme0n1, which no USB or card reader takes; it is recognised by its layout and refused if removable.Checks and evidence
cargo test -p toyos-metal: 82 passed.admit's BOOT count removed.admit(the dry run reaches the ssh step).locatedandadoptableran against both benches' real unprivileged listings (lsblk 2.39.3):sdais selected on each; MBR types (0x0/0xef/0xc) carry no mark;mmcblk0andnvme0n1are excluded. This still holds: selection is unchanged apart fromLayoutdropping the fixed numbers, and the bench tables carry one of each part regardless.cargo run -- --ci host: see the latest comment.disk /dev/sda: … carrying a ToyOS imageandthe boot stick enumerated as /dev/sda, and listed everysudo -nline. Driver logs:driver/.acpi_server_death1/1.acpi_server_death1/1.--adopt-scratch /dev/sdb): both exit 0,/dev/sdaselected by content, nothing written.Unresolved risks
sgdisk --clearafterwipefson a real adoption. Only dry runs have run adoption so far. The PARTUUID follow after the boot is settled by both T14 runs.locatedandwipefs/dd, a disk replaced under the same letter would be written. This needs a hot-plug, or both sticks re-enumerating with swapped letters, within those seconds. Writing through/dev/disk/by-diskseq/N, which is never reused, would close it. The sudoers obstacle is gone with the rule, but no bench reading has confirmed theby-diskseqlinks yet, so this is recorded, not built.Target::argvis the one place a root line is written, andno_root_line_writes_the_benchs_own_partitionscovers the internal disk.🤖 Generated with Claude Code