vmm: Add support for multiple virtio-fs devices

Until now, the VMM was only accepting a single instance of a virtio-fs
device. This commit extend the virtio-fs support by allowing several
devices to be created for a single VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-06-27 09:14:11 -07:00 committed by Samuel Ortiz
parent 0fcca3ed74
commit 1cb2378499
3 changed files with 41 additions and 27 deletions

View File

@ -74,7 +74,8 @@ fn main() {
sock=<socket_path>,num_queues=<number_of_queues>,\ sock=<socket_path>,num_queues=<number_of_queues>,\
queue_size=<size_of_each_queue>\"", queue_size=<size_of_each_queue>\"",
) )
.takes_value(true), .takes_value(true)
.min_values(1),
) )
.get_matches(); .get_matches();
@ -98,7 +99,7 @@ fn main() {
// This .unwrap() cannot fail as there is a default value defined // This .unwrap() cannot fail as there is a default value defined
let rng = cmd_arguments.value_of("rng").unwrap(); let rng = cmd_arguments.value_of("rng").unwrap();
let fs = cmd_arguments.value_of("fs"); let fs: Option<Vec<&str>> = cmd_arguments.values_of("fs").map(|x| x.collect());
let vm_config = match config::VmConfig::parse(config::VmParams { let vm_config = match config::VmConfig::parse(config::VmParams {
cpus, cpus,

View File

@ -59,7 +59,7 @@ pub struct VmParams<'a> {
pub disks: Vec<&'a str>, pub disks: Vec<&'a str>,
pub net: Option<&'a str>, pub net: Option<&'a str>,
pub rng: &'a str, pub rng: &'a str,
pub fs: Option<&'a str>, pub fs: Option<Vec<&'a str>>,
} }
pub struct CpusConfig(pub u8); pub struct CpusConfig(pub u8);
@ -232,6 +232,7 @@ impl<'a> RngConfig<'a> {
} }
} }
#[derive(Debug)]
pub struct FsConfig<'a> { pub struct FsConfig<'a> {
pub tag: &'a str, pub tag: &'a str,
pub sock: &'a Path, pub sock: &'a Path,
@ -240,13 +241,9 @@ pub struct FsConfig<'a> {
} }
impl<'a> FsConfig<'a> { impl<'a> FsConfig<'a> {
pub fn parse(fs: Option<&'a str>) -> Result<Option<Self>> { pub fn parse(fs: &'a str) -> Result<Self> {
if fs.is_none() {
return Ok(None);
}
// Split the parameters based on the comma delimiter // Split the parameters based on the comma delimiter
let params_list: Vec<&str> = fs.unwrap().split(',').collect(); let params_list: Vec<&str> = fs.split(',').collect();
let mut tag: &str = ""; let mut tag: &str = "";
let mut sock: &str = ""; let mut sock: &str = "";
@ -285,12 +282,12 @@ impl<'a> FsConfig<'a> {
.map_err(Error::ParseFsQueueSizeParam)?; .map_err(Error::ParseFsQueueSizeParam)?;
} }
Ok(Some(FsConfig { Ok(FsConfig {
tag, tag,
sock: Path::new(sock), sock: Path::new(sock),
num_queues, num_queues,
queue_size, queue_size,
})) })
} }
} }
@ -302,7 +299,7 @@ pub struct VmConfig<'a> {
pub disks: Vec<DiskConfig<'a>>, pub disks: Vec<DiskConfig<'a>>,
pub net: Option<NetConfig<'a>>, pub net: Option<NetConfig<'a>>,
pub rng: RngConfig<'a>, pub rng: RngConfig<'a>,
pub fs: Option<FsConfig<'a>>, pub fs: Option<Vec<FsConfig<'a>>>,
} }
impl<'a> VmConfig<'a> { impl<'a> VmConfig<'a> {
@ -312,6 +309,15 @@ impl<'a> VmConfig<'a> {
disks.push(DiskConfig::parse(disk)?); disks.push(DiskConfig::parse(disk)?);
} }
let mut fs: Option<Vec<FsConfig>> = None;
if let Some(fs_list) = &vm_params.fs {
let mut fs_config_list = Vec::new();
for item in fs_list.iter() {
fs_config_list.push(FsConfig::parse(item)?);
}
fs = Some(fs_config_list);
}
Ok(VmConfig { Ok(VmConfig {
cpus: CpusConfig::parse(vm_params.cpus)?, cpus: CpusConfig::parse(vm_params.cpus)?,
memory: MemoryConfig::parse(vm_params.memory)?, memory: MemoryConfig::parse(vm_params.memory)?,
@ -320,7 +326,7 @@ impl<'a> VmConfig<'a> {
disks, disks,
net: NetConfig::parse(vm_params.net)?, net: NetConfig::parse(vm_params.net)?,
rng: RngConfig::parse(vm_params.rng)?, rng: RngConfig::parse(vm_params.rng)?,
fs: FsConfig::parse(vm_params.fs)?, fs,
}) })
} }
} }

View File

@ -595,21 +595,28 @@ impl DeviceManager {
} }
// Add virtio-fs if required // Add virtio-fs if required
if let Some(fs_cfg) = &vm_cfg.fs { if let Some(fs_list_cfg) = &vm_cfg.fs {
if let Some(fs_sock) = fs_cfg.sock.to_str() { for fs_cfg in fs_list_cfg.iter() {
let virtio_fs_device = println!("####VIRTIO-FS config {:?}", fs_cfg);
vm_virtio::Fs::new(fs_sock, fs_cfg.tag, fs_cfg.num_queues, fs_cfg.queue_size) if let Some(fs_sock) = fs_cfg.sock.to_str() {
.map_err(DeviceManagerError::CreateVirtioFs)?; let virtio_fs_device = vm_virtio::Fs::new(
fs_sock,
fs_cfg.tag,
fs_cfg.num_queues,
fs_cfg.queue_size,
)
.map_err(DeviceManagerError::CreateVirtioFs)?;
DeviceManager::add_virtio_pci_device( DeviceManager::add_virtio_pci_device(
Box::new(virtio_fs_device), Box::new(virtio_fs_device),
memory.clone(), memory.clone(),
allocator, allocator,
vm_fd, vm_fd,
&mut pci_root, &mut pci_root,
&mut mmio_bus, &mut mmio_bus,
&interrupt_info, &interrupt_info,
)?; )?;
}
} }
} }