mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-20 15:01:16 +00:00
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 <sebastien.boeuf@intel.com>
This commit is contained in:
parent
e78e34b36a
commit
a31f5f8106
@ -49,7 +49,7 @@ const BLK_SIZE: u32 = 512;
|
|||||||
// and the overhead of the emulation layer.
|
// and the overhead of the emulation layer.
|
||||||
const POLL_QUEUE_US: u128 = 50;
|
const POLL_QUEUE_US: u128 = 50;
|
||||||
|
|
||||||
trait DiskFile: Read + Seek + Write + Send + Sync {}
|
pub trait DiskFile: Read + Seek + Write + Send + Sync {}
|
||||||
impl<D: Read + Seek + Write + Send + Sync> DiskFile for D {}
|
impl<D: Read + Seek + Write + Send + Sync> DiskFile for D {}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
@ -102,59 +102,21 @@ pub struct VhostUserBlkThread {
|
|||||||
disk_image: Arc<Mutex<dyn DiskFile>>,
|
disk_image: Arc<Mutex<dyn DiskFile>>,
|
||||||
disk_image_id: Vec<u8>,
|
disk_image_id: Vec<u8>,
|
||||||
disk_nsectors: u64,
|
disk_nsectors: u64,
|
||||||
config: virtio_blk_config,
|
|
||||||
rdonly: bool,
|
|
||||||
poll_queue: bool,
|
|
||||||
event_idx: bool,
|
event_idx: bool,
|
||||||
kill_evt: EventFd,
|
kill_evt: EventFd,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VhostUserBlkThread {
|
impl VhostUserBlkThread {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
image_path: String,
|
disk_image: Arc<Mutex<dyn DiskFile>>,
|
||||||
num_queues: usize,
|
disk_image_id: Vec<u8>,
|
||||||
rdonly: bool,
|
disk_nsectors: u64,
|
||||||
direct: bool,
|
|
||||||
poll_queue: bool,
|
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
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<Mutex<dyn DiskFile>>,
|
|
||||||
ImageType::Qcow2 => {
|
|
||||||
Arc::new(Mutex::new(QcowFile::from(raw_img).unwrap())) as Arc<Mutex<dyn DiskFile>>
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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 {
|
Ok(VhostUserBlkThread {
|
||||||
mem: None,
|
mem: None,
|
||||||
disk_image: image,
|
disk_image,
|
||||||
disk_image_id: image_id,
|
disk_image_id,
|
||||||
disk_nsectors: nsectors,
|
disk_nsectors,
|
||||||
config,
|
|
||||||
rdonly,
|
|
||||||
poll_queue,
|
|
||||||
event_idx: false,
|
event_idx: false,
|
||||||
kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?,
|
kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?,
|
||||||
})
|
})
|
||||||
@ -220,6 +182,9 @@ impl VhostUserBlkThread {
|
|||||||
|
|
||||||
pub struct VhostUserBlkBackend {
|
pub struct VhostUserBlkBackend {
|
||||||
thread: Mutex<VhostUserBlkThread>,
|
thread: Mutex<VhostUserBlkThread>,
|
||||||
|
config: virtio_blk_config,
|
||||||
|
rdonly: bool,
|
||||||
|
poll_queue: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VhostUserBlkBackend {
|
impl VhostUserBlkBackend {
|
||||||
@ -230,17 +195,50 @@ impl VhostUserBlkBackend {
|
|||||||
direct: bool,
|
direct: bool,
|
||||||
poll_queue: bool,
|
poll_queue: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let thread = Mutex::new(VhostUserBlkThread::new(
|
let mut options = OpenOptions::new();
|
||||||
image_path, num_queues, rdonly, direct, poll_queue,
|
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<Mutex<dyn DiskFile>>,
|
||||||
|
ImageType::Qcow2 => {
|
||||||
|
Arc::new(Mutex::new(QcowFile::from(raw_img).unwrap())) as Arc<Mutex<dyn DiskFile>>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 {
|
impl VhostUserBackend for VhostUserBlkBackend {
|
||||||
fn num_queues(&self) -> usize {
|
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 {
|
fn max_queue_size(&self) -> usize {
|
||||||
@ -254,7 +252,7 @@ impl VhostUserBackend for VhostUserBlkBackend {
|
|||||||
| 1 << VIRTIO_F_VERSION_1
|
| 1 << VIRTIO_F_VERSION_1
|
||||||
| VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits();
|
| VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits();
|
||||||
|
|
||||||
if self.thread.lock().unwrap().rdonly {
|
if self.rdonly {
|
||||||
avail_features |= 1 << VIRTIO_BLK_F_RO;
|
avail_features |= 1 << VIRTIO_BLK_F_RO;
|
||||||
}
|
}
|
||||||
avail_features
|
avail_features
|
||||||
@ -288,10 +286,10 @@ impl VhostUserBackend for VhostUserBlkBackend {
|
|||||||
|
|
||||||
let mut thread = self.thread.lock().unwrap();
|
let mut thread = self.thread.lock().unwrap();
|
||||||
match device_event {
|
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();
|
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
|
// Actively poll the queue until POLL_QUEUE_US has passed
|
||||||
// without seeing a new request.
|
// without seeing a new request.
|
||||||
let mut now = Instant::now();
|
let mut now = Instant::now();
|
||||||
@ -332,7 +330,7 @@ impl VhostUserBackend for VhostUserBlkBackend {
|
|||||||
// self.config is a statically allocated virtio_blk_config
|
// self.config is a statically allocated virtio_blk_config
|
||||||
let buf = unsafe {
|
let buf = unsafe {
|
||||||
slice::from_raw_parts(
|
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::<virtio_blk_config>(),
|
mem::size_of::<virtio_blk_config>(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user