vmm: device_manager: Implement the Pausable trait

Since the Snapshotable placeholder and Migratable traits are provided as
well, the DeviceManager object and all its objects are now Migratable.

All Migratable devices are tracked as Arc<Mutex<dyn Migratable>>
references.

Keeping track of all migratable devices allows for implementing the
Migratable trait for the DeviceManager structure, making the whole
device model potentially migratable.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-11-19 00:24:31 +01:00
parent a122da4bef
commit 35dd1523c9
4 changed files with 40 additions and 0 deletions

1
Cargo.lock generated
View File

@ -1130,6 +1130,7 @@ dependencies = [
"signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"vfio 0.0.1",
"vm-allocator 0.1.0",
"vm-device 0.1.0",
"vm-memory 0.1.0 (git+https://github.com/rust-vmm/vm-memory)",
"vm-virtio 0.1.0",
"vmm-sys-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -30,6 +30,7 @@ serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vfio = { path = "../vfio", optional = true }
vm-allocator = { path = "../vm-allocator" }
vm-device = { path = "../vm-device" }
vm-virtio = { path = "../vm-virtio" }
vmm-sys-util = ">=0.3.1"
signal-hook = "0.1.10"

View File

@ -9,6 +9,8 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
//
extern crate vm_device;
use crate::config::{ConsoleOutputMode, VmConfig};
use crate::vm::VmInfo;
#[cfg(feature = "acpi")]
@ -43,6 +45,7 @@ use std::sync::{Arc, Mutex, RwLock};
#[cfg(feature = "pci_support")]
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
use vm_allocator::SystemAllocator;
use vm_device::{Migratable, MigratableError, Pausable, Snapshotable};
use vm_memory::GuestAddress;
use vm_memory::{Address, GuestMemoryMmap, GuestUsize};
#[cfg(feature = "pci_support")]
@ -404,6 +407,9 @@ pub struct DeviceManager {
// VM configuration
config: Arc<Mutex<VmConfig>>,
// Migratable devices
migratable_devices: Vec<Arc<Mutex<dyn Migratable>>>,
}
impl DeviceManager {
@ -418,6 +424,7 @@ impl DeviceManager {
let mmio_bus = devices::Bus::new();
let mut virtio_devices: Vec<(Arc<Mutex<dyn vm_virtio::VirtioDevice>>, bool)> = Vec::new();
let mut migratable_devices: Vec<Arc<Mutex<dyn Migratable>>> = Vec::new();
let mut mmap_regions = Vec::new();
#[allow(unused_mut)]
@ -501,6 +508,7 @@ impl DeviceManager {
start_of_device_area,
end_of_device_area,
config,
migratable_devices,
})
}
@ -1710,3 +1718,24 @@ impl Aml for DeviceManager {
bytes
}
}
impl Pausable for DeviceManager {
fn pause(&mut self) -> result::Result<(), MigratableError> {
for dev in &self.migratable_devices {
dev.lock().unwrap().pause()?;
}
Ok(())
}
fn resume(&mut self) -> result::Result<(), MigratableError> {
for dev in &self.migratable_devices {
dev.lock().unwrap().resume()?;
}
Ok(())
}
}
impl Snapshotable for DeviceManager {}
impl Migratable for DeviceManager {}

View File

@ -43,6 +43,7 @@ use std::os::unix::io::FromRawFd;
use std::sync::{Arc, Mutex, RwLock};
use std::{result, str, thread};
use vm_allocator::{GsiApic, SystemAllocator};
use vm_device::{MigratableError, Pausable};
use vm_memory::guest_memory::FileOffset;
use vm_memory::{
Address, Bytes, Error as MmapError, GuestAddress, GuestMemory, GuestMemoryMmap,
@ -145,6 +146,12 @@ pub enum Error {
/// Capability missing
CapabilityMissing(Cap),
/// Cannot pause devices
PauseDevices(MigratableError),
/// Cannot resume devices
ResumeDevices(MigratableError),
}
pub type Result<T> = result::Result<T, Error>;
@ -627,6 +634,7 @@ impl Vm {
.unwrap()
.pause()
.map_err(Error::CpuManager)?;
self.devices.pause().map_err(Error::PauseDevices)?;
*state = new_state;
@ -639,6 +647,7 @@ impl Vm {
state.valid_transition(new_state)?;
self.devices.resume().map_err(Error::ResumeDevices)?;
self.cpu_manager
.lock()
.unwrap()