diff --git a/vmm/src/coredump.rs b/vmm/src/coredump.rs index 2e0cbf403..08c395286 100644 --- a/vmm/src/coredump.rs +++ b/vmm/src/coredump.rs @@ -36,6 +36,8 @@ pub struct DumpState { pub enum GuestDebuggableError { Coredump(anyhow::Error), CoredumpFile(std::io::Error), + Pause(vm_migration::MigratableError), + Resume(vm_migration::MigratableError), } pub trait GuestDebuggable: vm_migration::Pausable { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index f28fcd668..078bdd8a4 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -2607,6 +2607,8 @@ impl GuestDebuggable for Vm { fn coredump(&mut self, destination_url: &str) -> std::result::Result<(), GuestDebuggableError> { event!("vm", "coredumping"); + let mut resume = false; + #[cfg(feature = "tdx")] { if let Some(ref platform) = self.config.lock().unwrap().platform { @@ -2618,11 +2620,17 @@ impl GuestDebuggable for Vm { } } - let current_state = self.get_state().unwrap(); - if current_state != VmState::Paused { - return Err(GuestDebuggableError::Coredump(anyhow!( - "Trying to coredump while VM is running" - ))); + match self.get_state().unwrap() { + VmState::Running => { + self.pause().map_err(GuestDebuggableError::Pause)?; + resume = true; + } + VmState::Paused => {} + _ => { + return Err(GuestDebuggableError::Coredump(anyhow!( + "Trying to coredump while VM is not running or paused" + ))); + } } let coredump_state = self.get_dump_state(destination_url)?; @@ -2643,7 +2651,13 @@ impl GuestDebuggable for Vm { self.memory_manager .lock() .unwrap() - .coredump_iterate_save_mem(&coredump_state) + .coredump_iterate_save_mem(&coredump_state)?; + + if resume { + self.resume().map_err(GuestDebuggableError::Resume)?; + } + + Ok(()) } }