Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
status: open
kind: defect
opened: 2026-10-09
---

# A file server waits 30 s on a block port nobody serves, and says nothing

An image whose `[boot]` `start` runs `fileserver` and no `diskserver`, on a
machine whose every partition is on a disk the kernel does not drive, stands
still for about thirty seconds after its three file servers are spawned, and
no line of the boot says who is waiting or on what.

Measured once, on `nvme_disk_keeps_log_and_home`'s machine with `diskserver`
taken out of `tests/testcases/system.toml`'s `start` (host load 52 by
`uptime`'s one-minute mean); the guest's own stamps:

```
[10.330 cpu0 kernel] spawn: /system/bin/fileserver pid=2 …
[10.362 cpu0 kernel] spawn: /system/bin/fileserver pid=3 …
[10.377 cpu0 kernel] spawn: /system/bin/fileserver pid=4 …
[40.513 cpu0 kernel] spawn: /system/bin/logkeeper pid=5 …
[40.526 cpu0 kernel] spawn: /system/bin/soundserver pid=6 …
```

No `fileserver:`, `supervisor:` or kernel line falls between the third and
the fourth, and none after it names a wait that ran out. The test went red
only on its own ceiling, `[qemu] Boot timed out waiting for ===READY===`.

Not read: which call waits, and whose bound the thirty seconds are.
`fileserver` reaches the port through `diskserver::list` and
`diskserver::Session::open` on `toyos_blockring::PORT`
(`userland/fileserver/src/main.rs`), and the supervisor starts `logkeeper`
only after the file servers.

Where `diskserver` runs and is refused its controller the same servers answer
at once and by name (`fileserver: Log serving /log — absent: …`), so the wait
is the unserved port's alone.

**Exit condition.** On that boot the file servers say, by role, that no block
service answers, and the boot reaches its ready marker without the wait: a
guest test of an image with `fileserver` and no `diskserver` on a
`Storage::Disk` profile requires the three lines and reds on the gap.

## Owner

`userland/fileserver` and `userland/supervisor`; unheld.
57 changes: 57 additions & 0 deletions issues/a-jobs-capture-holds-every-programs-lines-of-its-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
status: open
kind: tooling
opened: 2026-10-09
---

# A job's capture holds every program's lines of its window, so a test that compares one whole is red under load only

`TestResult::stdout` is filed by `push_user_half` (`tests/common/qemu.rs`),
which takes every console line between a job's `===TEST_START===` and its
end marker that is not the kernel's. Whose line it is is not asked: a server
still finishing its boot when the job starts says its late lines into the
job's capture, and the head `logkeeper` gave each, which names its program,
is cut off by `user_text` before the test sees it. A test that compares a
capture whole is green alone, green in one suite and red in the next, by how
late the host's load makes a server.

Evidence: the suite at `6b1a9322f` exited 1 with 37 of 38, `uptime`'s
one-minute mean 29.6 as it began and 47.9 as it ended.
`nvme_disk_keeps_log_and_home` compared `cat` of a kept file with `cat` of
its source, byte for byte, as the first two jobs after a reboot's ready
marker, and said they differed. The kept file's read was its ten lines. The
source's was six of `acpiserver`'s boot lines and then the same ten, value
for value; as the round-2 review of pull request #797 read them off the
run's log, the six run from `table 1 of 1 (DSDT) loaded` to
`\_S5 handed to the kernel`:

```
acpiserver: table 1 of 1 (DSDT) loaded
… four more of acpiserver's …
acpiserver: \_S5 handed to the kernel…
NAME="…"
… nine more lines of the file, each `UPPER_CASE="…"` …
```

The four between and the head each line carried on the console were not
read again for this file. The same test passed alone at that head (exit 0)
and in the suite at `a4033a5d2` (exit 0, 38 of 38, load 56.8 to 45.1). It is
not reproduced on demand: no late line was staged.

`9a0660e79` holds both reads to the lines of the file's own form: the
`assignments` closure in `nvme_disk_keeps_log_and_home` (`tests/toyos.rs`)
keeps a line whose key before `=` is upper case and `_` only, which leans on
no program saying such a line and no longer sees a line of another form
added to the kept file. That test was the tree's only whole-capture
comparison when this was filed: `run_test`'s other callers look for one
line, a phrase, or an exit code.

**Exit condition.** `TestResult` hands a job its own lines, told from every
other program's by the head each line arrives with, and the `assignments`
filter is deleted from `nvme_disk_keeps_log_and_home`, which then compares
the two reads whole. The clause on `tests/CLAUDE.md`'s two-pieces bullet
that states this fact goes in the same change.

## Owner

`tests/common/qemu.rs`; unheld.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
status: open
kind: defect
opened: 2026-10-09
---

# A machine that boots off NVMe looks 1500 ms for a USB boot disk

