From 2be703ca92f836a02a7d3a6fe33705ae5f9c421d Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 13 Mar 2020 09:38:42 +0000 Subject: [PATCH] vmm: device_manager: Refactor make_virtio_block_devices Split it into a method that creates a single device which is called by the multiple device version so this can be used when dynamically adding a device. Signed-off-by: Rob Bradford --- vmm/src/device_manager.rs | 205 ++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 98 deletions(-) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 3d42113d1..ae6e54ae9 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1054,110 +1054,119 @@ impl DeviceManager { Ok(sock) } + fn make_virtio_block_device( + &mut self, + disk_cfg: &DiskConfig, + ) -> DeviceManagerResult<(VirtioDeviceArc, bool)> { + if disk_cfg.vhost_user { + let sock = if let Some(sock) = disk_cfg.vhost_socket.clone() { + sock + } else { + self.start_block_backend(disk_cfg)? + }; + let vu_cfg = VhostUserConfig { + sock, + num_queues: disk_cfg.num_queues, + queue_size: disk_cfg.queue_size, + }; + let vhost_user_block_device = Arc::new(Mutex::new( + vm_virtio::vhost_user::Blk::new(disk_cfg.wce, vu_cfg) + .map_err(DeviceManagerError::CreateVhostUserBlk)?, + )); + + self.migratable_devices + .push(Arc::clone(&vhost_user_block_device) as Arc>); + + Ok(( + Arc::clone(&vhost_user_block_device) as Arc>, + false, + )) + } else { + let mut options = OpenOptions::new(); + options.read(true); + options.write(!disk_cfg.readonly); + if disk_cfg.direct { + options.custom_flags(libc::O_DIRECT); + } + // Open block device path + let image: File = options + .open( + disk_cfg + .path + .as_ref() + .ok_or(DeviceManagerError::NoDiskPath)? + .clone(), + ) + .map_err(DeviceManagerError::Disk)?; + + let mut raw_img = vm_virtio::RawFile::new(image, disk_cfg.direct); + + let image_type = qcow::detect_image_type(&mut raw_img) + .map_err(DeviceManagerError::DetectImageType)?; + match image_type { + ImageType::Raw => { + let dev = vm_virtio::Block::new( + raw_img, + disk_cfg + .path + .as_ref() + .ok_or(DeviceManagerError::NoDiskPath)? + .clone(), + disk_cfg.readonly, + disk_cfg.iommu, + disk_cfg.num_queues, + disk_cfg.queue_size, + ) + .map_err(DeviceManagerError::CreateVirtioBlock)?; + + let block = Arc::new(Mutex::new(dev)); + + self.migratable_devices + .push(Arc::clone(&block) as Arc>); + + Ok(( + Arc::clone(&block) as Arc>, + disk_cfg.iommu, + )) + } + ImageType::Qcow2 => { + let qcow_img = + QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?; + let dev = vm_virtio::Block::new( + qcow_img, + disk_cfg + .path + .as_ref() + .ok_or(DeviceManagerError::NoDiskPath)? + .clone(), + disk_cfg.readonly, + disk_cfg.iommu, + disk_cfg.num_queues, + disk_cfg.queue_size, + ) + .map_err(DeviceManagerError::CreateVirtioBlock)?; + + let block = Arc::new(Mutex::new(dev)); + + self.migratable_devices + .push(Arc::clone(&block) as Arc>); + + Ok(( + Arc::clone(&block) as Arc>, + disk_cfg.iommu, + )) + } + } + } + } + fn make_virtio_block_devices(&mut self) -> DeviceManagerResult> { let mut devices = Vec::new(); let block_devices = self.config.lock().unwrap().disks.clone(); if let Some(disk_list_cfg) = &block_devices { for disk_cfg in disk_list_cfg.iter() { - if disk_cfg.vhost_user { - let sock = if let Some(sock) = disk_cfg.vhost_socket.clone() { - sock - } else { - self.start_block_backend(disk_cfg)? - }; - let vu_cfg = VhostUserConfig { - sock, - num_queues: disk_cfg.num_queues, - queue_size: disk_cfg.queue_size, - }; - let vhost_user_block_device = Arc::new(Mutex::new( - vm_virtio::vhost_user::Blk::new(disk_cfg.wce, vu_cfg) - .map_err(DeviceManagerError::CreateVhostUserBlk)?, - )); - - devices.push(( - Arc::clone(&vhost_user_block_device) - as Arc>, - false, - )); - - self.migratable_devices - .push(Arc::clone(&vhost_user_block_device) as Arc>); - } else { - let mut options = OpenOptions::new(); - options.read(true); - options.write(!disk_cfg.readonly); - if disk_cfg.direct { - options.custom_flags(libc::O_DIRECT); - } - // Open block device path - let image: File = options - .open( - &disk_cfg - .path - .as_ref() - .ok_or(DeviceManagerError::NoDiskPath)?, - ) - .map_err(DeviceManagerError::Disk)?; - - let mut raw_img = vm_virtio::RawFile::new(image, disk_cfg.direct); - - let image_type = qcow::detect_image_type(&mut raw_img) - .map_err(DeviceManagerError::DetectImageType)?; - match image_type { - ImageType::Raw => { - let dev = vm_virtio::Block::new( - raw_img, - disk_cfg - .path - .as_ref() - .ok_or(DeviceManagerError::NoDiskPath)? - .clone(), - disk_cfg.readonly, - disk_cfg.iommu, - disk_cfg.num_queues, - disk_cfg.queue_size, - ) - .map_err(DeviceManagerError::CreateVirtioBlock)?; - - let block = Arc::new(Mutex::new(dev)); - - devices.push(( - Arc::clone(&block) as Arc>, - disk_cfg.iommu, - )); - self.migratable_devices - .push(Arc::clone(&block) as Arc>); - } - ImageType::Qcow2 => { - let qcow_img = QcowFile::from(raw_img) - .map_err(DeviceManagerError::QcowDeviceCreate)?; - let dev = vm_virtio::Block::new( - qcow_img, - disk_cfg - .path - .as_ref() - .ok_or(DeviceManagerError::NoDiskPath)? - .clone(), - disk_cfg.readonly, - disk_cfg.iommu, - disk_cfg.num_queues, - disk_cfg.queue_size, - ) - .map_err(DeviceManagerError::CreateVirtioBlock)?; - - let block = Arc::new(Mutex::new(dev)); - - devices.push(( - Arc::clone(&block) as Arc>, - disk_cfg.iommu, - )); - self.migratable_devices - .push(Arc::clone(&block) as Arc>); - } - }; - } + devices.push(self.make_virtio_block_device(disk_cfg)?); } }