vmm: Move Vm to the new restore design

Now the entire codebase has been moved to the new restore design, we can
complete the work by creating a dedicated restore() function for the Vm
object and get rid of the method restore() from the Snapshottable trait.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-12-01 16:52:04 +01:00 committed by Bo Chen
parent 3888f57600
commit d0c53a5357
3 changed files with 34 additions and 45 deletions

View File

@ -264,11 +264,6 @@ pub trait Snapshottable: Pausable {
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
Ok(Snapshot::new(""))
}
/// Restore a component from its snapshot.
fn restore(&mut self, _snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
Ok(())
}
}
/// A transportable component can be sent or receive to a specific URL.

View File

@ -682,7 +682,7 @@ impl Vmm {
None,
None,
None,
Some(snapshot.clone()),
Some(snapshot),
Some(source_url),
Some(restore_cfg.prefault),
)?;
@ -690,7 +690,7 @@ impl Vmm {
// Now we can restore the rest of the VM.
if let Some(ref mut vm) = self.vm {
vm.restore(snapshot).map_err(VmError::Restore)
vm.restore()
} else {
Err(VmError::VmNotCreated)
}
@ -1272,9 +1272,9 @@ impl Vmm {
})?;
// Create VM
vm.restore(snapshot).map_err(|e| {
vm.restore().map_err(|e| {
Response::error().write_to(socket).ok();
e
MigratableError::MigrateReceive(anyhow!("Failed restoring the Vm: {}", e))
})?;
self.vm = Some(vm);

View File

@ -308,6 +308,9 @@ pub enum Error {
#[cfg(feature = "guest_debug")]
#[error("Error coredumping VM: {0:?}")]
Coredump(GuestDebuggableError),
#[error("Failed taking the RwLock")]
TryRwLock(#[source] anyhow::Error),
}
pub type Result<T> = result::Result<T, Error>;
@ -2120,6 +2123,33 @@ impl Vm {
Ok(())
}
pub fn restore(&mut self) -> Result<()> {
event!("vm", "restoring");
let current_state = self.get_state()?;
let new_state = VmState::Paused;
current_state.valid_transition(new_state)?;
// Now we can start all vCPUs from here.
self.cpu_manager
.lock()
.unwrap()
.start_restored_vcpus()
.map_err(Error::CpuManager)?;
self.setup_signal_handler()?;
self.setup_tty()?;
let mut state = self
.state
.try_write()
.map_err(|e| Error::TryRwLock(anyhow!("Failed taking the lock: {}", e)))?;
*state = new_state;
event!("vm", "restored");
Ok(())
}
/// Gets a thread-safe reference counted pointer to the VM configuration.
pub fn get_config(&self) -> Arc<Mutex<VmConfig>> {
Arc::clone(&self.config)
@ -2493,42 +2523,6 @@ impl Snapshottable for Vm {
event!("vm", "snapshotted");
Ok(vm_snapshot)
}
fn restore(&mut self, _snapshot: Snapshot) -> std::result::Result<(), MigratableError> {
event!("vm", "restoring");
let current_state = self
.get_state()
.map_err(|e| MigratableError::Restore(anyhow!("Could not get VM state: {:#?}", e)))?;
let new_state = VmState::Paused;
current_state.valid_transition(new_state).map_err(|e| {
MigratableError::Restore(anyhow!("Could not restore VM state: {:#?}", e))
})?;
// Now we can start all vCPUs from here.
self.cpu_manager
.lock()
.unwrap()
.start_restored_vcpus()
.map_err(|e| {
MigratableError::Restore(anyhow!("Cannot start restored vCPUs: {:#?}", e))
})?;
self.setup_signal_handler().map_err(|e| {
MigratableError::Restore(anyhow!("Could not setup signal handler: {:#?}", e))
})?;
self.setup_tty()
.map_err(|e| MigratableError::Restore(anyhow!("Could not setup tty: {:#?}", e)))?;
let mut state = self
.state
.try_write()
.map_err(|e| MigratableError::Restore(anyhow!("Could not set VM state: {:#?}", e)))?;
*state = new_state;
event!("vm", "restored");
Ok(())
}
}
impl Transportable for Vm {