Repository navigation
Support suspending and resuming Linux VMs - #1297
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d2a3fcca1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
0d2a3fc to
769f6a2
Compare
|
I'm very excited about getting this merged in. My org has a suite of playwright tests that run against a containerized stack of services running on a Linux host. Bringing that stack up and down to reset state for each test is expensive at around 30s per respin. Some initial experiments with code behind this new PR show that we can take a snapshot of a VM running our system, and then resume it in ~2s before each test. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 769f6a21be
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
769f6a2 to
01d9359
Compare
|
Would be great to get this in |
|
@randvoorhies can you rebase and I will review |
|
@yzhuang-oai yup no problem I'll get to it in the next few days |
01d9359 to
6b6a326
Compare
|
Ok @yzhuang-oai this MR is rebased and should be good to go. |
|
@randvoorhies can you check the review comment? almost ready to merge. |
6b6a326 to
b01bd45
Compare
|
@yzhuang-oai updated and rebased onto the latest
I had originally wanted to follow how Running several VMs with the same |
|
Hey @yzhuang-oai do you need anything more from me before reviewing/merging? |
Restoring saved state requires the VZGenericMachineIdentifier that the
VM was saved with, but Linux VMs were getting a new one every time they
started (including when trying to restore from saved state). The
identifier is now persisted in the VM config and reused on every start.
Apple's SDK header for VZGenericPlatformConfiguration.machineIdentifier
says:
> Running two virtual machines concurrently with the same identifier
> results in undefined behavior in the guest operating system. When
> restoring a virtual machine from saved state, this `machineIdentifier`
> must match the `machineIdentifier` of the saved virtual machine.
So identifiers for Linux guests are now treated like MAC addresses:
- Cloning a non-suspended VM generates a new id for the clone.
- Suspended clones keep their id because their saved state requires
it.
- Running a VM whose id matches an already running VM generates a new
id.
- If the colliding VM being run was suspended, its saved state will
be discarded.
Configurations without an identifier will still load, but can't be
suspended.
Suspendable mode for Linux VMs omits the pointing device because
VZUSBScreenCoordinatePointingDeviceConfiguration makes restores fail.
b01bd45 to
d9e347d
Compare
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d9e347d914
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
yzhuang-oai
left a comment
There was a problem hiding this comment.
lgtm thanks @randvoorhies for all the work on this!!
|
You bet, thanks for the great feedback! |
|
Hey @yzhuang-oai btw I was about to finish up some final polish to sneak in before the merge. If you want, I can open another quick PR for the following:
Happy to do it, or happy to move on just lmk. |
Fixes #1177
Summary
Previous investigation in #796 and #1177 implied that restoring suspended Linux VMs wasn't supported by Virtualization.framework. Some testing on current macOS shows that Linux restoration does actually work properly, and that Tart's existing suspend/restore mechanisms were very close to working.
The
Darwinplatform implementation persists the VM's ECID and assigns it toVZMacPlatformConfiguration.machineIdentifier. However, theLinuxplatform didn't specify amachineIdentifierwhen constructing itsVZGenericPlatformConfiguration, which caused a new identifier to be generated each time the platform was instantiated.Unfortunately, Virtualization.framework returns a very opaque error if saved machine state is restored with a mismatched identifier:
This PR generates and persists a
VZGenericMachineIdentifierin new Linux VM config files, then reuses it whenever the platform is constructed.Apple's SDK header for
VZGenericPlatformConfiguration.machineIdentifiersays that running two VMs concurrently with the same identifier results in undefined behavior in the guest, and that restoring saved state requires the identifier the state was saved with. Now that identifiers are persisted, they're handled the same way Tart already handles MAC addresses:tart cloneof a non-suspended Linux VM gives the clone a new identifier. Clones of suspended VMs keep the source's identifier, because their saved state can only be restored with it.tart rungives a VM a new identifier (discarding any saved state) if another running VM already has the same one, mirroring the existing MAC collision check. This covers clones of suspended VMs and duplicate imports. The config is read under the global storage lock, so concurrent runs of the same VM can't act on a stale identifier.Darwin ECIDs are intentionally left as they are, because changing the ECID of an installed macOS guest can stop it from booting (#59, #977). Linux guests previously got a new identifier on every boot, so regenerating one is safe.
Existing Linux configs without a
machineIdentifierare loadable for normal use but can't be suspended. Cloning such a VM gives the clone an identifier.The
Linuxplatform now conforms toPlatformSuspendable. Suspendable Linux VMs retain USB keyboard support but omitVZUSBScreenCoordinatePointingDeviceConfiguration, which passesvalidateSaveRestoreSupport()but causes restoration to fail.Testing
The matching boot ID and PID with a continuously incrementing counter confirm that saved machine state was restored rather than cold-booted.