vmm: migration asynchronization - #8021
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
eddec32 to
201577b
Compare
This comment was marked as outdated.
This comment was marked as outdated.
ebf5a69 to
a949d28
Compare
a949d28 to
b279f71
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
ebf1862 to
07c63b8
Compare
likebreath
left a comment
There was a problem hiding this comment.
@phip1611 Thanks for the patience. On top of the comments below, two high-level questions:
- What's the broader plan for an async HTTP API? This PR makes the handler async on the VMM side, but achieving full async semantics, say a cancel endpoint, or a progress query that can run alongside an in-flight migration, needs the HTTP layer to be async too, since it's currently a single-threaded serial loop.
- With send-migration becoming dispatch-only, how is the management layer meant to learn that a migration finished or failed?
Fair question!
Exactly! Thus the name "asynchronization" in the PR. However, with the temporary workaround But I see this as temporary workaround and I would like to entirely get rid of this behavior shortly after this gets merged.
By querying the upcoming With all that knowledge. Would you be fine with giving By the way: For a couple of weeks we actually tried keeping a blocking Does that help and clarify all your questions? A few pointers into our fork (please apologize the sometimes rather pragmatic implementation, haha):
|
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
f44d5c6 to
205e914
Compare
rbradford
left a comment
There was a problem hiding this comment.
Do you need to update the live migration documentation?
| } | ||
|
|
||
| /// Returns an error if the VM is currently owned by a migration worker. | ||
| fn reject_if_migrating(&self) -> result::Result<(), VmError> { |
There was a problem hiding this comment.
Would something like ok_or_migrating() be more Rust idiomatic? The "reject" verb feels off - not sure we use that anywhere else. This is frustrating because this feels off but i'm struggling to make a better suggestion. I like the code deduplication that this provides.
There was a problem hiding this comment.
I like the new name. Please note that this helper just exists for a single commit to keep the diff smaller and changes less invasive. THe following commit streamlines the use of match self.vm {}
| EpollDispatch::GuestExit => { | ||
| info!("VM guest exit event"); | ||
| self.guest_exit_evt.read().map_err(Error::EventFdRead)?; | ||
| // TODO: Future follow-up must resolve lifecycle handling while migrating. |
There was a problem hiding this comment.
I think this feels pretty fundamental - we could easily get exit events or reset events during a migration. How does it work before this change?
There was a problem hiding this comment.
I agree with you - the necessary changes are not trivial and I want to keep them out of this already complex PR. In our fork, we catch postponed lifecycle events (reboot, shutdown) in a field and replay them on the destination after successfull migration - but that is a non-trivial (but also not overly complex) change.
Currently (without this), when the guest reboots or shutdowns during a migration, the VMM is in a weird state: the API loop is blocked because of the ongoing long-living send_migration call, eventually the vCPUs are in a weird state (producing panics) and producing scary logs and then the guest reboots on the host and the migration fails.
So IMHO the new code makes existing technical debt visible - doesn't necessarily makes things worse.
There was a problem hiding this comment.
That was what was unclear to me - whether these TODOs are just surfacing the existing undefined behaviour or making it worse.
rbradford
left a comment
There was a problem hiding this comment.
This code introduces lots of assertions and panics - I hope you're sure they're ok?
| fn reject_if_migrating(&self) -> result::Result<(), VmError> { | ||
| match self { | ||
| VmOwnership::Migration { .. } => Err(VmError::VmMigrating), | ||
| _ => Ok(()), | ||
| } | ||
| } |
There was a problem hiding this comment.
Weird, i'm sure I left a comment about this - I know i'm brown M&Ming here - but this feels slightly off. I like the code deduplication but i'm not sure about the naming. Can we look for a more Rust idiomatic name?
There was a problem hiding this comment.
I agree with you, also not 100% happy. I'll brainstorm a bit
Let me double-check. The whole PR is crafted with a very special focus on not panicking, to keep the VM running at all costs. I usually just do panics for situations of programming errors, which typically end in non-recoverable issues anyway |
205e914 to
5ac8592
Compare
This initializes the module and the thread that will handle (control) the migration. This introduces the new types without the necessary wiring. On-behalf-of: SAP [email protected] Signed-off-by: Philipp Schuster <[email protected]>
This is a pre-requisite for the following commit which puts the migration into a dedicated thread. It allows the VMM to react to migration events (success/failure). The commit series was inspired by @ljcore [0] but was changed quite significantly. [0] cloud-hypervisor#7038 On-behalf-of: SAP [email protected] Signed-off-by: Philipp Schuster <[email protected]>
5ac8592 to
9b12af5
Compare
TBH, I've iterated on this so much that right now I can't see the forest for the trees. Time for weekend :D I'm confident it's solid, since I've also done multiple manual and LLM review rounds. I'm planning follow-ups anyway, where I can put more focus on this. This will serve as the base for many great future follow-ups, although this is the biggest change and enables many more features. PS: From a very coarse-grained check, I think most unwraps were there already and are just a result of the changed indentation |
This puts the send-migration action into a dedicated thread, laying the
groundwork for many follow-ups towards first-class live-migration in
CH.
This means:
1. The send-migration call will exit sooner (just trigger the
migration - dispatch semantics)
2. Other API calls can be triggered while a migration is ongoing but
will not be able to alter the VM as the VM's ownership is transferred
from the VMM to the migration thread. Example: hotplugging won't work
(which is good).
3. This is the basis for migration statistics via a dedicated endpoint
(future work).
The whole change was done with a special focus on graceful recover and
cleanup: even if anything on the migration paths go wrong, the proper
cleanups are already executed and the VMM can take back the ownership
of the VM.
The receive-migration API call remains blocking. To observe any status
changes about the migration on the sender side, one can observe the
event-monitor output and look for `vm.migration-{failed,finished}`.
These changes are inspired by [0] but differ significantly in details.
[0] cloud-hypervisor#7038
On-behalf-of: SAP [email protected]
Signed-off-by: Philipp Schuster <[email protected]>
This streamlines the behavior with the other request handlers so that now almost every request handler uses a match on self.vm. On-behalf-of: SAP [email protected] Signed-off-by: Philipp Schuster <[email protected]>
On-behalf-of: SAP [email protected] Signed-off-by: Philipp Schuster <[email protected]>
On-behalf-of: SAP [email protected] Signed-off-by: Philipp Schuster <[email protected]>
9b12af5 to
ec2dc9b
Compare
rbradford
left a comment
There was a problem hiding this comment.
Thank you for your patience - this has been open a long time!
|
I'll leave for @likebreath to do a final review and merge. |
This is part of our upstreaming plan (#7111 (comment)), specifically the "core mechanism" track.
The main changes are:
send-migrationnow only has dispatch semanticsreceive-migrationremains blockingvm.migration-{finished,failed}vm.migration-statusendpointseccomp for the migration path (which was missing!)Closes #7039