-
Notifications
You must be signed in to change notification settings - Fork 615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vz: implement auto save/restore #2900
base: master
Are you sure you want to change the base?
Changes from 1 commit
4fc95cd
349ccd1
929c7e5
c5305c0
1d533a7
de78015
7f4df6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//go:build darwin && !arm64 && !no_vz | ||
|
||
package vz | ||
|
||
import ( | ||
"fmt" | ||
"runtime" | ||
|
||
"github.com/Code-Hex/vz/v3" | ||
) | ||
|
||
func saveVM(vm *vz.VirtualMachine, machineStatePath string) error { | ||
return fmt.Errorf("save is not supported on the vz driver for the architecture %s", runtime.GOARCH) | ||
} | ||
|
||
func restoreVM(vm *vz.VirtualMachine, machineStatePath string) error { | ||
return fmt.Errorf("restore is not supported on the vz driver for the architecture %s", runtime.GOARCH) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
//go:build darwin && arm64 && !no_vz | ||
|
||
package vz | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/Code-Hex/vz/v3" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func saveVM(vm *vz.VirtualMachine, machineStatePath string) error { | ||
if !vm.CanPause() { | ||
return fmt.Errorf("can't pause the VZ machine") | ||
} | ||
|
||
// Remove the old machine state file if it exists, | ||
// because saving the machine state will fail if the file already exists. | ||
if err := os.Remove(machineStatePath); err != nil && !errors.Is(err, os.ErrNotExist) { | ||
logrus.WithError(err).Errorf("Failed to remove the old VZ machine state file %q", machineStatePath) | ||
return err | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can write machine state to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently, I don't see the value in keeping the By the time we reach this point, the guest OS should already have gone through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. Maybe add a comment here to explain why we don't keep the state? |
||
|
||
logrus.Info("Pausing VZ") | ||
norio-nomura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := vm.Pause(); err != nil { | ||
return err | ||
} | ||
|
||
// If we can't stop the machine after pausing, saving the machine state will be useless. | ||
// So we should check this before saving the machine state. | ||
if !vm.CanStop() { | ||
return fmt.Errorf("can't stop the VZ machine after pausing") | ||
} | ||
norio-nomura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
logrus.Info("Saving VZ machine state for resuming later") | ||
norio-nomura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := vm.SaveMachineStateToPath(machineStatePath); err != nil { | ||
// If we fail to save the machine state, we should resume the machine to call RequestStop() later | ||
logrus.WithError(err).Errorf("Failed to save the machine state to %q", machineStatePath) | ||
if resumeError := vm.Resume(); resumeError != nil { | ||
return resumeError | ||
} | ||
norio-nomura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return err | ||
} | ||
|
||
logrus.Info("Stopping VZ") | ||
if err := vm.Stop(); err != nil { | ||
// If we fail to stop the machine, we should resume the machine to call RequestStop() later | ||
logrus.WithError(err).Error("Failed to stop the VZ machine") | ||
if resumeError := vm.Resume(); resumeError != nil { | ||
return resumeError | ||
} | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func restoreVM(vm *vz.VirtualMachine, machineStatePath string) error { | ||
if _, err := os.Stat(machineStatePath); err != nil { | ||
return err | ||
} | ||
logrus.Info("Saved VZ machine state found, resuming VZ") | ||
norio-nomura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err := vm.RestoreMachineStateFromURL(machineStatePath); err != nil { | ||
return err | ||
} | ||
if err := vm.Resume(); err != nil { | ||
return err | ||
} | ||
// Remove the machine state file after resuming the machine | ||
if err := os.Remove(machineStatePath); err != nil { | ||
// We should log the error but continue the process, because the machine state is already restored | ||
logrus.WithError(err).Errorf("Failed to remove the VZ machine state file %q", machineStatePath) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we always remove the saved state? what if you want to always start with the same saved state? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As I mentioned in a reply to another comment earlier, achieving that would require a snapshot feature that includes saving and restoring the diffdisk. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, we can add this later. |
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing to avoid failure on save is not a good reason, save can replace existing file.