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 <sebastien.boeuf@intel.com>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-04-27 10:15:30 +02:00 committed by Rob Bradford
parent 10348f73e4
commit 6e049e0da1
3 changed files with 55 additions and 26 deletions

View File

@ -196,7 +196,8 @@ fn create_app<'a, 'b>(
Arg::with_name("vsock") Arg::with_name("vsock")
.long("vsock") .long("vsock")
.help( .help(
"Virtio VSOCK parameters \"cid=<context_id>,sock=<socket_path>,iommu=on|off\"", "Virtio VSOCK parameters \
\"cid=<context_id>,sock=<socket_path>,iommu=on|off,id=<device_id>\"",
) )
.takes_value(true) .takes_value(true)
.number_of_values(1) .number_of_values(1)

View File

@ -1136,12 +1136,14 @@ pub struct VsockConfig {
pub sock: PathBuf, pub sock: PathBuf,
#[serde(default)] #[serde(default)]
pub iommu: bool, pub iommu: bool,
#[serde(default)]
pub id: Option<String>,
} }
impl VsockConfig { impl VsockConfig {
pub fn parse(vsock: &str) -> Result<Self> { pub fn parse(vsock: &str) -> Result<Self> {
let mut parser = OptionParser::new(); 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)?; parser.parse(vsock).map_err(Error::ParseVsock)?;
let sock = parser let sock = parser
@ -1157,8 +1159,14 @@ impl VsockConfig {
.convert("cid") .convert("cid")
.map_err(Error::ParseVsock)? .map_err(Error::ParseVsock)?
.ok_or(Error::ParseVsockCidMissing)?; .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 { VsockConfig {
cid: 1, cid: 1,
sock: PathBuf::from("/tmp/sock"), sock: PathBuf::from("/tmp/sock"),
iommu: false iommu: false,
id: None,
} }
); );
assert_eq!( assert_eq!(
@ -1886,7 +1895,8 @@ mod tests {
VsockConfig { VsockConfig {
cid: 1, cid: 1,
sock: PathBuf::from("/tmp/sock"), sock: PathBuf::from("/tmp/sock"),
iommu: true iommu: true,
id: None,
} }
); );
Ok(()) Ok(())

View File

@ -14,7 +14,7 @@ extern crate vm_device;
use crate::config::ConsoleOutputMode; use crate::config::ConsoleOutputMode;
#[cfg(feature = "pci_support")] #[cfg(feature = "pci_support")]
use crate::config::DeviceConfig; use crate::config::DeviceConfig;
use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig}; use crate::config::{DiskConfig, FsConfig, NetConfig, PmemConfig, VmConfig, VsockConfig};
use crate::interrupt::{ use crate::interrupt::{
KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry, KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry,
}; };
@ -76,6 +76,7 @@ const VFIO_DEVICE_NAME_PREFIX: &str = "vfio";
const DISK_DEVICE_NAME_PREFIX: &str = "disk"; const DISK_DEVICE_NAME_PREFIX: &str = "disk";
const NET_DEVICE_NAME_PREFIX: &str = "net"; const NET_DEVICE_NAME_PREFIX: &str = "net";
const PMEM_DEVICE_NAME_PREFIX: &str = "pmem"; const PMEM_DEVICE_NAME_PREFIX: &str = "pmem";
const VSOCK_DEVICE_NAME_PREFIX: &str = "vsock";
/// Errors associated with device manager /// Errors associated with device manager
#[derive(Debug)] #[derive(Debug)]
@ -1120,7 +1121,7 @@ impl DeviceManager {
devices.append(&mut self.make_virtio_pmem_devices()?); devices.append(&mut self.make_virtio_pmem_devices()?);
// Add virtio-vsock if required // 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()?); devices.append(&mut self.make_virtio_mem_devices()?);
@ -1642,10 +1643,12 @@ impl DeviceManager {
fn make_virtio_vsock_device( fn make_virtio_vsock_device(
&mut self, &mut self,
) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool, Option<String>)>> { vsock_cfg: &mut VsockConfig,
let mut devices = Vec::new(); ) -> DeviceManagerResult<(VirtioDeviceArc, bool, Option<String>)> {
// Add vsock if required if vsock_cfg.id.is_none() {
if let Some(vsock_cfg) = &self.config.lock().unwrap().vsock { vsock_cfg.id = self.next_device_name(VSOCK_DEVICE_NAME_PREFIX)?;
}
let socket_path = vsock_cfg let socket_path = vsock_cfg
.sock .sock
.to_str() .to_str()
@ -1659,13 +1662,28 @@ impl DeviceManager {
.map_err(DeviceManagerError::CreateVirtioVsock)?, .map_err(DeviceManagerError::CreateVirtioVsock)?,
)); ));
devices.push((Arc::clone(&vsock_device) as VirtioDeviceArc, false, None));
let migratable = Arc::clone(&vsock_device) as Arc<Mutex<dyn Migratable>>; let migratable = Arc::clone(&vsock_device) as Arc<Mutex<dyn Migratable>>;
let id = migratable.lock().unwrap().id(); let id = migratable.lock().unwrap().id();
self.migratable_devices.push((id, migratable)); 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<Vec<(VirtioDeviceArc, bool, Option<String>)>> {
let mut devices = Vec::new();
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) Ok(devices)
} }