From 6e049e0da1297c929ce92a553ea3c6c8e4ff404e Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 27 Apr 2020 10:15:30 +0200 Subject: [PATCH] vmm: Add an identifier to the --vsock device It's possible to have multiple vsock devices so in preparation for hotplug/unplug it is important to be able to have a unique identifier for each device. Signed-off-by: Sebastien Boeuf Signed-off-by: Rob Bradford --- src/main.rs | 3 +- vmm/src/config.rs | 18 +++++++++--- vmm/src/device_manager.rs | 60 +++++++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/main.rs b/src/main.rs index f76fbfeb3..360643b60 100755 --- a/src/main.rs +++ b/src/main.rs @@ -196,7 +196,8 @@ fn create_app<'a, 'b>( Arg::with_name("vsock") .long("vsock") .help( - "Virtio VSOCK parameters \"cid=,sock=,iommu=on|off\"", + "Virtio VSOCK parameters \ + \"cid=,sock=,iommu=on|off,id=\"", ) .takes_value(true) .number_of_values(1) diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 0526fbe8e..6161c6a1d 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -1136,12 +1136,14 @@ pub struct VsockConfig { pub sock: PathBuf, #[serde(default)] pub iommu: bool, + #[serde(default)] + pub id: Option, } impl VsockConfig { pub fn parse(vsock: &str) -> Result { let mut parser = OptionParser::new(); - parser.add("sock").add("cid").add("iommu"); + parser.add("sock").add("cid").add("iommu").add("id"); parser.parse(vsock).map_err(Error::ParseVsock)?; let sock = parser @@ -1157,8 +1159,14 @@ impl VsockConfig { .convert("cid") .map_err(Error::ParseVsock)? .ok_or(Error::ParseVsockCidMissing)?; + let id = parser.get("id"); - Ok(VsockConfig { cid, sock, iommu }) + Ok(VsockConfig { + cid, + sock, + iommu, + id, + }) } } @@ -1878,7 +1886,8 @@ mod tests { VsockConfig { cid: 1, sock: PathBuf::from("/tmp/sock"), - iommu: false + iommu: false, + id: None, } ); assert_eq!( @@ -1886,7 +1895,8 @@ mod tests { VsockConfig { cid: 1, sock: PathBuf::from("/tmp/sock"), - iommu: true + iommu: true, + id: None, } ); Ok(()) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 33cd1e185..49081e134 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -14,7 +14,7 @@ extern crate vm_device; use crate::config::ConsoleOutputMode; #[cfg(feature = "pci_support")] use crate::config::DeviceConfig; -use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig}; +use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig}; use crate::interrupt::{ KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry, }; @@ -76,6 +76,7 @@ const VFIO_DEVICE_NAME_PREFIX: &str = "vfio"; const DISK_DEVICE_NAME_PREFIX: &str = "disk"; const NET_DEVICE_NAME_PREFIX: &str = "net"; const PMEM_DEVICE_NAME_PREFIX: &str = "pmem"; +const VSOCK_DEVICE_NAME_PREFIX: &str = "vsock"; /// Errors associated with device manager #[derive(Debug)] @@ -1120,7 +1121,7 @@ impl DeviceManager { devices.append(&mut self.make_virtio_pmem_devices()?); // Add virtio-vsock if required - devices.append(&mut self.make_virtio_vsock_device()?); + devices.append(&mut self.make_virtio_vsock_devices()?); devices.append(&mut self.make_virtio_mem_devices()?); @@ -1642,29 +1643,46 @@ impl DeviceManager { fn make_virtio_vsock_device( &mut self, + vsock_cfg: &mut VsockConfig, + ) -> DeviceManagerResult<(VirtioDeviceArc, bool, Option)> { + if vsock_cfg.id.is_none() { + vsock_cfg.id = self.next_device_name(VSOCK_DEVICE_NAME_PREFIX)?; + } + + let socket_path = vsock_cfg + .sock + .to_str() + .ok_or(DeviceManagerError::CreateVsockConvertPath)?; + let backend = + vm_virtio::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string()) + .map_err(DeviceManagerError::CreateVsockBackend)?; + + let vsock_device = Arc::new(Mutex::new( + vm_virtio::Vsock::new(vsock_cfg.cid, backend, vsock_cfg.iommu) + .map_err(DeviceManagerError::CreateVirtioVsock)?, + )); + + let migratable = Arc::clone(&vsock_device) as Arc>; + let id = migratable.lock().unwrap().id(); + self.migratable_devices.push((id, migratable)); + + Ok(( + Arc::clone(&vsock_device) as VirtioDeviceArc, + false, + vsock_cfg.id.clone(), + )) + } + + fn make_virtio_vsock_devices( + &mut self, ) -> DeviceManagerResult)>> { let mut devices = Vec::new(); - // Add vsock if required - if let Some(vsock_cfg) = &self.config.lock().unwrap().vsock { - let socket_path = vsock_cfg - .sock - .to_str() - .ok_or(DeviceManagerError::CreateVsockConvertPath)?; - let backend = - vm_virtio::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string()) - .map_err(DeviceManagerError::CreateVsockBackend)?; - let vsock_device = Arc::new(Mutex::new( - vm_virtio::Vsock::new(vsock_cfg.cid, backend, vsock_cfg.iommu) - .map_err(DeviceManagerError::CreateVirtioVsock)?, - )); - - devices.push((Arc::clone(&vsock_device) as VirtioDeviceArc, false, None)); - - let migratable = Arc::clone(&vsock_device) as Arc>; - let id = migratable.lock().unwrap().id(); - self.migratable_devices.push((id, migratable)); + let mut vsock = self.config.lock().unwrap().vsock.clone(); + if let Some(ref mut vsock_cfg) = &mut vsock { + devices.push(self.make_virtio_vsock_device(vsock_cfg)?); } + self.config.lock().unwrap().vsock = vsock; Ok(devices) }