diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 41a2c3383..dcf6614b2 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1875,7 +1875,7 @@ impl RequestHandler for Vmm { match &self.vm_config { Some(vm_config) => { let state = match &self.vm { - Some(vm) => vm.get_state()?, + Some(vm) => vm.get_state(), None => VmState::Created, }; let config = vm_config.lock().unwrap().clone(); @@ -2347,7 +2347,7 @@ impl RequestHandler for Vmm { return e; } - if vm.get_state().unwrap() == VmState::Paused + if vm.get_state() == VmState::Paused && let Err(e) = vm.resume() { return e; diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index e359eb4eb..882993f0a 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -19,7 +19,7 @@ use std::mem::size_of; use std::num::Wrapping; use std::ops::Deref; use std::os::unix::net::UnixStream; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex}; #[cfg(not(target_arch = "riscv64"))] use std::time::Instant; use std::{cmp, result, str, thread}; @@ -150,9 +150,6 @@ pub enum Error { #[error("Cannot enable interrupt controller")] EnableInterruptController(#[source] interrupt_controller::Error), - #[error("VM state is poisoned")] - PoisonedState, - #[error("Error from device manager")] DeviceManager(#[source] DeviceManagerError), @@ -511,7 +508,7 @@ pub struct Vm { threads: Vec>, device_manager: Arc>, config: Arc>, - state: RwLock, + state: VmState, cpu_manager: Arc>, memory_manager: Arc>, #[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))] @@ -875,7 +872,7 @@ impl Vm { None }; - let vm_state = if snapshot.is_some() { + let state = if snapshot.is_some() { VmState::Paused } else { VmState::Created @@ -888,7 +885,7 @@ impl Vm { device_manager, config, threads: Vec::with_capacity(1), - state: RwLock::new(vm_state), + state, cpu_manager, memory_manager, vm, @@ -1669,10 +1666,9 @@ impl Vm { } pub fn shutdown(&mut self) -> Result<()> { - let mut state = self.state.try_write().map_err(|_| Error::PoisonedState)?; let new_state = VmState::Shutdown; - state.valid_transition(new_state)?; + self.state.valid_transition(new_state)?; // Wake up the DeviceManager threads so they will get terminated cleanly self.device_manager @@ -1691,7 +1687,7 @@ impl Vm { for thread in self.threads.drain(..) { thread.join().map_err(Error::ThreadCleanup)?; } - *state = new_state; + self.state = new_state; Ok(()) } @@ -2378,7 +2374,7 @@ impl Vm { pub fn boot(&mut self) -> Result<()> { trace_scoped!("Vm::boot"); - let current_state = self.get_state()?; + let current_state = self.state; if current_state == VmState::Paused { return self.resume().map_err(Error::Resume); } @@ -2562,8 +2558,7 @@ impl Vm { .start_boot_vcpus(new_state == VmState::BreakPoint) .map_err(Error::CpuManager)?; - let mut state = self.state.try_write().map_err(|_| Error::PoisonedState)?; - *state = new_state; + self.state = new_state; Ok(()) } @@ -2593,12 +2588,9 @@ impl Vm { Arc::clone(&self.config) } - /// Get the VM state. Returns an error if the state is poisoned. - pub fn get_state(&self) -> Result { + /// Get the VM state. + pub fn get_state(&self) -> VmState { self.state - .try_read() - .map_err(|_| Error::PoisonedState) - .map(|state| *state) } /// Gets the actual size of the balloon. @@ -2850,13 +2842,8 @@ impl Vm { impl Pausable for Vm { fn pause(&mut self) -> std::result::Result<(), MigratableError> { event!("vm", "pausing"); - let mut state = self - .state - .try_write() - .map_err(|e| MigratableError::Pause(anyhow!("Could not get VM state: {e}")))?; let new_state = VmState::Paused; - - state + self.state .valid_transition(new_state) .map_err(|e| MigratableError::Pause(anyhow!("Invalid transition: {e:?}")))?; @@ -2883,7 +2870,7 @@ impl Pausable for Vm { .pause() .map_err(|e| MigratableError::Pause(anyhow!("Could not pause the VM: {e}")))?; - *state = new_state; + self.state = new_state; event!("vm", "paused"); Ok(()) @@ -2891,14 +2878,10 @@ impl Pausable for Vm { fn resume(&mut self) -> std::result::Result<(), MigratableError> { event!("vm", "resuming"); - let current_state = self.get_state().unwrap(); - let mut state = self - .state - .try_write() - .map_err(|e| MigratableError::Resume(anyhow!("Could not get VM state: {e}")))?; + let current_state = self.get_state(); let new_state = VmState::Running; - state + self.state .valid_transition(new_state) .map_err(|e| MigratableError::Resume(anyhow!("Invalid transition: {e:?}")))?; @@ -2921,7 +2904,7 @@ impl Pausable for Vm { self.device_manager.lock().unwrap().resume()?; // And we're back to the Running state. - *state = new_state; + self.state = new_state; event!("vm", "resumed"); Ok(()) } @@ -2953,8 +2936,7 @@ impl Snapshottable for Vm { } } - let current_state = self.get_state().unwrap(); - if current_state != VmState::Paused { + if self.get_state() != VmState::Paused { return Err(MigratableError::Snapshot(anyhow!( "Trying to snapshot while VM is running" ))); @@ -3116,20 +3098,16 @@ impl Debuggable for Vm { } fn debug_pause(&mut self) -> std::result::Result<(), DebuggableError> { - if *self.state.read().unwrap() == VmState::Running { + if self.state == VmState::Running { self.pause().map_err(DebuggableError::Pause)?; } - let mut state = self - .state - .try_write() - .map_err(|_| DebuggableError::PoisonedState)?; - *state = VmState::BreakPoint; + self.state = VmState::BreakPoint; Ok(()) } fn debug_resume(&mut self) -> std::result::Result<(), DebuggableError> { - if *self.state.read().unwrap() == VmState::BreakPoint { + if self.state == VmState::BreakPoint { self.resume().map_err(DebuggableError::Pause)?; } @@ -3209,7 +3187,7 @@ impl GuestDebuggable for Vm { } } - match self.get_state().unwrap() { + match self.get_state() { VmState::Running => { self.pause().map_err(GuestDebuggableError::Pause)?; resume = true;