Repository navigation
openvmm: pin refusing a FIFO snapshot artifact without waiting - #1424
Conversation
Pins cba21d109eeb99fbc573c79b2ed9f4754f734b25, the head of microsoft/openvmm#5004, one commit on ac3dc27a7, the head of microsoft/openvmm#5003, on which it stacks, which follows b4028c1aa, the head of feature/microvm/dev: - cba21d109 openvmm_helpers: refuse a FIFO artifact without waiting for a writer A FIFO without a writer in place of a snapshot's manifest.bin, state.bin, memory.bin, or paired scratch.img made restore wait forever before it validated anything (#1154). OpenVMM opened each artifact without following a final link and only then checked the type of the file that it opened, and a read-only open of a FIFO waits until a writer opens it. The pinned revision opens artifacts with O_NONBLOCK on Unix, so it refuses such a FIFO at once, with "<artifact> is not a regular file", before a restore can claim a resume snapshot, and then makes a regular file's descriptor blocking again. Windows is unchanged: its relative opens never wait for a file's type. The protocol vectors, the excerpts and contract versions that nvx-rs copies from OpenVMM, and its CPU profiles match the revision's. With 904a33c32, the same patch on d501e5066, on nvx-kvm-test and nvx-mshv-test (KVM and MSHV virtual machines), a FIFO in place of each artifact of a workload-start and an instance-checkpoint snapshot made the OpenVMM of release v0.1.0-dev.a0173e7b7d97, at 6cb6ba87c, wait in the kernel's wait_for_partner until it was killed 30 s later, while the fix's glibc and musl builds exited with status 1 and that error within 0.01 s; none of the 32 restores claimed the instance checkpoint. On Windows, an AF_UNIX socket, which is a reparse point, in place of each artifact made that release's openvmm.exe refuse it at once, so WHP had no such wait. The snapshot-tiers and scratch-snapshot scenarios passed with it on KVM, MSHV, and WHP. Tests: OpenVMM's openvmm_helpers tests pass at the pinned revision, 135 of 135 on Linux (glibc) and 127 of 127 on Windows, as they did at 904a33c32, 131 of 131 on Linux, glibc and musl, and 123 of 123 on Windows, where the two new ones failed without the change. The openvmm_vectors and openvmm_cpu_profiles comparisons pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The validation section of the snapshot artifact model said that Linux hosts open a snapshot's artifacts without following symbolic links. With the previous commit's pin, they open them without waiting too, so a FIFO in place of an artifact, which a blocking open would wait on until a writer opened it, is refused for its type, as any other file that is not a regular file is, instead of holding restore forever (#1154). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Maps NVX's new pin, cba21d109, the head of microsoft/openvmm#5004, at position 237, after position 236, ac3dc27a7, the head of microsoft/openvmm#5003, on which it stacks, which follows position 235, b4028c1aa, the head of feature/microvm/dev. The pin is 106 commits past the mapped tip, and positions 132-237 stay unassigned. Position 237 changes the artifact openers of the snapshot file system module that PR11's position 032 adds, with the path-based opener and the type check, and its position 033 extends with the directory-relative opener, through which PR12's position 035 restores: on Unix both now open with O_NONBLOCK, so that the type check refuses a FIFO without waiting for a writer, and then make a regular file's descriptor blocking again. It adds tests beside positions 032's and 035's, and extends the restore paragraph that PR12's position 036 adds to the snapshot format guide. Replaying it on upstream main conflicts in all three of its files, since upstream main lacks the file system module of position 032, the directory-relative restore of position 035, and that paragraph, so it follows PR11, PR12, and PR19 upstream. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Snapshot-tiers, scratch-snapshot, and end-to-end FIFO acceptance checks remain outstanding for OpenVMM pin cba21d109 on KVM, MSHV, and WHP, requiring runtime evidence before landing.
No open issues 🎉
What changed in this PR
This PR integrates OpenVMM’s fix for #1154 so Linux snapshot restores reject writerless FIFO artifacts instead of hanging. The reviewed documentation describes the behavior and records the new pin’s upstream dependencies.
Changes:
- Document prompt rejection of FIFO snapshot artifacts while preserving existing descriptor and identity checks.
- Update the OpenVMM roadmap to pin
cba21d109at position 237 and map its changes and upstream prerequisites.
| File | Description |
|---|---|
doc/openvmm-upstream-roadmap.md |
Records the new pin, chain counts, and upstream mapping for FIFO rejection. |
doc/design/5.4-snapshot-artifact-and-attachment-model.md |
Explains that Linux refuses FIFO artifacts without waiting for a writer. |
Review effort: Balanced
|
On the overview's note that the
The Validation section now records these results. |
Fixes #1154
What and why
On Linux, a FIFO without a writer in place of a snapshot's
manifest.bin,state.bin,memory.bin, or pairedscratch.imgmade a restore waitforever, before it validated anything or claimed a resume snapshot: OpenVMM's
--restore-snapshot, and a management-RPCCreateVmwith arestore_path,never returned.
Root cause: OpenVMM opens each artifact without following a final link and
then checks the type of the file that it opened.
OpenedSnapshotDirectory::open_regular_file(
openvmm_helpers/src/snapshot/fs.rs) opened it withopenat(O_RDONLY | O_CLOEXEC | O_NOFOLLOW), and a read-only open of a FIFOwaits, in the kernel's
wait_for_partner, until a writer opens the FIFO, sothe open never returned to the check. The path-based
open_regular_file_impl,which the claimed scratch link and
write_snapshot's memory backing file use,waited the same way.
microsoft/openvmm#5004,
openvmm_helpers: refuse a FIFO artifact without waiting for a writer, opens artifacts withO_NONBLOCKin both Unix openers,so that the open of a FIFO returns at once and the existing check refuses it
like any other file that is not a regular file: "
<artifact>is not a regularfile". A new
accept_opened_regular_file, which both openers call, makes thatcheck and then clears
O_NONBLOCKon a regular file's descriptor, since thehandles outlive validation: as restore guards, as the descriptor that the VM
worker maps as RAM, and as the scratch source. Windows needs no change: NTFS
holds no FIFOs, and the AF_UNIX sockets and WSL FIFOs that it can hold are
reparse points, which the relative open opens as themselves, without waiting,
and refuses. OpenVMM's snapshot format guide says that Linux opens artifacts
with
O_NONBLOCK.Commits:
openvmm: pin refusing a FIFO snapshot artifact without waitingmoves thegitlink, and nothing else, from
ac3dc27a7, the head of[DO NOT REVIEW] openvmm_helpers: compute memory-expansion ranges without overflow openvmm#5003, which openvmm: pin overflow-free memory-expansion ranges #1423 pins, to
cba21d109eeb99fbc573c79b2ed9f4754f734b25, the head of[DO NOT REVIEW] openvmm_helpers: refuse a FIFO artifact without waiting for a writer openvmm#5004, one commit on
ac3dc27a7. The vectors, sourceexcerpts, contract versions, and CPU profiles that nvx-rs copies from
OpenVMM match the revision's.
doc: say that restore refuses a FIFO artifact without waitingupdates thevalidation section of
5.4 Snapshot Artifact and Attachment Model:
Linux hosts open a snapshot's artifacts without following symbolic links and
without waiting, so a FIFO is refused for its type.
doc: map the FIFO artifact refusal in the OpenVMM roadmapmaps position237, unassigned, 106 commits past the mapped tip, with the mapped work that
it changes: the artifact openers of the snapshot file system module that
PR11's positions 032 and 033 add, through which PR12's position 035
restores, and the restore paragraph that PR12's position 036 adds to the
snapshot format guide. It conflicts with upstream main in all three of its
files, so it follows PR11, PR12, and PR19 upstream.
Decisions:
O_NONBLOCKafter the type check, rather than leave itset as the issue proposed: the handles outlive validation, and the flag is
not inert for every consumer of a regular file (io_uring returns
EAGAINfora file without
FMODE_NOWAITrather than punting, and leases and mandatorylocks honor it). It costs one
fcntlpair per artifact.accept_opened_regular_filelets openvmm: nonregular paired scratch is accepted before a resume generation can be consumed #1157, which this issue blocks,check the type of
scratch.imgbefore the claim, through the same openers,without a blocking open, and the test helper
refusal_of_writerless_fifoisvisible to the snapshot module's tests for openvmm: nonregular paired scratch is accepted before a resume generation can be consumed #1157's.
O_DIRECTORYfails withENOTDIRbefore anyFIFO wait.
doc:commit of its own, as openvmm: pin the refusal of earlier snapshot formats by their version #1417's was,and the pin commit changes only the gitlink.
cba21d109is the commit that the validation before this restack tested,904a33c32ond501e5066, rebased ontoac3dc27a7:git range-diffshowsthe patch identical, and of its three files, the commits between change only
fs.rs, where position 234 changes the publication's rename.Stack
This is layer 2 of a stack of four pull requests, one for each of four issues,
each based on the branch of the one below it; their OpenVMM pull requests
stacked the same way. Layer 1 has landed, so this pull request now targets
dev, and microsoft/openvmm#5004 and microsoft/openvmm#5005 now targetfeature/microvm/dev.dev)feature/microvm/dev), landedac3dc27a7, position 236dev)feature/microvm/dev)cba21d109, position 237agents/issue-1154-fifo-artifact)feature/microvm/dev)46bfe02ed, position 238agents/issue-1138-input-gate-lock)46bfe02ed, layer 3'sLanding order, bottom first, one layer at a time; each OpenVMM pull request
lands before its NVX pull request merges:
feature/microvm/devtoac3dc27a738808d38e1148d3caefc5e89111ee32, since OpenVMM's merge buttonsquashes and would leave the pin off the branch. Then merge openvmm: pin overflow-free memory-expansion ranges #1423
through the merge queue; GitHub deletes its branch and retargets this pull
request to
dev.feature/microvm/dev(
gh pr edit 5004 --repo microsoft/openvmm --base feature/microvm/dev),fast-forward
feature/microvm/devtocba21d109eeb99fbc573c79b2ed9f4754f734b25, and merge this pull request.feature/microvm/devto46bfe02ed65697e858f66ce55eb60831b3ac3461, andmerge openvmm: pin input gating that keeps devices open to the vCPUs #1425.
Validation
Before this restack, with OpenVMM
904a33c32(the same patch ond501e5066)for "after":
6cb6ba87c): 8 of 8 wait inwait_for_partneruntil killed<artifact>is not a regular file"; none claims the checkpointmanifest.binartifact_opens_refuse_a_writerless_fifo_without_waiting,restore_refuses_a_writerless_fifo_artifact_without_waitingO_NONBLOCKflags, both fail after their 10 s boundopenvmm_helperstest-microvm --scenario snapshot-tiers --scenario scratch-snapshot --processors 1On nvx-kvm-test, removing only the directory-relative flag failed both new
tests; only the path-based flag, the opener test; and only the clearing of
O_NONBLOCK, the opener test's flag assertion. The nvx-rs vector and CPUprofile comparisons passed against
904a33c32.Rerun for this restack, at OpenVMM
cba21d109and this head:cargo nextest run --profile agent -p openvmm_helpers,127 passed on Windows, where the new tests do not build, and 135 on Linux
(nvx-kvm-test, glibc), both new tests among them;
cargo clippy --all-targetsandcargo doc --no-depsforopenvmm_helpers, andcargo check --all-targetson Linux, without warnings;cargo xtask fmtatthe stack's top OpenVMM head,
46bfe02ed, clean.python scripts/nvx.py verify;python scripts/local_gates.py --base <layer 1's head> --only test-changes markdown-links test-layout openvmm-vectors openvmm-cpu-profiles --run, all passed, with no change to anexisting test and the 4 vector and 1 CPU-profile comparisons passing against
cba21d109;python scripts/openvmm_pin.py check-roadmap --worktreeandcheck-branch --topic --target <layer 1's head>, passed. After the rebase,git range-diffshows this layer's three commits unchanged from those thatthe gates tested, on a base with the same tree, and this head's tree is the
one that they tested;
python scripts/rebase_check.py verifylists onlylayer 1's commits, now in the base, as dropped.
At the exact pin,
cba21d109, and this head,15a8a836c, for marking ready:manifest.bin,state.bin,memory.bin, andscratch.imgof a workload-start and an instance-checkpoint snapshot, captured with thesnapshot-tiersscenario's commands, then its restore command bounded at 30 s; OpenVMM built in a worktree of this head withbuild-openvmm, guest artifacts from this head's CI runcheck-openvmm-cirequires passed;unit tests [x64-linux]ran 6414 tests, both new FIFO tests among them, all passedsnapshot-tiersandscratch-snapshotpassed on each backend with OpenVMM built at the pin, as didOpenVMM CI of the pinned revision, NVX CLI on Linux and Windows, the rest of the microVM matrix, the performance regression gate, andRequired status checkWindows needs no new end-to-end case: the pin adds
O_NONBLOCKonly to theUnix openers, and the Windows type check that refused the socket, reparse
point, and directory cases above is unchanged. The merge group tests this
pull request again, merged into the latest
dev.