vmm: Streamline reboot code path

Separate the destruction and cleanup of original VM and the creation of
the new one. In particular have a clear hand off point for resources
(e.g. reset EventFd) used by the new VM from the original. In the
situation where vm.shutdown() generates an error this also avoids the
Vmm reference to the Vm (self.vm) from being maintained.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-03-17 11:16:32 +01:00
parent 03014e2e7f
commit 9c95109a6b

View File

@ -581,8 +581,9 @@ impl Vmm {
}
}
// First we stop the current VM and create a new one.
if let Some(ref mut vm) = self.vm {
// First we stop the current VM
let (config, serial_pty, console_pty, console_resize_pipe) =
if let Some(mut vm) = self.vm.take() {
let config = vm.get_config();
let serial_pty = vm.serial_pty();
let console_pty = vm.console_pty();
@ -590,7 +591,11 @@ impl Vmm {
.console_resize_pipe()
.as_ref()
.map(|pipe| pipe.try_clone().unwrap());
self.vm_shutdown()?;
vm.shutdown()?;
(config, serial_pty, console_pty, console_resize_pipe)
} else {
return Err(VmError::VmNotCreated);
};
let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?;
let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?;
@ -610,7 +615,9 @@ impl Vmm {
if self.reset_evt.read().is_ok() {
warn!("Spurious second reset event received. Ignoring.");
}
self.vm = Some(Vm::new(
// Then we create the new VM
let mut vm = Vm::new(
config,
exit_evt,
reset_evt,
@ -622,15 +629,14 @@ impl Vmm {
serial_pty,
console_pty,
console_resize_pipe,
)?);
}
)?;
// Then we start the new VM.
if let Some(ref mut vm) = self.vm {
vm.boot()
} else {
Err(VmError::VmNotCreated)
}
// And we boot it
vm.boot()?;
self.vm = Some(vm);
Ok(())
}
fn vm_info(&self) -> result::Result<VmInfo, VmError> {