Skip to main content

Module disktest

Module disktest 

Source
Expand description

The start-up disk test: what /data can actually do, said once on the screen.

 17:40:43  disktest /data  seq w 812 MB/s · r 1.9 GB/s · 4k sync 3100 ops/s  (1.6 s)

Three numbers, because they are the three a git server lives on: a sequential write (a pack arriving), a sequential read (a clone leaving), and 4 KiB overwrites each followed by fsync — the loose-object / ref update pattern, and the number that separates a FAT /data from an xfs one (an open item; the rig reads this row).

The write and the 4 KiB legs are plain std::fs. The READ leg measures the device, not the page cache: the file it just wrote is still cached, so the read reopens it with O_DIRECT (one 4 MiB buffer, 4 KiB-aligned, allocated once for the whole run) and streams it back off the disk. Where O_DIRECT is refused (tmpfs, some FUSE) the fallback is posix_fadvise(DONTNEED) to drop the cached pages, then a buffered read — and a result that is still implausible (over 5 GB/s) is said to be cached rather than reported as disk speed. On the appliance /data is the mounted xfs over the whole md raid0 set, so the numbers are the stripe’s, not one member disk’s. 256 MiB under <data>/.korp-disktest, deleted afterwards. Runs on its own thread the moment /data is known to be mounted and never delays serving: the row arrives when it arrives.

Never a panic, never a reason PID 1 is unhappy: too little free space is a skipped row, any I/O error is one WARN row, and both leave the file gone.

Structs§

AlignedBuf
A heap buffer whose start is aligned to align (a power of two): what O_DIRECT needs and Vec<u8> cannot promise. Allocated once per run.
Report
What the test measured.

Enums§

Outcome
How one run ended.
ReadHow
How the read leg got its bytes.

Constants§

CACHED_BPS
A read faster than this did not touch the disk.
DIR_NAME
The file’s directory under the data root; removed when the test is done.
ENV
The env seam: GUNNAR_DISKTEST=1 runs it on a developer box regardless of the PID-1 gate.
FILE_BYTES
What the test writes.
MIN_FREE_BYTES
Skip below this much free space: the test must never be the thing that fills the disk.
SYNC_WINDOW
How long the 4 KiB fsync loop runs.

Functions§

announce
Say the outcome as the ONE tracing line the log tap turns into the disktest row (dashboard::describe).
fmt_rate
812 MB/s / 1.9 GB/s (decimal units, as disks are sold).
last
The last outcome this process measured, or None if it has not finished one. A lookup, never a run: asking this question must never start a disk test, because the answer a caller wants is what the disk did at start-up.
read_back
Read path back sequentially into buf, past the page cache: O_DIRECT when try_direct and the filesystem takes it, else drop the cached pages (fadvise DONTNEED, after the caller’s fsync they are clean) and read buffered. Returns (bytes, seconds, how); the clock starts after the open so the number is the transfer, not the open.
record
Record the outcome of a run. Called once per run, beside announce.
run
Run the test under data_root with the production sizes.
run_sized
The test at any size — what the unit test calls with a few MiB.
should_skip
The skip rule, pure: free bytes available against MIN_FREE_BYTES (or need).
spawn
Start the test on its own thread when this is the appliance’s PID 1 (the dashboard’s gate) or ENV is set; say nothing otherwise. Returns whether it started. Serving never waits for it.