From a31f5f8106497fd9aac2c3874420b50861908391 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 16 Apr 2020 17:44:12 +0200 Subject: [PATCH] vhost_user_blk: Move disk initialization to VhostUserBlkBackend Anticipating the follow up patches to run multiple threads for the same backend, we need the initialization of the disk to happen in the high level structure VhostUserBlkBackend. Signed-off-by: Sebastien Boeuf --- vhost_user_block/src/lib.rs | 106 ++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/vhost_user_block/src/lib.rs b/vhost_user_block/src/lib.rs index 6be62ce3c..523e6cb5d 100644 --- a/vhost_user_block/src/lib.rs +++ b/vhost_user_block/src/lib.rs @@ -49,7 +49,7 @@ const BLK_SIZE: u32 = 512; // and the overhead of the emulation layer. const POLL_QUEUE_US: u128 = 50; -trait DiskFile: Read + Seek + Write + Send + Sync {} +pub trait DiskFile: Read + Seek + Write + Send + Sync {} impl DiskFile for D {} pub type Result = std::result::Result; @@ -102,59 +102,21 @@ pub struct VhostUserBlkThread { disk_image: Arc>, disk_image_id: Vec, disk_nsectors: u64, - config: virtio_blk_config, - rdonly: bool, - poll_queue: bool, event_idx: bool, kill_evt: EventFd, } impl VhostUserBlkThread { pub fn new( - image_path: String, - num_queues: usize, - rdonly: bool, - direct: bool, - poll_queue: bool, + disk_image: Arc>, + disk_image_id: Vec, + disk_nsectors: u64, ) -> Result { - let mut options = OpenOptions::new(); - options.read(true); - options.write(!rdonly); - if direct { - options.custom_flags(libc::O_DIRECT); - } - let image: File = options.open(&image_path).unwrap(); - let mut raw_img: vm_virtio::RawFile = vm_virtio::RawFile::new(image, direct); - - let image_id = build_disk_image_id(&PathBuf::from(&image_path)); - let image_type = qcow::detect_image_type(&mut raw_img).unwrap(); - let image = match image_type { - ImageType::Raw => Arc::new(Mutex::new(raw_img)) as Arc>, - ImageType::Qcow2 => { - Arc::new(Mutex::new(QcowFile::from(raw_img).unwrap())) as Arc> - } - }; - - let nsectors = (image.lock().unwrap().seek(SeekFrom::End(0)).unwrap() as u64) / SECTOR_SIZE; - let mut config = virtio_blk_config::default(); - - config.capacity = nsectors; - config.blk_size = BLK_SIZE; - config.size_max = 65535; - config.seg_max = 128 - 2; - config.min_io_size = 1; - config.opt_io_size = 1; - config.num_queues = num_queues as u16; - config.wce = 1; - Ok(VhostUserBlkThread { mem: None, - disk_image: image, - disk_image_id: image_id, - disk_nsectors: nsectors, - config, - rdonly, - poll_queue, + disk_image, + disk_image_id, + disk_nsectors, event_idx: false, kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?, }) @@ -220,6 +182,9 @@ impl VhostUserBlkThread { pub struct VhostUserBlkBackend { thread: Mutex, + config: virtio_blk_config, + rdonly: bool, + poll_queue: bool, } impl VhostUserBlkBackend { @@ -230,17 +195,50 @@ impl VhostUserBlkBackend { direct: bool, poll_queue: bool, ) -> Result { - let thread = Mutex::new(VhostUserBlkThread::new( - image_path, num_queues, rdonly, direct, poll_queue, - )?); + let mut options = OpenOptions::new(); + options.read(true); + options.write(!rdonly); + if direct { + options.custom_flags(libc::O_DIRECT); + } + let image: File = options.open(&image_path).unwrap(); + let mut raw_img: vm_virtio::RawFile = vm_virtio::RawFile::new(image, direct); - Ok(VhostUserBlkBackend { thread }) + let image_id = build_disk_image_id(&PathBuf::from(&image_path)); + let image_type = qcow::detect_image_type(&mut raw_img).unwrap(); + let image = match image_type { + ImageType::Raw => Arc::new(Mutex::new(raw_img)) as Arc>, + ImageType::Qcow2 => { + Arc::new(Mutex::new(QcowFile::from(raw_img).unwrap())) as Arc> + } + }; + + let nsectors = (image.lock().unwrap().seek(SeekFrom::End(0)).unwrap() as u64) / SECTOR_SIZE; + let mut config = virtio_blk_config::default(); + + config.capacity = nsectors; + config.blk_size = BLK_SIZE; + config.size_max = 65535; + config.seg_max = 128 - 2; + config.min_io_size = 1; + config.opt_io_size = 1; + config.num_queues = num_queues as u16; + config.wce = 1; + + let thread = Mutex::new(VhostUserBlkThread::new(image, image_id, nsectors)?); + + Ok(VhostUserBlkBackend { + thread, + config, + rdonly, + poll_queue, + }) } } impl VhostUserBackend for VhostUserBlkBackend { fn num_queues(&self) -> usize { - self.thread.lock().unwrap().config.num_queues as usize + self.config.num_queues as usize } fn max_queue_size(&self) -> usize { @@ -254,7 +252,7 @@ impl VhostUserBackend for VhostUserBlkBackend { | 1 << VIRTIO_F_VERSION_1 | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); - if self.thread.lock().unwrap().rdonly { + if self.rdonly { avail_features |= 1 << VIRTIO_BLK_F_RO; } avail_features @@ -288,10 +286,10 @@ impl VhostUserBackend for VhostUserBlkBackend { let mut thread = self.thread.lock().unwrap(); match device_event { - q if device_event < thread.config.num_queues => { + q if device_event < self.config.num_queues => { let mut vring = vrings[q as usize].write().unwrap(); - if thread.poll_queue { + if self.poll_queue { // Actively poll the queue until POLL_QUEUE_US has passed // without seeing a new request. let mut now = Instant::now(); @@ -332,7 +330,7 @@ impl VhostUserBackend for VhostUserBlkBackend { // self.config is a statically allocated virtio_blk_config let buf = unsafe { slice::from_raw_parts( - &self.thread.lock().unwrap().config as *const virtio_blk_config as *const _, + &self.config as *const virtio_blk_config as *const _, mem::size_of::(), ) };