`gpt::probe_usb_disks` (`kernel/src/gpt.rs`) keeps asking the USB disks for
the partition firmware booted from until one carries it or
`xhci::PORT_SETTLE_CEILING`, 1500 ms, has passed. On a machine whose image is
on its NVMe disk no USB disk ever carries it, so every boot spends the whole
ceiling, on the boot CPU, before a task runs: paced by `PORT_POLL` in a
`spin_loop`, with nothing else scheduled.

Measured on `nvme_disk_keeps_log_and_home`'s machine, which has no USB
controller at all, on both of its boots: the kernel says `xHCI: no controller
on this machine, USB input unavailable` and, stamped 1501 ms later (`2.917`
and `4.418` on the test's first run), `usb-storage: 0 disk(s) on this machine
and none carries the boot partition after 1500 ms of looking`. Those boots
report `kernel to Boot: complete 1741 ms`. And on `bar_map_again`'s, a
`Headless` machine whose xHCI carries a keyboard and no disk: `usb-storage: 0
device(s)` at `6.126` and the same line at `7.628`.

The kernel already knows the outcome it waits for is impossible on a machine
with no xHCI controller, and it is told nothing about which bus the boot
partition's disk is on: the loader has the device path and hands over the
partition's GUID and extent alone.

**Exit condition.** A machine that boots off a disk this kernel does not
drive spends none of that ceiling: the line above is gone from
`nvme_disk_keeps_log_and_home`'s boots, or the wait is deleted with the
kernel's xHCI at step 10 of
`issues/the-kernel-is-small-interrupts-post-and-threads-wait.md`.

## Owner

`kernel/src/gpt.rs`; unheld.
12 changes: 12 additions & 0 deletions issues/a-machine-without-an-iommu-refuses-every-claim.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ there is no physical address for a grant to answer with. The signed driver's
claim is the path where `NotRemapped` and `Untranslated` both give way under
the ruling.

On such a machine whose image is on its NVMe disk, which
`Profile::HeadlessNoIommu` is, the refusal takes every volume but ROOT with
it: `diskserver` is refused the controller (`diskserver: NOT SERVING —
pci:1b36:0010 is on this machine and the kernel refused this service its
claim`), so the three file servers say `Data serving … — absent`, `Log serving
/log — absent` and `Boot serving /boot — absent`, and `logkeeper` says `no
/log on this machine - this boot's kernel log is on the console only`. Read off the no-unit arm of `iommu_virtio_platform`, which is
green with it: the arm asserts the refusal and reads no volume. Where the
image is on a USB stick the kernel drives, LOG and BOOT are served through
kernel partition claims, which need no unit, and DATA alone is absent; that
is read off the claim path and not run.

Exit, in both arms of `iommu_virtio_platform` (`tests/common/iommu.rs`):

- On `Profile::HeadlessNoIommu` a claim by a driver the image ships and signs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ kind: defect
opened: 2026-09-27
---

# An image on a disk blockd drives cannot write its slots
# An image on a disk diskserver drives cannot write its slots

The updater writes the idle slot through a partition claim
(`SYS_DEVICE_CLAIM` with `DeviceType::Partition`, granted by `system.toml`'s
`slots` row), and the kernel answers a claim only on the disks it drives —
the USB disks, until usbd drives the controller. The kernel drives no NVMe
controller: blockd does (`userland/blockd`). So a machine booted from an image
on its NVMe disk — `Profile::InternalDisk`, and the T14 once ToyOS is installed
on its internal disk — finds its slots nowhere a claim reaches, and an update
is refused at the claim.
`slots` row), and the kernel answers a claim only on the disks it drives: the
USB disks. The kernel drives no NVMe controller: `diskserver` does
(`userland/diskserver`). So a machine booted from an image on its NVMe disk —
every guest whose profile's storage is `Storage::Disk`
(`tests/common/qemu.rs`), and the T14 once ToyOS is installed on its internal
disk — finds its slots nowhere a claim reaches, and an update is refused at
the claim: `slot_grant` (`userland/supervisor/src/main.rs`) asks the inventory
for the ROOT partition the kernel holds, and the kernel lists no partition of
a disk it does not drive. Read off that function, and not run: the tree holds
no test that runs an update on any machine, which is why nothing fails.

Every update test boots off a USB stick, which is why nothing fails.
The launcher (`src/qemu.rs`) boots every machine it starts off a USB stick
for this reason: a machine that updates itself keeps its image where a claim
reaches its slots, and moves onto its NVMe disk only once this issue's exit
is met.

**Exit**: the slots of an image on a disk blockd drives are written through a
session init grants the updater on blockd's port, judged by an update test
that boots `Profile::InternalDisk`.
**Exit**: the slots of an image on a disk `diskserver` drives are written
through a session the supervisor grants the updater on `diskserver`'s port,
judged by an update test that boots a profile whose storage is
`Storage::Disk`.

## Owner

`userland/supervisor` and `userland/diskserver`; unheld.
Loading
Loading