Skip to content

Commit a042bf5

Browse files
committed
[apple-vm] Implement 2-stage save/restore to file
1 parent 1773097 commit a042bf5

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

src/platform/backends/apple/apple_virtual_machine.cpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace mpl = multipass::logging;
2626
namespace
2727
{
2828
constexpr static auto log_category = "apple vm";
29+
constexpr static auto suspend_file = "suspend.vm_state";
2930
}
3031

3132
namespace multipass::apple
@@ -81,10 +82,27 @@ void AppleVirtualMachine::start()
8182
auto curr_state = MP_APPLE_VZ.get_state(vm_handle);
8283

8384
mpl::debug(log_category, "start() -> VM `{}` VM state is `{}`", vm_name, curr_state);
84-
if (curr_state == apple::AppleVMState::paused && MP_APPLE_VZ.can_resume(vm_handle))
85+
if (curr_state == apple::AppleVMState::stopped &&
86+
std::filesystem::exists(instance_dir.filesystemAbsolutePath() / suspend_file))
8587
{
86-
mpl::debug(log_category, "start() -> VM `{}` is in paused state, resuming", vm_name);
87-
error = MP_APPLE_VZ.resume_vm(vm_handle);
88+
mpl::debug(log_category,
89+
"start() -> found suspend file for VM `{}`, restoring state from file",
90+
vm_name);
91+
92+
error =
93+
MP_APPLE_VZ.restore_vm_from_file(vm_handle,
94+
instance_dir.filesystemAbsolutePath() / suspend_file);
95+
96+
if (!error && MP_APPLE_VZ.can_resume(vm_handle))
97+
{
98+
mpl::debug(log_category,
99+
"start() -> VM `{}` successfully restored state from file",
100+
vm_name);
101+
102+
std::filesystem::remove(instance_dir.filesystemAbsolutePath() / suspend_file);
103+
104+
error = MP_APPLE_VZ.resume_vm(vm_handle);
105+
}
88106
}
89107
else if (MP_APPLE_VZ.can_start(vm_handle))
90108
{
@@ -192,16 +210,29 @@ void AppleVirtualMachine::suspend()
192210
state = State::suspending;
193211
handle_state_update();
194212

195-
const auto error = MP_APPLE_VZ.pause_vm(vm_handle);
213+
auto error = MP_APPLE_VZ.pause_vm(vm_handle);
196214
if (error)
197215
{
198-
mpl::error(log_category, "suspend() -> VM '{}' failed to suspend: {}", vm_name, error);
216+
mpl::error(log_category, "suspend() -> VM '{}' failed to pause: {}", vm_name, error);
199217
throw std::runtime_error(
200218
fmt::format("VM '{}' failed to suspend, check logs for more details", vm_name));
201219
}
202220

203221
drop_ssh_session();
204222

223+
error = MP_APPLE_VZ.save_vm_to_file(vm_handle,
224+
instance_dir.filesystemAbsolutePath() / suspend_file);
225+
if (error)
226+
{
227+
mpl::error(log_category,
228+
"suspend() -> VM '{}' failed to save state to file '{}': {}",
229+
vm_name,
230+
instance_dir.filePath(suspend_file).toStdString(),
231+
error);
232+
throw std::runtime_error(
233+
fmt::format("VM '{}' failed to save state, check logs for more details", vm_name));
234+
}
235+
205236
// Reflect vm's state
206237
set_state(MP_APPLE_VZ.get_state(vm_handle));
207238
handle_state_update();

0 commit comments

Comments
 (0)