Repository navigation
One block service and a driver per disk controller; input names each device; SCSI is its own crate (usbd step 10, PR 1 of 2) - #962
Conversation
…device; SCSI is its own crate Step 10's first half under the orchestrator's block ruling (recorded in the device-function track): a disk driver is a `drives` row receiving `disk`, reads its own table and offers its disks; diskserver is the block service alone, and hands each opened session's client connection and region to the offering driver, which answers the open and serves it. No block passes through the service. - toyos-blockring: `disk`, the driver/service frames; `Listed` names its disk. - lib/blockserve: a disk driver's side — its table, its link (it connects again and offers again when the service restarts), each disk's sessions over a `Device` it implements. - system/nvme: the NVMe driver, moved out of diskserver whole, one process per controller; it describes its claim once (the claim answers once). - diskserver: what is listed and admitted, by grant, across every offer; a listing and an open of what no disk offers wait until every boot-started driver has settled, bounded by DRIVER_BOUND (30 s) and naming the driver that did not. - supervisor: disk drivers start before the storage rows; the block service is told how many (`--drivers`) and which controllers got none (`--undriven`); the slot table is the one on the running ROOT's disk. - SDK: `Connection::received` and `into_owned`, to pass a connection on. - nvme_disk_boots requires each role served: it passed with all three absent while the driver's second describe was refused. toyos-input's records carry a u16 `source` on keys and pointers and a `gone` per source in place of `LOST`; the owners hold each connection's devices by source, at most `DEVICES` holding something, and drop a sender past it. ps2server's pointer is source 0 and its keyboard source 1. toyos-scsi is `lib/xhci/src/scsi.rs` moved, `no_std`, with no xHCI dependency; `Sense::of` reads only fixed format (SPC-4 table 27), refuses a short additional length, and carries a deferred error as one, which never reads as the current command's INVALID COMMAND OPERATION CODE. Closes scsi-is-decoded-inside-the-xhci-crate and sense-data-is-read-as-fixed-format-whatever-its-response-code-says. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Orchestrator, bench at 27b75c3 (one boot per bench, image hashes verified): T14 |
#962 names NVMe by QEMU's id in every image so no metal boot drives the bench's own disk, which holds the Ubuntu the metal loop reboots through. The record now says what a shipped image should drive (every NVMe by class), what keeps another system's disk unwritten under a class row (no grant reaches its partitions; read, not measured), and what closes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #962 at
|
…r by its badge Review round 1 of #962. - Nothing is routed until every disk driver started before the service has settled and every driver that ended has settled again. An open the grant admits on a disk already offered waits too, so a GUID a second disk also carries is refused on both rather than sent to whichever offered first, and a type-granted DATA reopen after its driver's restart waits for the offer rather than being refused NotGranted for a type no offer carries. - A driver is the badge the supervisor minted its `disk` connector with (its function's arrival, `toyos_blockring::disk::badge`), never the name it gives itself. The supervisor names each running disk driver by it (`--driver`), so a late driver never stands in for one that never spoke, and a second connection with a live badge is let go. - DRIVER_BOUND counts from the service's start or a settled driver's last end, so past it every answer is immediate; the client bounds its wait for a listing's or an open's answer by ANSWER_BOUND_NS, twice that. - The driver's link connects again in a bounded loop, not by recursion. - Comments that said what the code does not: MSG_GONE's payload, a `source`'s life, the listing's refusals. Sessions::busy is deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round 1 is answered in BLOCKER 1 (a type-granted reopen) and BLOCKER 2 (routing before settle): one rule.
BLOCKER 3 (driver identity): the approved approach.
BLOCKER 4 (the comments).
BLOCKER 5. Suggestions taken:
Checks at
Negative controls, each applied, run (
Evidence: https://github.com/ToyOSOrg/evidence/tree/ddc16d3eaf90590530f85e1ab82d3a8ed4f330d7/pr1-r1 The metal rows ran at |
Round 2 review of #962 at
|
Review round 2 of #962. drop_driver's doc still described identity by name. The code waits for the same badge, and only for a driver that had settled. DRIVER_BOUND's doc now says how the client's bound derives from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round 2 answered in
|
…bd-2 Each conflict was resolved for both intents: - toyos-untrusted is gone (main, 6699efb) and so is kernel/usbhid (this branch). The workspace keeps lib/usbhid, and the kernel depends on neither. - kernel/src/mm/dma.rs keeps main's comment, without copy_to, which only the deleted xHCI driver called. - SYS_PARTITION_* stays deleted (dispatch.rs), as do kernel/src/drivers/xhci and the-boot-volumes-server-holds-a-claim-that-writes.md. Main's edits to them are untrue now: the boot volume is a read-only session through usbd. - tests/toyos.rs takes main's stdio and launch rows with this branch's spare wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Orchestrator: re-review LAND apart from one stale comment, fixed at b21b38c (verified). Merged origin/main at 867d0e6 (the only real conflict: Cargo.toml workspace members after #963; #968's null stdio slots merge beside the drives-before-storage order and badges); |
#962 rewrote blockring's crate header; it keeps its text with `toyos::transport` for `toyos-transport`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#974 changed the kernel xHCI driver and the old usbd binary (system/usbd/src/hc.rs), both of which this branch deletes. They stay deleted, and their new limit and start calls are carried into the new usbd in the next commit. dispatch.rs takes #974's two DMA syscalls, and SYS_PARTITION_* stays deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR 1 of 2 for step 10 of
issues/the-kernel-is-small-interrupts-post-and-threads-wait.md(stage 4 ofissues/a-device-function-is-driven-from-its-arrival-to-its-end.md). It builds what usbd's whole xHCI (PR 2) stands on, and deletes what it supersedes. The kernel's xHCI driver, its USB storage,keyboard.rs/mouse.rs, the partition claims andOwedLockgo in PR 2.The block path: one service, a driver per disk controller
Ruling (orchestrator, on this assignment; recorded in the device-function track and step 10's text, replacing #901's
block@<location>,each,pci@and several block services).blockto its clients anddiskto disk drivers. Clients are unchanged; their grants are still supervisor-minted badges.drivesrow withreceives = ["disk"]. It reads its own GPT, offers each disk's partitions, and says when a disk is gone.MSG_OPENEDon the client's own connection and serves the session itself, so no block passes through the service.system/nvmeis adrivesrow, one process per controller. The supervisor starts disk drivers before the storage rows.What changed:
toyos-blockring::disk: the driver/service frames. A driver says its name, offers each disk (Offer, up to a GPT's 128 entries), settles once (OfferedorUnusable), and says when a disk is gone. The service hands over a session with two handles.wire::Listedgains the service's number for the partition's disk.lib/blockserve: a disk driver's side.table: the GPT read, moved from diskserver.link: offers and hand-overs. When the service ends, the link connects again at once (the supervisor keeps the port) and offers everything again. Sessions already handed over keep running.sessions: each disk's sessions over aDevicetrait the driver implements (has_room,submit_io,submit_flush,dma_map/dma_unmap). This is diskserver's old serving code with admission left to the service.region, moved from diskserver, since both ends map it.system/nvme: the NVMe driver moved whole, plus a main loop. The row keeps QEMU'spci:01:08:02/1b36:0010, as diskserver's row did, so a metal boot leaves the bench's own NVMe alone (issues/diskserver-claims-qemus-nvme-by-its-pci-id.md, whose citations move here).system/diskserver: the block service alone. Its decisions are pure functions over what drivers said (Known::listing,Known::open) and are host-tested.diskconnector: the function's arrival, which the kernel stamps on the connection. The supervisor names each disk driver it started by that badge (--driver). A driver's own name appears in log lines only.DRIVER_BOUND(30 s, a stated policy,wire::DRIVER_BOUND_NS), counted from the service's start or a settled driver's last end. Past it every answer is immediate, with what is known, and the line names the drivers that never settled.Unusablewhile a driver is missing, unusable or ended. It is refusedClaimRefusedwhile a disk controller got no driver (--undriven), andNotFoundonly otherwise. So "not yet" is never answered as "absent".wire::ANSWER_BOUND_NS(twice that), and answersUnansweredpast it.diskconnector with its arrival as the badge, and passes the block service--driver <arrival>for each running disk driver and--undriven <entry at PCI x>, at every start of it, restarts and swaps included.updateis granted is the one on the running ROOT's disk, now that a listing spans several disks.--claim-refusedpath instart()is gone.Connection::receivedandConnection::into_owned, so a connection end can be passed on. The kernel refuses each connection call on a handle of another type, so trust stops at what the sending protocol vouches for.Two consequential choices, mine to flag:
Unusablein that state, rather than reporting DATA absent. The alternative refuses every DATA lookup on a machine with any unusable controller.input: each device its ownsourceandgonetoyos-inputnow owns its wire records. They are no longertoyos_abitypes; the kernel streams' readers stay until PR 2 deletes the streams.u16source, pointers'sourcewidens tou16, andMSG_GONE{source}replacesLOST.MergeandPointerhold each connection's devices bysource. An entry holds a place only while its device holds something, up toDEVICES(16).Full), and the owners drop its connection.gonefor source 1.a_connections_end_releases_every_device_it_carried_and_a_gone_only_its_own_source. It is red withMerge's release on a connection's end removed, and red withgonereleasing its whole connection (below).toyos-scsilib/xhci/src/scsi.rsmoved whole tolib/scsi:no_std, no xHCI dependency, its host tests with it.Sense::ofnow reads only fixed format (SPC-4 §4.5.1, table 27: 0x70 current, 0x71 deferred).This closes
issues/scsi-is-decoded-inside-the-xhci-crate.mdandissues/sense-data-is-read-as-fixed-format-whatever-its-response-code-says.md. The kernel's one caller logs a refused sense and reads it asSense::NONE, the failing side.A defect a test missed, and the test now holding it
The first guest run of
nvme_disk_bootspassed with LOG, BOOT and DATA all absent. The driver calleddescribetwice, and a claim answers it exactly once. The test only checked a clean boot. It now requires each role served:Log serving /log — FAT32,Boot serving /boot — FAT32 read-only,Data serving ... — bcachefs,That double
describeis its negative control (below). In the green run every role mounts off sessions the driver serves, BOOT read-only.Checks
At head
27b75c355(one commit onorigin/main9b11608ab):cargo run -- --ci hostcargo run -- --build-onlycargo run -- --build-only --arch aarch64cargo test --test toyos-build -- --nocapture nvme_disk_boots iommu_virtio_platform acpi_mediated_access a_drives_row_holds_one_process_per_function usbd_drives_the_spareWhy each guest row:
nvme_disk_boots: the whole block path on an NVMe-only machine.iommu_virtio_platform: a refuseddrivesstart's line, which its no-unit arm reads.acpi_mediated_access: its shared string.a_drives_row_holds_one_process_per_functionandusbd_drives_the_spare: the supervisor's new order ofdrivesstarts.Negative controls, each a checked patch applied, run and restored in one script (
RESTORED_CLEAN=yesin every log):Merge::endreleases nothinga_connections_end_releases_…gonereleases its whole connectionsense_is_read_only_in_the_fixed_format…what_no_disk_offers_waits_for_every_driver_started_at_bootnvme_disk_boots(guest)"fileserver: Log serving /log — FAT32, " never reached the boot consoleThe controls ran on the uncommitted tree just before the commit. Later edits touched only the supervisor's
drive_whereand the--claim-refused→--undrivenrename, neither in a mutated line.Evidence (logs and patches): https://github.com/ToyOSOrg/evidence/tree/b167cf5d6e0ae745e9e1e34e2599112f29767e77/pr1 (the first
nvme_disk_bootsrun, roles absent, ispr1/nvme-disk-boots-first-run-roles-absent.log)Metal (staged, not run; the orchestrator runs every boot)
The judges read
/logoff the stick, which in this PR is still the kernel's. These boots therefore show that the new supervisor order and the block service with no disk drivers leave the log path whole on both benches.usbd_drives_the_type_c_controller(itstestcases-xhci-leaveboot).amdvi_translates_the_stick_controller(itstestcasesboot); its request needs the bench's--host.Run by the orchestrator at
27b75c355: the T14 row passed. The AMD row failed only on the recorded HDMI-audio DMA truncation (03:00.1). On both benches the log partition and the kernel log read back whole. Readbacks, with USB serials masked: https://github.com/ToyOSOrg/evidence/tree/00757415fbf704cec4092b98a0c4bc7413aee14e/pr1 (bench-t14/,bench-amd/).649e0cbe3changes onlyissues/diskserver-claims-qemus-nvme-by-its-pci-id.md, which records thenvmerow's QEMU id as a compromise with its owner and exit. No check above can change.Review round 1
Answered in
e07354fb1; checks and controls are in the reply on this PR (#962 (comment)). Evidence: https://github.com/ToyOSOrg/evidence/tree/ddc16d3eaf90590530f85e1ab82d3a8ed4f330d7/pr1-r1Risks
DRIVER_BOUND(30 s) is a policy, not a specification. It is spent only when a driver never settles, and then once.MAX_WAITING(16) wait; past that the acceptor goes unwatched and connects queue in the port./logand/homestay on kernel partition claims, which this PR leaves as they were.🤖 Generated with Claude Code