Repository navigation
Conversation
A fork's metadata is saved before the fork is brought to its target state. If Hypeman was killed in between, the fork stayed behind as an ordinary standby or paused instance: nothing marked it as unfinished, and a restore that was cut short kept its VMM, its memory and its vGPU. The caller had been disconnected without an answer and could not know the instance existed. A fork is now marked pending until its request succeeds, and pending forks are deleted at startup before the vGPU reconciler runs.
This branch has not been deployed
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.
Summary
A fork that was still being brought up when Hypeman was killed stayed behind as an ordinary instance, holding its VMM, its memory and its vGPU. A fork is now marked pending until its request succeeds, and Hypeman deletes the forks that are still marked when it starts.
Why it happened
A fork is made in two steps: its metadata is saved, then it is brought to the state the caller asked for. If the process dies in between, the fork stays wherever it got to. Nothing on disk says it is unfinished, so after the restart it looks like any other standby or paused instance. The caller was disconnected without a response and has no ID to delete.
For a QEMU guest with a vGPU this is expensive: a restore that was cut short keeps its VMM, the guest memory it had pinned and its virtual function until someone deletes the instance by hand.
What changes
StoredMetadata.ForkPendingis set when a fork's metadata is first saved, for instance forks and snapshot forks, and cleared once the fork has reached its target state. If clearing it fails, the fork request fails and the fork is cleaned up like any other failed fork, so a fork whose caller got a success is never still marked.RecoverInterruptedForksdeletes the forks that are still marked. It runs once at startup, before the API listens and before the vGPU reconciler starts. Like the network and device reconciliation next to it, it assumes that no other API process is using the data directory.Forks that completed are not touched, and a graceful restart still lets in-flight forks finish.
Testing
TestForkIsPendingOnlyUntilItsRequestSucceedscovers the mark through an instance fork, a snapshot fork, a fork left half-made and a snapshot of that fork.TestRecoverInterruptedForksDeletesOnlyPendingForkscovers the startup pass. Five mutants (mark never cleared for either kind of fork, mark kept in snapshots, recovery deleting everything, recovery deleting nothing) each fail one of them.No VMM, virtual function, TAP or guest directory was left in any case, and the next fork passed. Without the change the same kill at 1.0 s left two forks
Pausedand two inStandby, with two VMMs still holding two virtual functions (two runs).Not covered