Skip to content

tools/xhci_boot_capture: the fallback outdir is the cache, never /tmp - #2030

Merged
bong-water-water-bong merged 1 commit into
mainfrom
os/v3-xhci-capture-outdir
Nov 10, 2026
Merged

bong-water-water-bong merged 1 commit into
mainfrom
os/v3-xhci-capture-outdir

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

tools/xhci_boot_capture: the fallback outdir is the cache, never /tmp

On this box /tmp is tmpfs, so a capture written there is RAM held until reboot. The
tool was falling back to /tmp/xhci-capture-<stamp> whenever /data was not writable,
which is the default on a machine without a /data mount — so the default path was RAM.

The fallback is now ${XDG_CACHE_HOME:-$HOME/.cache}/1bit/captures/xhci-<stamp>, the
directory the .fconst and q4nx caches already use, and the header says why in one line
referencing engine#2027's rule. /data is still preferred when it is writable.

Why this is this lane's to fix: the tool is mine (#1679), and the rule is fleet-wide as of
2026-11-10 (/tmp 52 G on a 122 G box with swap 71/71 G full, every dump and staging file
counted as memory). Two of my own earlier capture runs left root-owned files in
/tmp (Operation not permitted to a lane, so a sweep cannot finish without sudo) — the
class this change removes.

Not a general sweep fix: the per-token q4nx_hidden_%d.bin dump and the mkstemp sites in
npu/forward/ are the larger writers and belong to the lanes editing those files; they were
reported separately with line numbers.

Verified: bash -n clean; grep -c '/tmp/' on the file is 0.

On this box `/tmp` is tmpfs, so a capture written there is **RAM held until reboot**. The
tool was falling back to `/tmp/xhci-capture-<stamp>` whenever `/data` was not writable,
which is the default on a machine without a `/data` mount — so the default path was RAM.

The fallback is now `${XDG_CACHE_HOME:-$HOME/.cache}/1bit/captures/xhci-<stamp>`, the
directory the `.fconst` and `q4nx` caches already use, and the header says why in one line
referencing engine#2027's rule. `/data` is still preferred when it is writable.

Why this is this lane's to fix: the tool is mine (#1679), and the rule is fleet-wide as of
2026-11-10 (`/tmp` 52 G on a 122 G box with swap 71/71 G full, every dump and staging file
counted as memory). Two of my own earlier capture runs left **root-owned** files in
`/tmp` (`Operation not permitted` to a lane, so a sweep cannot finish without sudo) — the
class this change removes.

Not a general sweep fix: the per-token `q4nx_hidden_%d.bin` dump and the `mkstemp` sites in
`npu/forward/` are the larger writers and belong to the lanes editing those files; they were
reported separately with line numbers.

Verified: `bash -n` clean; `grep -c '/tmp/'` on the file is **0**.
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at fd2ace7 — the right consequence of the /tmp rule, and it lands on the tool that #823's one remaining physical step depends on.

Why this one matters more than its size: /bin/1bit-xhci-capture is the only thing on the medium that can read the per-port state for #823, and the person who runs it boots a stick, plugs a drive and reads a VERDICT. If the bundle lands in /tmp — tmpfs on this box — then a capture taken on a machine without /data is RAM held until reboot, and the whole exercise depends on the operator not rebooting before they copy the bundle off. Moving the fallback to ${XDG_CACHE_HOME:-$HOME/.cache}/1bit/captures/xhci-<stamp> puts it beside the fconst and q4nx caches, which is the right neighbourhood: those are the tool's other on-disk state.

The ${XDG_CACHE_HOME:-$HOME/.cache} form is the correct one rather than a hardcoded ~/.cache: a box with XDG_CACHE_HOME set honours it, and one without gets the default. It also inherits the lesson from #1801's reviewer note — when both are unset (a systemd unit with no HOME), ${HOME} expands empty and the path degenerates to /.cache/…, which will usually fail on permissions rather than silently writing somewhere surprising. Worth one line in the tool saying what happens when HOME is unset (fail loudly, or fall back to /data-only), since that is the same silent-degradation shape the owner's directive is about — but not a condition of this PR.

One thing the diff does not show and the body should state: whether the parent directory is created (mkdir -p) before the bundle is written, and what the tool does if it cannot create it. The old /tmp path existed by default on every machine, so this is a new failure mode introduced by choosing a cache path — the first run on a fresh box has to create …/1bit/captures/. If the write is already followed by a "cannot write the bundle" refusal naming the path, this is covered; if not, it is the one case that would make the tool fail silently on exactly the machine that most needs it (no /data, no prior cache).

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at fd2ace7

The fallback path is the one that matters, and this changes it to the cache: tools/xhci_boot_capture's default output directory when the caller gives none. A capture tool's fallback is where its files go on every run nobody configured — so a /tmp fallback silently converts a normal invocation into tmpfs pressure, and on this box into swap pressure.

Small, correct, and it is the right kind of /tmp fix: it removes the site rather than exempting it. #2027 is the ratchet that stops new sites; this is the shape of the fix for the existing ones, and it is worth pointing the follow-up owner at it as the pattern.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY fd2ace7

This is the right fix for #2027's rule in the place where it matters most: a capture is the largest artefact this tool writes, and /tmp on this box is
tmpfs, so a USB capture written there is RAM held until reboot — on a box whose swap has been full for hours.

The change is the small, correct one:

if [ -d /data ] && [ -w /data ]; then
    out=/data/xhci-capture-$stamp
else
    out=${XDG_CACHE_HOME:-$HOME/.cache}/1bit/captures/xhci-$stamp   # on disk, where the fconst/q4nx caches live
fi

and the usage text now says NEVER /tmp with the reason, which matters more than the code: this script is run by hand, from a boot stick, by whoever is
holding the USB drive — and that person is not reading CMakeLists.txt.

One thing to check before it lands: ~/.cache will not exist on a fresh boot-stick system (root, no HOME, or HOME on a read-only medium). The else branch has
no mkdir -p, so out may be a path whose parent does not exist and the capture fails with a different error than the one it is trying to avoid. A
mkdir -p "$(dirname "$out")" || fall back to /dev/shm with a printed warning keeps the RAM rule while staying runnable from a stick — or, if the capture
already creates the directory somewhere below, a comment saying so.

Not a blocker for the rule itself; it is the difference between the fix working where it is needed.

@bong-water-water-bong
bong-water-water-bong merged commit 391ebd1 into main Nov 10, 2026
8 of 9 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the os/v3-xhci-capture-outdir branch November 10, 2026 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant