From d5729c2ab26e277aa9a2dc514df9df4edf286e46 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Sat, 3 Oct 2026 16:37:11 -0300 Subject: [PATCH] docs: clarify QEMU detach behavior and release content details --- AGENTS.md | 10 +++++++++- README.md | 15 +++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3b6589e..d551176 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -191,6 +191,12 @@ spin-machine attach --qmp /tmp/q.sock --target 0 --disk disk.raw # sda, in the spin-machine detach --qmp /tmp/q.sock --target 0 ``` +`detach` returns when QEMU reports the device free, but the guest notices the +ejection asynchronously: a check that greps for the node inside the guest runs +immediately after it can still see it, and saw it gone seconds later (measured +2026-10-03). Leave the guest a moment before treating a visible node as a +hot-unplug failure. + A one-off check needs no socket and no QMP: the shell's console is stdin/stdout, so a script on stdin is what the guest runs, and `poweroff -f` ends the boot. `--init /bin/sh` runs the script as PID 1 with nothing mounted, so it mounts `/proc` and @@ -204,7 +210,9 @@ printf '\n\n\n\n\n\n\n\n\n\nmount -t proc proc /proc\ncat /proc/cpuinfo | head - The leading blank lines are load-bearing: the guest's shell is not reading its console when QEMU starts feeding it, so the first bytes of the first line are lost, and a leading `sleep` would be the thing eaten — `mount` arrived as `unt` and `sleep` as -`ep` before the blanks absorbed it. +`ep` before the blanks absorbed it. How far the window reaches is host timing, not a +line count, so keep the number of blanks generous rather than tuning it; a blank +costs only a prompt. ## Taskfiles diff --git a/README.md b/README.md index 762b728..243541e 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,13 @@ One tarball: `LICENSE` and `NOTICE` sit at the root of the tarball. -`task build` writes that same tree into `_output/`, byte for byte the layout above, and -`machine.OpenRelease` reads either. `_output/bin/` holds one thing more: `spin-machine`, +`task build` writes that same tree into `_output/`, and `machine.OpenRelease` reads +either. What a release has beyond a build directory is what `hack/release` creates or +copies when it names one: `machine.env` and `SOURCES` it writes, and the QEMU and qboot +patches under `qemu/` it takes from this repository, not from the build. A tree without +a manifest is still a release for every purpose except being named — the fingerprint +decides whether checkpoints resume, and it is computed from the files, not from +`machine.env`. `_output/bin/` holds one thing more: `spin-machine`, which `task tools` builds for working in this repository and `hack/release` does not ship — a release is the machine, not the tool that boots it. There is one layout: nothing rearranges the files on the way out of a build, into a tarball or into a consumer. Let the three differ @@ -85,8 +90,10 @@ printf '\n\n\n\n\n\n\n\n\n\nmount -t proc proc /proc\necho hello from $(uname -r so the script mounts `/proc` itself — `poweroff` refuses without it. The leading blank lines are load-bearing: the guest's shell is not reading its console when QEMU starts feeding it, so the first bytes of the first line are lost, and the blanks absorb that -instead of the first real command. Nothing touches the base image — without `--disk`, -QEMU boots it under a throwaway overlay (`-snapshot`). +instead of the first real command. How far that window reaches is host timing, not a +line count — a quiet host may lose nothing — so treat the number of blanks as +insurance, not a figure to trim: a blank costs one prompt. Nothing touches the base +image — without `--disk`, QEMU boots it under a throwaway overlay (`-snapshot`). Read the output by grepping a marker, since the guest's prompt and the kernel's boot chatter share stdout: `| grep -a MARKER`. The exit status is QEMU's, so a script that