block_util: Add synchronous support for fixed VHD disk files

Relying on the simplified version of the synchronous support for RAW
disk files, the new fixed_vhd_sync module in the block_util crate
introduces the synchronous support for fixed VHD disk files.

With this patch, the fixed VHD support is complete as it is implemented
in both synchronous and asynchronous versions.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-01-28 16:23:03 +01:00 committed by Rob Bradford
parent c6854c5a97
commit 24c8cce012
3 changed files with 118 additions and 3 deletions

View File

@ -0,0 +1,107 @@
// Copyright © 2021 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
use crate::async_io::{
AsyncIo, AsyncIoError, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult,
};
use crate::raw_sync::RawFileSync;
use crate::vhd::VhdFooter;
use std::fs::File;
use std::os::unix::io::{AsRawFd, RawFd};
use vmm_sys_util::eventfd::EventFd;
pub struct FixedVhdDiskSync {
file: File,
size: u64,
}
impl FixedVhdDiskSync {
pub fn new(mut file: File) -> std::io::Result<Self> {
let footer = VhdFooter::new(&mut file)?;
Ok(FixedVhdDiskSync {
file,
size: footer.current_size(),
})
}
}
impl DiskFile for FixedVhdDiskSync {
fn size(&mut self) -> DiskFileResult<u64> {
Ok(self.size)
}
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
Ok(Box::new(
FixedVhdSync::new(self.file.as_raw_fd(), self.size)
.map_err(DiskFileError::NewAsyncIo)?,
) as Box<dyn AsyncIo>)
}
}
pub struct FixedVhdSync {
raw_file_sync: RawFileSync,
size: u64,
}
impl FixedVhdSync {
pub fn new(fd: RawFd, size: u64) -> std::io::Result<Self> {
Ok(FixedVhdSync {
raw_file_sync: RawFileSync::new(fd),
size,
})
}
}
impl AsyncIo for FixedVhdSync {
fn notifier(&self) -> &EventFd {
self.raw_file_sync.notifier()
}
fn read_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::ReadVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_sync.read_vectored(offset, iovecs, user_data)
}
fn write_vectored(
&mut self,
offset: libc::off_t,
iovecs: Vec<libc::iovec>,
user_data: u64,
) -> AsyncIoResult<()> {
if offset as u64 >= self.size {
return Err(AsyncIoError::WriteVectored(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid offset {}, can't be larger than file size {}",
offset, self.size
),
)));
}
self.raw_file_sync.write_vectored(offset, iovecs, user_data)
}
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
self.raw_file_sync.fsync(user_data)
}
fn complete(&mut self) -> Vec<(u64, i32)> {
self.raw_file_sync.complete()
}
}

View File

@ -15,6 +15,7 @@ extern crate serde_derive;
pub mod async_io; pub mod async_io;
pub mod fixed_vhd_async; pub mod fixed_vhd_async;
pub mod fixed_vhd_sync;
pub mod qcow_sync; pub mod qcow_sync;
pub mod raw_async; pub mod raw_async;
pub mod raw_sync; pub mod raw_sync;

View File

@ -40,8 +40,8 @@ use arch::layout::{APIC_START, IOAPIC_SIZE, IOAPIC_START};
use arch::DeviceType; use arch::DeviceType;
use block_util::{ use block_util::{
async_io::DiskFile, block_io_uring_is_supported, detect_image_type, async_io::DiskFile, block_io_uring_is_supported, detect_image_type,
fixed_vhd_async::FixedVhdDiskAsync, qcow_sync::QcowDiskSync, raw_async::RawFileDisk, fixed_vhd_async::FixedVhdDiskAsync, fixed_vhd_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync,
raw_sync::RawFileDiskSync, ImageType, raw_async::RawFileDisk, raw_sync::RawFileDiskSync, ImageType,
}; };
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
use devices::gic; use devices::gic;
@ -383,6 +383,9 @@ pub enum DeviceManagerError {
/// Failed to create FixedVhdDiskAsync /// Failed to create FixedVhdDiskAsync
CreateFixedVhdDiskAsync(io::Error), CreateFixedVhdDiskAsync(io::Error),
/// Failed to create FixedVhdDiskSync
CreateFixedVhdDiskSync(io::Error),
} }
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>; pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
@ -1675,7 +1678,11 @@ impl DeviceManager {
.map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?, .map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?,
) as Box<dyn DiskFile> ) as Box<dyn DiskFile>
} else { } else {
unimplemented!("No synchronous implementation for fixed VHD files"); info!("Using synchronous fixed VHD disk file");
Box::new(
FixedVhdDiskSync::new(file)
.map_err(DeviceManagerError::CreateFixedVhdDiskSync)?,
) as Box<dyn DiskFile>
} }
} }
ImageType::Raw => { ImageType::Raw => {