vmm: add vhost-user-blk support

Update vm configuration and device initial process to add
vhost-user-blk support.

Signed-off-by: Yang Zhong <yang.zhong@intel.com>
This commit is contained in:
Yang Zhong 2019-09-11 11:16:41 +08:00 committed by Samuel Ortiz
parent c7559bb7a4
commit 4164853ec6
2 changed files with 97 additions and 0 deletions

View File

@ -71,6 +71,8 @@ pub enum Error<'a> {
ParseVuQueueSizeParam(std::num::ParseIntError),
/// Failed parsing vhost-user-net server parameter.
ParseVuNetServerParam(std::num::ParseIntError),
/// Failed parsing vhost-user-blk wce parameter.
ParseVuBlkWceParam(std::str::ParseBoolError),
/// Failed parsing vsock context ID parameter.
ParseVsockCidParam(std::num::ParseIntError),
/// Failed parsing vsock socket path parameter.
@ -92,6 +94,7 @@ pub struct VmParams<'a> {
pub console: &'a str,
pub devices: Option<Vec<&'a str>>,
pub vhost_user_net: Option<Vec<&'a str>>,
pub vhost_user_blk: Option<Vec<&'a str>>,
pub vsock: Option<Vec<&'a str>>,
}
@ -550,6 +553,61 @@ impl<'a> VsockConfig<'a> {
}
}
pub struct VhostUserBlkConfig<'a> {
pub wce: bool,
pub vu_cfg: VhostUserConfig<'a>,
}
impl<'a> VhostUserBlkConfig<'a> {
pub fn parse(vhost_user_blk: &'a str) -> Result<Self> {
// Split the parameters based on the comma delimiter
let params_list: Vec<&str> = vhost_user_blk.split(',').collect();
let mut sock: &str = "";
let mut num_queues_str: &str = "";
let mut queue_size_str: &str = "";
let mut wce_str: &str = "";
for param in params_list.iter() {
if param.starts_with("sock=") {
sock = &param[5..];
} else if param.starts_with("num_queues=") {
num_queues_str = &param[11..];
} else if param.starts_with("queue_size=") {
queue_size_str = &param[11..];
} else if param.starts_with("wce=") {
wce_str = &param[4..];
}
}
let mut num_queues: usize = 1;
let mut queue_size: u16 = 128;
let mut wce: bool = true;
if !num_queues_str.is_empty() {
num_queues = num_queues_str
.parse()
.map_err(Error::ParseVuNumQueuesParam)?;
}
if !queue_size_str.is_empty() {
queue_size = queue_size_str
.parse()
.map_err(Error::ParseVuQueueSizeParam)?;
}
if !wce_str.is_empty() {
wce = wce_str.parse().map_err(Error::ParseVuBlkWceParam)?;
}
let vu_cfg = VhostUserConfig {
sock,
num_queues,
queue_size,
};
Ok(VhostUserBlkConfig { wce, vu_cfg })
}
}
pub struct VmConfig<'a> {
pub cpus: CpusConfig,
pub memory: MemoryConfig<'a>,
@ -564,6 +622,7 @@ pub struct VmConfig<'a> {
pub console: ConsoleConfig<'a>,
pub devices: Option<Vec<DeviceConfig<'a>>>,
pub vhost_user_net: Option<Vec<VhostUserNetConfig<'a>>>,
pub vhost_user_blk: Option<Vec<VhostUserBlkConfig<'a>>>,
pub vsock: Option<Vec<VsockConfig<'a>>>,
}
@ -638,6 +697,15 @@ impl<'a> VmConfig<'a> {
vsock = Some(vsock_config_list);
}
let mut vhost_user_blk: Option<Vec<VhostUserBlkConfig>> = None;
if let Some(vhost_user_blk_list) = &vm_params.vhost_user_blk {
let mut vhost_user_blk_config_list = Vec::new();
for item in vhost_user_blk_list.iter() {
vhost_user_blk_config_list.push(VhostUserBlkConfig::parse(item)?);
}
vhost_user_blk = Some(vhost_user_blk_config_list);
}
Ok(VmConfig {
cpus: CpusConfig::parse(vm_params.cpus)?,
memory: MemoryConfig::parse(vm_params.memory)?,
@ -652,6 +720,7 @@ impl<'a> VmConfig<'a> {
console,
devices,
vhost_user_net,
vhost_user_blk,
vsock,
})
}

View File

@ -78,6 +78,9 @@ pub enum DeviceManagerError {
/// Cannot create virtio-fs device
CreateVirtioFs(vm_virtio::vhost_user::Error),
/// Cannot create vhost-user-blk device
CreateVhostUserBlk(vm_virtio::vhost_user::Error),
/// Cannot create virtio-pmem device
CreateVirtioPmem(io::Error),
@ -515,6 +518,11 @@ impl DeviceManager {
vm_info,
)?);
// Add virtio-vhost-user-blk if required
devices.append(&mut DeviceManager::make_virtio_vhost_user_blk_devices(
vm_info,
)?);
// Add virtio-vsock if required
devices.append(&mut DeviceManager::make_virtio_vsock_devices(vm_info)?);
@ -778,6 +786,26 @@ impl DeviceManager {
Ok(devices)
}
fn make_virtio_vhost_user_blk_devices(
vm_info: &VmInfo,
) -> DeviceManagerResult<Vec<Box<dyn vm_virtio::VirtioDevice>>> {
let mut devices = Vec::new();
// Add vhost-user-blk if required
if let Some(vhost_user_blk_list_cfg) = &vm_info.vm_cfg.vhost_user_blk {
for vhost_user_blk_cfg in vhost_user_blk_list_cfg.iter() {
let vhost_user_blk_device = vm_virtio::vhost_user::Blk::new(
vhost_user_blk_cfg.wce,
vhost_user_blk_cfg.vu_cfg,
)
.map_err(DeviceManagerError::CreateVhostUserBlk)?;
devices.push(Box::new(vhost_user_blk_device) as Box<dyn vm_virtio::VirtioDevice>);
}
}
Ok(devices)
}
fn make_virtio_vsock_devices(
vm_info: &VmInfo,
) -> DeviceManagerResult<Vec<Box<dyn vm_virtio::VirtioDevice>>> {