@@ -26,6 +26,7 @@ namespace mpl = multipass::logging;
2626namespace
2727{
2828constexpr static auto log_category = " apple vm" ;
29+ constexpr static auto suspend_file = " suspend.vm_state" ;
2930}
3031
3132namespace 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