diff --git a/vm-migration/src/lib.rs b/vm-migration/src/lib.rs index 73848348b..dc5f6a45b 100644 --- a/vm-migration/src/lib.rs +++ b/vm-migration/src/lib.rs @@ -264,11 +264,6 @@ pub trait Snapshottable: Pausable { fn snapshot(&mut self) -> std::result::Result { 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. diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index a5661832a..21addf5b9 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -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); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 8256ac2b9..4570a346f 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -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 = result::Result; @@ -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> { 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 {