mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +00:00
block_util, vhdx: vhdx crate integration with the cloud hypervisor
vhdx_sync.rs in block_util implements traits to represent the vhdx crate as a supported block device in the cloud hypervisor. The vhdx is added to the block device list in device_manager.rs at the vmm crate so that it can automatically detect a vhdx disk and invoke the corresponding crate. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Signed-off-by: Fazla Mehrab <akm.fazla.mehrab@intel.com>
This commit is contained in:
parent
452af9b17c
commit
5db4dede28
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -141,6 +141,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"versionize",
|
"versionize",
|
||||||
"versionize_derive",
|
"versionize_derive",
|
||||||
|
"vhdx",
|
||||||
"virtio-bindings",
|
"virtio-bindings",
|
||||||
"vm-memory 0.6.0",
|
"vm-memory 0.6.0",
|
||||||
"vm-virtio",
|
"vm-virtio",
|
||||||
@ -224,6 +225,15 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32c"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "210cdf933e6a81212bfabf90cd8762f471b5922e5f6b709547673ad8e04b9448"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc64"
|
name = "crc64"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -860,6 +870,15 @@ version = "0.1.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
|
checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
@ -880,6 +899,21 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.127"
|
version = "1.0.127"
|
||||||
@ -1058,6 +1092,9 @@ name = "uuid"
|
|||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
@ -1137,6 +1174,20 @@ dependencies = [
|
|||||||
"vmm-sys-util",
|
"vmm-sys-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vhdx"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"crc32c",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"remain",
|
||||||
|
"thiserror",
|
||||||
|
"uuid",
|
||||||
|
"vmm-sys-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vhost"
|
name = "vhost"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -1347,6 +1398,7 @@ dependencies = [
|
|||||||
"versionize",
|
"versionize",
|
||||||
"versionize_derive",
|
"versionize_derive",
|
||||||
"vfio-ioctls",
|
"vfio-ioctls",
|
||||||
|
"vhdx",
|
||||||
"virtio-devices",
|
"virtio-devices",
|
||||||
"vm-allocator",
|
"vm-allocator",
|
||||||
"vm-device",
|
"vm-device",
|
||||||
|
@ -78,6 +78,7 @@ members = [
|
|||||||
"qcow",
|
"qcow",
|
||||||
"rate_limiter",
|
"rate_limiter",
|
||||||
"vfio_user",
|
"vfio_user",
|
||||||
|
"vhdx",
|
||||||
"vhost_user_backend",
|
"vhost_user_backend",
|
||||||
"vhost_user_block",
|
"vhost_user_block",
|
||||||
"vhost_user_net",
|
"vhost_user_net",
|
||||||
|
@ -16,6 +16,7 @@ qcow = { path = "../qcow" }
|
|||||||
thiserror = "1.0.26"
|
thiserror = "1.0.26"
|
||||||
versionize = "0.1.6"
|
versionize = "0.1.6"
|
||||||
versionize_derive = "0.1.4"
|
versionize_derive = "0.1.4"
|
||||||
|
vhdx = { path = "../vhdx" }
|
||||||
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
|
virtio-bindings = { version = "0.1.0", features = ["virtio-v5_0_0"] }
|
||||||
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
|
vm-memory = { version = "0.6.0", features = ["backend-mmap", "backend-atomic", "backend-bitmap"] }
|
||||||
vm-virtio = { path = "../vm-virtio" }
|
vm-virtio = { path = "../vm-virtio" }
|
||||||
|
@ -18,6 +18,7 @@ pub mod qcow_sync;
|
|||||||
pub mod raw_async;
|
pub mod raw_async;
|
||||||
pub mod raw_sync;
|
pub mod raw_sync;
|
||||||
pub mod vhd;
|
pub mod vhd;
|
||||||
|
pub mod vhdx_sync;
|
||||||
|
|
||||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, DiskFileError, DiskFileResult};
|
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult, DiskFileError, DiskFileResult};
|
||||||
#[cfg(feature = "io_uring")]
|
#[cfg(feature = "io_uring")]
|
||||||
@ -602,9 +603,11 @@ pub enum ImageType {
|
|||||||
FixedVhd,
|
FixedVhd,
|
||||||
Qcow2,
|
Qcow2,
|
||||||
Raw,
|
Raw,
|
||||||
|
Vhdx,
|
||||||
}
|
}
|
||||||
|
|
||||||
const QCOW_MAGIC: u32 = 0x5146_49fb;
|
const QCOW_MAGIC: u32 = 0x5146_49fb;
|
||||||
|
const VHDX_SIGN: u64 = 0x656C_6966_7864_6876;
|
||||||
|
|
||||||
/// Determine image type through file parsing.
|
/// Determine image type through file parsing.
|
||||||
pub fn detect_image_type(f: &mut File) -> std::io::Result<ImageType> {
|
pub fn detect_image_type(f: &mut File) -> std::io::Result<ImageType> {
|
||||||
@ -623,6 +626,8 @@ pub fn detect_image_type(f: &mut File) -> std::io::Result<ImageType> {
|
|||||||
ImageType::Qcow2
|
ImageType::Qcow2
|
||||||
} else if vhd::is_fixed_vhd(f)? {
|
} else if vhd::is_fixed_vhd(f)? {
|
||||||
ImageType::FixedVhd
|
ImageType::FixedVhd
|
||||||
|
} else if u64::from_le_bytes(s.data[0..8].try_into().unwrap()) == VHDX_SIGN {
|
||||||
|
ImageType::Vhdx
|
||||||
} else {
|
} else {
|
||||||
ImageType::Raw
|
ImageType::Raw
|
||||||
};
|
};
|
||||||
|
113
block_util/src/vhdx_sync.rs
Normal file
113
block_util/src/vhdx_sync.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright © 2021 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use crate::async_io::{AsyncIo, AsyncIoResult, DiskFile, DiskFileError, DiskFileResult};
|
||||||
|
use crate::{fsync_sync, read_vectored_sync, write_vectored_sync};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use vhdx::vhdx::{Result as VhdxResult, Vhdx};
|
||||||
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
|
pub struct VhdxDiskSync {
|
||||||
|
vhdx_file: Arc<Mutex<Vhdx>>,
|
||||||
|
semaphore: Arc<Mutex<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VhdxDiskSync {
|
||||||
|
pub fn new(f: File) -> VhdxResult<Self> {
|
||||||
|
let vhdx = Vhdx::new(f)?;
|
||||||
|
let vhdx_file = Arc::new(Mutex::new(vhdx));
|
||||||
|
|
||||||
|
Ok(VhdxDiskSync {
|
||||||
|
vhdx_file,
|
||||||
|
semaphore: Arc::new(Mutex::new(())),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiskFile for VhdxDiskSync {
|
||||||
|
fn size(&mut self) -> DiskFileResult<u64> {
|
||||||
|
Ok(self.vhdx_file.lock().unwrap().virtual_disk_size())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_async_io(&self, _ring_depth: u32) -> DiskFileResult<Box<dyn AsyncIo>> {
|
||||||
|
Ok(Box::new(
|
||||||
|
VhdxSync::new(self.vhdx_file.clone(), self.semaphore.clone())
|
||||||
|
.map_err(DiskFileError::NewAsyncIo)?,
|
||||||
|
) as Box<dyn AsyncIo>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VhdxSync {
|
||||||
|
vhdx_file: Arc<Mutex<Vhdx>>,
|
||||||
|
eventfd: EventFd,
|
||||||
|
completion_list: Vec<(u64, i32)>,
|
||||||
|
semaphore: Arc<Mutex<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VhdxSync {
|
||||||
|
pub fn new(vhdx_file: Arc<Mutex<Vhdx>>, semaphore: Arc<Mutex<()>>) -> std::io::Result<Self> {
|
||||||
|
Ok(VhdxSync {
|
||||||
|
vhdx_file,
|
||||||
|
eventfd: EventFd::new(libc::EFD_NONBLOCK)?,
|
||||||
|
completion_list: Vec::new(),
|
||||||
|
semaphore,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncIo for VhdxSync {
|
||||||
|
fn notifier(&self) -> &EventFd {
|
||||||
|
&self.eventfd
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_vectored(
|
||||||
|
&mut self,
|
||||||
|
offset: libc::off_t,
|
||||||
|
iovecs: Vec<libc::iovec>,
|
||||||
|
user_data: u64,
|
||||||
|
) -> AsyncIoResult<()> {
|
||||||
|
read_vectored_sync(
|
||||||
|
offset,
|
||||||
|
iovecs,
|
||||||
|
user_data,
|
||||||
|
self.vhdx_file.lock().unwrap().deref_mut(),
|
||||||
|
&self.eventfd,
|
||||||
|
&mut self.completion_list,
|
||||||
|
&mut self.semaphore,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_vectored(
|
||||||
|
&mut self,
|
||||||
|
offset: libc::off_t,
|
||||||
|
iovecs: Vec<libc::iovec>,
|
||||||
|
user_data: u64,
|
||||||
|
) -> AsyncIoResult<()> {
|
||||||
|
write_vectored_sync(
|
||||||
|
offset,
|
||||||
|
iovecs,
|
||||||
|
user_data,
|
||||||
|
self.vhdx_file.lock().unwrap().deref_mut(),
|
||||||
|
&self.eventfd,
|
||||||
|
&mut self.completion_list,
|
||||||
|
&mut self.semaphore,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fsync(&mut self, user_data: Option<u64>) -> AsyncIoResult<()> {
|
||||||
|
fsync_sync(
|
||||||
|
user_data,
|
||||||
|
self.vhdx_file.lock().unwrap().deref_mut(),
|
||||||
|
&self.eventfd,
|
||||||
|
&mut self.completion_list,
|
||||||
|
&mut self.semaphore,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn complete(&mut self) -> Vec<(u64, i32)> {
|
||||||
|
self.completion_list.drain(..).collect()
|
||||||
|
}
|
||||||
|
}
|
@ -111,6 +111,7 @@ fn virtio_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
|
|||||||
(libc::SYS_fsync, vec![]),
|
(libc::SYS_fsync, vec![]),
|
||||||
(libc::SYS_ftruncate, vec![]),
|
(libc::SYS_ftruncate, vec![]),
|
||||||
(libc::SYS_futex, vec![]),
|
(libc::SYS_futex, vec![]),
|
||||||
|
(libc::SYS_getrandom, vec![]),
|
||||||
(libc::SYS_io_uring_enter, vec![]),
|
(libc::SYS_io_uring_enter, vec![]),
|
||||||
(libc::SYS_lseek, vec![]),
|
(libc::SYS_lseek, vec![]),
|
||||||
(libc::SYS_madvise, vec![]),
|
(libc::SYS_madvise, vec![]),
|
||||||
|
@ -45,6 +45,7 @@ uuid = "0.8.2"
|
|||||||
versionize = "0.1.6"
|
versionize = "0.1.6"
|
||||||
versionize_derive = "0.1.4"
|
versionize_derive = "0.1.4"
|
||||||
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio-ioctls", branch = "master", default-features = false }
|
vfio-ioctls = { git = "https://github.com/rust-vmm/vfio-ioctls", branch = "master", default-features = false }
|
||||||
|
vhdx = { path = "../vhdx" }
|
||||||
virtio-devices = { path = "../virtio-devices" }
|
virtio-devices = { path = "../virtio-devices" }
|
||||||
vm-allocator = { path = "../vm-allocator" }
|
vm-allocator = { path = "../vm-allocator" }
|
||||||
vm-device = { path = "../vm-device" }
|
vm-device = { path = "../vm-device" }
|
||||||
|
@ -39,7 +39,7 @@ use arch::{DeviceType, MmioDeviceInfo};
|
|||||||
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, fixed_vhd_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync,
|
fixed_vhd_async::FixedVhdDiskAsync, fixed_vhd_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync,
|
||||||
raw_async::RawFileDisk, raw_sync::RawFileDiskSync, ImageType,
|
raw_async::RawFileDisk, raw_sync::RawFileDiskSync, vhdx_sync::VhdxDiskSync, ImageType,
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::gic;
|
use devices::gic;
|
||||||
@ -420,6 +420,9 @@ pub enum DeviceManagerError {
|
|||||||
/// Failed to create QcowDiskSync
|
/// Failed to create QcowDiskSync
|
||||||
CreateQcowDiskSync(qcow::Error),
|
CreateQcowDiskSync(qcow::Error),
|
||||||
|
|
||||||
|
/// Failed to create FixedVhdxDiskSync
|
||||||
|
CreateFixedVhdxDiskSync(vhdx::vhdx::VhdxError),
|
||||||
|
|
||||||
/// Failed adding DMA mapping handler to virtio-mem device.
|
/// Failed adding DMA mapping handler to virtio-mem device.
|
||||||
AddDmaMappingHandlerVirtioMem(virtio_devices::mem::Error),
|
AddDmaMappingHandlerVirtioMem(virtio_devices::mem::Error),
|
||||||
|
|
||||||
@ -1944,6 +1947,13 @@ impl DeviceManager {
|
|||||||
.map_err(DeviceManagerError::CreateQcowDiskSync)?,
|
.map_err(DeviceManagerError::CreateQcowDiskSync)?,
|
||||||
) as Box<dyn DiskFile>
|
) as Box<dyn DiskFile>
|
||||||
}
|
}
|
||||||
|
ImageType::Vhdx => {
|
||||||
|
info!("Using synchronous VHDX disk file");
|
||||||
|
Box::new(
|
||||||
|
VhdxDiskSync::new(file)
|
||||||
|
.map_err(DeviceManagerError::CreateFixedVhdxDiskSync)?,
|
||||||
|
) as Box<dyn DiskFile>
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let dev = Arc::new(Mutex::new(
|
let dev = Arc::new(Mutex::new(
|
||||||
|
Loading…
Reference in New Issue
Block a user