(&mut self)
| 3237 | |
| 3238 | impl Pausable for Vm { |
| 3239 | fn pause(&mut self) -> std::result::Result<(), MigratableError> { |
| 3240 | event!("vm", "pausing"); |
| 3241 | let new_state = VmState::Paused; |
| 3242 | self.state |
| 3243 | .valid_transition(new_state) |
| 3244 | .map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {e:?}")))?; |
| 3245 | |
| 3246 | #[cfg(target_arch = "x86_64")] |
| 3247 | { |
| 3248 | let mut clock = self |
| 3249 | .vm |
| 3250 | .get_clock() |
| 3251 | .map_err(|e| MigratableError::Pause(anyhow!("Could not get VM clock: {e}")))?; |
| 3252 | clock.reset_flags(); |
| 3253 | self.saved_clock = Some(clock); |
| 3254 | } |
| 3255 | |
| 3256 | // Before pausing the vCPUs activate any pending virtio devices that might |
| 3257 | // need activation between starting the pause (or e.g. a migration it's part of) |
| 3258 | self.activate_virtio_devices().map_err(|e| { |
| 3259 | MigratableError::Pause(anyhow!("Error activating pending virtio devices: {e:?}")) |
| 3260 | })?; |
| 3261 | |
| 3262 | self.cpu_manager.lock().unwrap().pause()?; |
| 3263 | self.device_manager.lock().unwrap().pause()?; |
| 3264 | |
| 3265 | self.vm |
| 3266 | .pause() |
| 3267 | .map_err(|e| MigratableError::Pause(anyhow!("Could not pause the VM: {e}")))?; |
| 3268 | |
| 3269 | self.state = new_state; |
| 3270 | |
| 3271 | event!("vm", "paused"); |
| 3272 | Ok(()) |
| 3273 | } |
| 3274 | |
| 3275 | fn resume(&mut self) -> std::result::Result<(), MigratableError> { |
| 3276 | event!("vm", "resuming"); |
no test coverage detected