vmm: Automatically pause VM for coredump

If the VMM is not already paused then pause the VM prior to executing
the coredump and then resume it after. If the VM is already paused then
the original state is maintained.

Signed-off-by: Yi Wang <foxywang@tencent.com>
This commit is contained in:
Yi Wang 2023-07-17 20:42:10 +08:00 committed by Rob Bradford
parent c03f3b54b6
commit 3225c0c7c8
2 changed files with 22 additions and 6 deletions

View File

@ -36,6 +36,8 @@ pub struct DumpState {
pub enum GuestDebuggableError { pub enum GuestDebuggableError {
Coredump(anyhow::Error), Coredump(anyhow::Error),
CoredumpFile(std::io::Error), CoredumpFile(std::io::Error),
Pause(vm_migration::MigratableError),
Resume(vm_migration::MigratableError),
} }
pub trait GuestDebuggable: vm_migration::Pausable { pub trait GuestDebuggable: vm_migration::Pausable {

View File

@ -2607,6 +2607,8 @@ impl GuestDebuggable for Vm {
fn coredump(&mut self, destination_url: &str) -> std::result::Result<(), GuestDebuggableError> { fn coredump(&mut self, destination_url: &str) -> std::result::Result<(), GuestDebuggableError> {
event!("vm", "coredumping"); event!("vm", "coredumping");
let mut resume = false;
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
{ {
if let Some(ref platform) = self.config.lock().unwrap().platform { if let Some(ref platform) = self.config.lock().unwrap().platform {
@ -2618,12 +2620,18 @@ impl GuestDebuggable for Vm {
} }
} }
let current_state = self.get_state().unwrap(); match self.get_state().unwrap() {
if current_state != VmState::Paused { VmState::Running => {
self.pause().map_err(GuestDebuggableError::Pause)?;
resume = true;
}
VmState::Paused => {}
_ => {
return Err(GuestDebuggableError::Coredump(anyhow!( return Err(GuestDebuggableError::Coredump(anyhow!(
"Trying to coredump while VM is running" "Trying to coredump while VM is not running or paused"
))); )));
} }
}
let coredump_state = self.get_dump_state(destination_url)?; let coredump_state = self.get_dump_state(destination_url)?;
@ -2643,7 +2651,13 @@ impl GuestDebuggable for Vm {
self.memory_manager self.memory_manager
.lock() .lock()
.unwrap() .unwrap()
.coredump_iterate_save_mem(&coredump_state) .coredump_iterate_save_mem(&coredump_state)?;
if resume {
self.resume().map_err(GuestDebuggableError::Resume)?;
}
Ok(())
} }
} }