mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-21 20:15:21 +00:00
build: Allow disabling io_uring
This gives users the chance to reduce the number of dependencies included, which is generally good practice and also reduces code size. Furthermore, `io_uring` specifically is a strong contender for something one may wish to disable due to the syscall API's many security issues[1] [1]: https://security.googleblog.com/2023/06/learnings-from-kctf-vrps-42-linux.html Signed-off-by: Manish Goregaokar <manishsmail@gmail.com>
This commit is contained in:
parent
d2e42a0ed4
commit
6fdba7ca11
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2151,7 +2151,6 @@ dependencies = [
|
||||
"byteorder",
|
||||
"epoll",
|
||||
"event_monitor",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"log",
|
||||
"net_gen",
|
||||
|
@ -66,10 +66,11 @@ test_infra = { path = "test_infra" }
|
||||
wait-timeout = "0.2.0"
|
||||
|
||||
[features]
|
||||
default = ["kvm"]
|
||||
default = ["kvm", "io_uring"]
|
||||
dbus_api = ["zbus", "vmm/dbus_api"]
|
||||
dhat-heap = ["dhat"] # For heap profiling
|
||||
guest_debug = ["vmm/guest_debug"]
|
||||
io_uring = ["vmm/io_uring"]
|
||||
kvm = ["vmm/kvm"]
|
||||
mshv = ["vmm/mshv"]
|
||||
tdx = ["vmm/tdx"]
|
||||
|
@ -6,9 +6,10 @@ edition = "2021"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
io_uring = ["dep:io-uring"]
|
||||
|
||||
[dependencies]
|
||||
io-uring = "0.5.13"
|
||||
io-uring = { version = "0.5.13", optional = true }
|
||||
libc = "0.2.139"
|
||||
log = "0.4.17"
|
||||
qcow = { path = "../qcow" }
|
||||
|
@ -12,15 +12,22 @@
|
||||
extern crate log;
|
||||
|
||||
pub mod async_io;
|
||||
#[cfg(feature = "io_uring")]
|
||||
/// Enabled with the `"io_uring"` feature
|
||||
pub mod fixed_vhd_async;
|
||||
pub mod fixed_vhd_sync;
|
||||
pub mod qcow_sync;
|
||||
#[cfg(feature = "io_uring")]
|
||||
/// Async primitives based on `io-uring`
|
||||
///
|
||||
/// Enabled with the `"io_uring"` feature
|
||||
pub mod raw_async;
|
||||
pub mod raw_sync;
|
||||
pub mod vhd;
|
||||
pub mod vhdx_sync;
|
||||
|
||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
||||
#[cfg(feature = "io_uring")]
|
||||
use io_uring::{opcode, IoUring, Probe};
|
||||
use smallvec::SmallVec;
|
||||
use std::alloc::{alloc_zeroed, dealloc, Layout};
|
||||
@ -543,50 +550,59 @@ unsafe impl ByteValued for VirtioBlockGeometry {}
|
||||
/// Check if io_uring for block device can be used on the current system, as
|
||||
/// it correctly supports the expected io_uring features.
|
||||
pub fn block_io_uring_is_supported() -> bool {
|
||||
let error_msg = "io_uring not supported:";
|
||||
#[cfg(not(feature = "io_uring"))]
|
||||
{
|
||||
info!("io_uring is disabled by crate features");
|
||||
false
|
||||
}
|
||||
|
||||
// Check we can create an io_uring instance, which effectively verifies
|
||||
// that io_uring_setup() syscall is supported.
|
||||
let io_uring = match IoUring::new(1) {
|
||||
Ok(io_uring) => io_uring,
|
||||
Err(e) => {
|
||||
info!("{} failed to create io_uring instance: {}", error_msg, e);
|
||||
#[cfg(feature = "io_uring")]
|
||||
{
|
||||
let error_msg = "io_uring not supported:";
|
||||
|
||||
// Check we can create an io_uring instance, which effectively verifies
|
||||
// that io_uring_setup() syscall is supported.
|
||||
let io_uring = match IoUring::new(1) {
|
||||
Ok(io_uring) => io_uring,
|
||||
Err(e) => {
|
||||
info!("{} failed to create io_uring instance: {}", error_msg, e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let submitter = io_uring.submitter();
|
||||
|
||||
let mut probe = Probe::new();
|
||||
|
||||
// Check we can register a probe to validate supported operations.
|
||||
match submitter.register_probe(&mut probe) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
info!("{} failed to register a probe: {}", error_msg, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check IORING_OP_FSYNC is supported
|
||||
if !probe.is_supported(opcode::Fsync::CODE) {
|
||||
info!("{} IORING_OP_FSYNC operation not supported", error_msg);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let submitter = io_uring.submitter();
|
||||
|
||||
let mut probe = Probe::new();
|
||||
|
||||
// Check we can register a probe to validate supported operations.
|
||||
match submitter.register_probe(&mut probe) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
info!("{} failed to register a probe: {}", error_msg, e);
|
||||
// Check IORING_OP_READV is supported
|
||||
if !probe.is_supported(opcode::Readv::CODE) {
|
||||
info!("{} IORING_OP_READV operation not supported", error_msg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check IORING_OP_FSYNC is supported
|
||||
if !probe.is_supported(opcode::Fsync::CODE) {
|
||||
info!("{} IORING_OP_FSYNC operation not supported", error_msg);
|
||||
return false;
|
||||
}
|
||||
// Check IORING_OP_WRITEV is supported
|
||||
if !probe.is_supported(opcode::Writev::CODE) {
|
||||
info!("{} IORING_OP_WRITEV operation not supported", error_msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check IORING_OP_READV is supported
|
||||
if !probe.is_supported(opcode::Readv::CODE) {
|
||||
info!("{} IORING_OP_READV operation not supported", error_msg);
|
||||
return false;
|
||||
true
|
||||
}
|
||||
|
||||
// Check IORING_OP_WRITEV is supported
|
||||
if !probe.is_supported(opcode::Writev::CODE) {
|
||||
info!("{} IORING_OP_WRITEV operation not supported", error_msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub trait AsyncAdaptor<F>
|
||||
|
@ -14,7 +14,6 @@ block_util = { path = "../block_util" }
|
||||
byteorder = "1.4.3"
|
||||
epoll = "4.3.3"
|
||||
event_monitor = { path = "../event_monitor" }
|
||||
io-uring = "0.5.13"
|
||||
libc = "0.2.139"
|
||||
log = "0.4.17"
|
||||
net_gen = { path = "../net_gen" }
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
default = []
|
||||
dbus_api = ["blocking", "futures", "zbus"]
|
||||
guest_debug = ["kvm", "gdbstub", "gdbstub_arch"]
|
||||
io_uring = ["block_util/io_uring"]
|
||||
kvm = ["hypervisor/kvm", "vfio-ioctls/kvm", "vm-device/kvm", "pci/kvm"]
|
||||
mshv = ["hypervisor/mshv", "vfio-ioctls/mshv", "vm-device/mshv", "pci/mshv"]
|
||||
tdx = ["arch/tdx", "hypervisor/tdx"]
|
||||
|
@ -36,9 +36,11 @@ use arch::NumaNodes;
|
||||
use arch::{DeviceType, MmioDeviceInfo};
|
||||
use block_util::{
|
||||
async_io::DiskFile, block_io_uring_is_supported, detect_image_type,
|
||||
fixed_vhd_async::FixedVhdDiskAsync, fixed_vhd_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync,
|
||||
raw_async::RawFileDisk, raw_sync::RawFileDiskSync, vhdx_sync::VhdxDiskSync, ImageType,
|
||||
fixed_vhd_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync, raw_sync::RawFileDiskSync,
|
||||
vhdx_sync::VhdxDiskSync, ImageType,
|
||||
};
|
||||
#[cfg(feature = "io_uring")]
|
||||
use block_util::{fixed_vhd_async::FixedVhdDiskAsync, raw_async::RawFileDisk};
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use devices::gic;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -2225,12 +2227,21 @@ impl DeviceManager {
|
||||
ImageType::FixedVhd => {
|
||||
// Use asynchronous backend relying on io_uring if the
|
||||
// syscalls are supported.
|
||||
if !disk_cfg.disable_io_uring && self.io_uring_is_supported() {
|
||||
if cfg!(feature = "io_uring")
|
||||
&& !disk_cfg.disable_io_uring
|
||||
&& self.io_uring_is_supported()
|
||||
{
|
||||
info!("Using asynchronous fixed VHD disk file (io_uring)");
|
||||
Box::new(
|
||||
FixedVhdDiskAsync::new(file)
|
||||
.map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?,
|
||||
) as Box<dyn DiskFile>
|
||||
|
||||
#[cfg(not(feature = "io_uring"))]
|
||||
unreachable!("Checked in if statement above");
|
||||
#[cfg(feature = "io_uring")]
|
||||
{
|
||||
Box::new(
|
||||
FixedVhdDiskAsync::new(file)
|
||||
.map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?,
|
||||
) as Box<dyn DiskFile>
|
||||
}
|
||||
} else {
|
||||
info!("Using synchronous fixed VHD disk file");
|
||||
Box::new(
|
||||
@ -2242,9 +2253,18 @@ impl DeviceManager {
|
||||
ImageType::Raw => {
|
||||
// Use asynchronous backend relying on io_uring if the
|
||||
// syscalls are supported.
|
||||
if !disk_cfg.disable_io_uring && self.io_uring_is_supported() {
|
||||
if cfg!(feature = "io_uring")
|
||||
&& !disk_cfg.disable_io_uring
|
||||
&& self.io_uring_is_supported()
|
||||
{
|
||||
info!("Using asynchronous RAW disk file (io_uring)");
|
||||
Box::new(RawFileDisk::new(file)) as Box<dyn DiskFile>
|
||||
|
||||
#[cfg(not(feature = "io_uring"))]
|
||||
unreachable!("Checked in if statement above");
|
||||
#[cfg(feature = "io_uring")]
|
||||
{
|
||||
Box::new(RawFileDisk::new(file)) as Box<dyn DiskFile>
|
||||
}
|
||||
} else {
|
||||
info!("Using synchronous RAW disk file");
|
||||
Box::new(RawFileDiskSync::new(file)) as Box<dyn DiskFile>
|
||||
|
Loading…
x
Reference in New Issue
Block a user