fix: use parameterized Popen[bytes] for QEMU handle type annotation in guest_vsock.py - #292
Closed
markg-github with Copilot wants to merge 7 commits into
Closed
fix: use parameterized Popen[bytes] for QEMU handle type annotation in guest_vsock.py#292markg-github with Copilot wants to merge 7 commits into
markg-github with Copilot wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
execute_test assigned the loop's local `profile` onto `ctx.profile` at the top of every iteration. A callable step that replaces the profile — `dataclasses.replace` on a frozen VMProfile returns a new object, so mutating it in place is not possible — had that replacement silently overwritten before the next step ran. Any handler that reconfigures the guest for subsequent steps was therefore a no-op. Read the profile out of the context instead of writing the stale local back over it. Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
run_vm_launch_step reported "error" unconditionally when vm_launch raised VMLaunchError, ignoring the step's expected_result. That made it impossible to write a step that expects a launch to be refused: QEMU exiting immediately raises rather than returning ok=False, so a step declaring expected_result="exit_code:1" errored on exactly the outcome it was asserting. Evaluate expected_result against exit code 1 and the exception text, and record exit_code=1 so the result is self-describing. Steps that do not declare an expectation still default to "exit_code:0" and so still report error, leaving existing behavior unchanged. Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
execute_certification folded per-test results with
if tr.result != "pass":
overall = tr.result
which is last-writer-wins, not worst-wins. A run where the first test
errors and a later one merely fails reported the certification as
"fail", losing the error. The bug is latent today because both outcomes
are non-passing, but it silently downgrades severity in reports, and any
new non-passing state makes it worse.
Fold with an explicit severity ordering instead.
Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
vm_launch checks whether QEMU is still alive exactly once, at wait_ready_seconds, and never again. wait_for_guest then polls vsock until vsock_boot_timeout with no reference to the process at all. If QEMU exits after that single check, the harness spends the rest of the boot timeout pinging a VM that no longer exists. Measured on an EPYC 9654 with a deliberately corrupted ID block measurement, sampling the process at 1 Hz: +14.6s .. +17.2s QEMU alive +17.2s .. gone step ran +13.8s .. +195.9s QEMU lived 2.6s; the step took 182.1s. ~179s was spent waiting on a dead process. Policy violations are rejected at SNP_LAUNCH_START before guest memory is loaded, so QEMU dies inside the initial check and those launches already fail in ~2s — which is why only the measurement case was slow. Pass the process handle into wait_for_guest and abort as soon as it exits. The step drops from 182.1s to ~3s and the id-block suite from ~200s to ~21s. The diagnostics matter more than the speed. Firmware had already reported the exact cause: SNP_LAUNCH_FINISH ret=-5 fw_error=11 'Bad measurement' and the harness discarded it in favour of "Vsock agent on CID ... not ready after 180.0s". A negative test asserting exit_code:1 is satisfied by that timeout just as well as by a real rejection, so it would pass identically if the guest merely hung or if the ID block were ignored entirely. The failure message now carries QEMU's exit code and its stderr tail, so a rejected launch states the firmware's reason. process defaults to None, preserving the old behavior for any caller that does not supply it. Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
Co-authored-by: markg-github <13836240+markg-github@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix code based on review comment
fix: use parameterized Popen[bytes] for QEMU handle type annotation in guest_vsock.py
Aug 14, 2026
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
sev_verify/vm_profile.py:234
- The PR title/description state this is only a type-annotation fix in guest_vsock.py, but this hunk introduces functional behavior changes (passing the QEMU process into guest readiness checks and altering failure messaging/diagnostics). Please update the PR title/description to reflect the expanded scope (or split the behavioral changes into a separate PR) so reviewers and release notes aren’t misled.
# Passing the process lets the wait abort as soon as QEMU dies,
# instead of polling vsock until the boot timeout expires against
# a VM that no longer exists.
booted, boot_error = check_guest_ready(self, process=process)
sev_verify/vm_profile.py:244
- Reading QEMU stderr via
_read_guest_errors()loads the entire log file into memory (Path.read_bytes()) and only then truncates tomax_bytes. If QEMU emits a large stderr log, this can cause avoidable memory spikes and slow failure handling. Consider changing_read_guest_errors()to read only the tail (seek from end) instead of reading the whole file.
stderr_tail = _read_guest_errors(self.guest_error_log).strip()
if stderr_tail:
message = f"{message}\nQEMU stderr:\n{stderr_tail}"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
processparameter inwait_for_guestandcheck_guest_readywas annotated assubprocess.Popen | None, dropping the bytes type argument and diverging from the rest of the codebase (e.g.VMLaunchResult.process: subprocess.Popen[bytes] | None).Change
sev_verify/guest_vsock.py— Updated both occurrences tosubprocess.Popen[bytes] | None:Applies to
wait_for_guest(line 146) andcheck_guest_ready(line 184).