mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 17:35:19 +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",
|
"byteorder",
|
||||||
"epoll",
|
"epoll",
|
||||||
"event_monitor",
|
"event_monitor",
|
||||||
"io-uring",
|
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"net_gen",
|
"net_gen",
|
||||||
|
@ -66,10 +66,11 @@ test_infra = { path = "test_infra" }
|
|||||||
wait-timeout = "0.2.0"
|
wait-timeout = "0.2.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["kvm"]
|
default = ["kvm", "io_uring"]
|
||||||
dbus_api = ["zbus", "vmm/dbus_api"]
|
dbus_api = ["zbus", "vmm/dbus_api"]
|
||||||
dhat-heap = ["dhat"] # For heap profiling
|
dhat-heap = ["dhat"] # For heap profiling
|
||||||
guest_debug = ["vmm/guest_debug"]
|
guest_debug = ["vmm/guest_debug"]
|
||||||
|
io_uring = ["vmm/io_uring"]
|
||||||
kvm = ["vmm/kvm"]
|
kvm = ["vmm/kvm"]
|
||||||
mshv = ["vmm/mshv"]
|
mshv = ["vmm/mshv"]
|
||||||
tdx = ["vmm/tdx"]
|
tdx = ["vmm/tdx"]
|
||||||
|
@ -6,9 +6,10 @@ edition = "2021"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
io_uring = ["dep:io-uring"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
io-uring = "0.5.13"
|
io-uring = { version = "0.5.13", optional = true }
|
||||||
libc = "0.2.139"
|
libc = "0.2.139"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
qcow = { path = "../qcow" }
|
qcow = { path = "../qcow" }
|
||||||
|
@ -12,15 +12,22 @@
|
|||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub mod async_io;
|
pub mod async_io;
|
||||||
|
#[cfg(feature = "io_uring")]
|
||||||
|
/// Enabled with the `"io_uring"` feature
|
||||||
pub mod fixed_vhd_async;
|
pub mod fixed_vhd_async;
|
||||||
pub mod fixed_vhd_sync;
|
pub mod fixed_vhd_sync;
|
||||||
pub mod qcow_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_async;
|
||||||
pub mod raw_sync;
|
pub mod raw_sync;
|
||||||
pub mod vhd;
|
pub mod vhd;
|
||||||
pub mod vhdx_sync;
|
pub mod vhdx_sync;
|
||||||
|
|
||||||
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
use crate::async_io::{AsyncIo, AsyncIoError, AsyncIoResult};
|
||||||
|
#[cfg(feature = "io_uring")]
|
||||||
use io_uring::{opcode, IoUring, Probe};
|
use io_uring::{opcode, IoUring, Probe};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::alloc::{alloc_zeroed, dealloc, Layout};
|
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
|
/// Check if io_uring for block device can be used on the current system, as
|
||||||
/// it correctly supports the expected io_uring features.
|
/// it correctly supports the expected io_uring features.
|
||||||
pub fn block_io_uring_is_supported() -> bool {
|
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
|
#[cfg(feature = "io_uring")]
|
||||||
// that io_uring_setup() syscall is supported.
|
{
|
||||||
let io_uring = match IoUring::new(1) {
|
let error_msg = "io_uring not supported:";
|
||||||
Ok(io_uring) => io_uring,
|
|
||||||
Err(e) => {
|
// Check we can create an io_uring instance, which effectively verifies
|
||||||
info!("{} failed to create io_uring instance: {}", error_msg, e);
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let submitter = io_uring.submitter();
|
// Check IORING_OP_READV is supported
|
||||||
|
if !probe.is_supported(opcode::Readv::CODE) {
|
||||||
let mut probe = Probe::new();
|
info!("{} IORING_OP_READV operation not supported", error_msg);
|
||||||
|
|
||||||
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check IORING_OP_FSYNC is supported
|
// Check IORING_OP_WRITEV is supported
|
||||||
if !probe.is_supported(opcode::Fsync::CODE) {
|
if !probe.is_supported(opcode::Writev::CODE) {
|
||||||
info!("{} IORING_OP_FSYNC operation not supported", error_msg);
|
info!("{} IORING_OP_WRITEV operation not supported", error_msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check IORING_OP_READV is supported
|
true
|
||||||
if !probe.is_supported(opcode::Readv::CODE) {
|
|
||||||
info!("{} IORING_OP_READV 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AsyncAdaptor<F>
|
pub trait AsyncAdaptor<F>
|
||||||
|
@ -14,7 +14,6 @@ block_util = { path = "../block_util" }
|
|||||||
byteorder = "1.4.3"
|
byteorder = "1.4.3"
|
||||||
epoll = "4.3.3"
|
epoll = "4.3.3"
|
||||||
event_monitor = { path = "../event_monitor" }
|
event_monitor = { path = "../event_monitor" }
|
||||||
io-uring = "0.5.13"
|
|
||||||
libc = "0.2.139"
|
libc = "0.2.139"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
net_gen = { path = "../net_gen" }
|
net_gen = { path = "../net_gen" }
|
||||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
|||||||
default = []
|
default = []
|
||||||
dbus_api = ["blocking", "futures", "zbus"]
|
dbus_api = ["blocking", "futures", "zbus"]
|
||||||
guest_debug = ["kvm", "gdbstub", "gdbstub_arch"]
|
guest_debug = ["kvm", "gdbstub", "gdbstub_arch"]
|
||||||
|
io_uring = ["block_util/io_uring"]
|
||||||
kvm = ["hypervisor/kvm", "vfio-ioctls/kvm", "vm-device/kvm", "pci/kvm"]
|
kvm = ["hypervisor/kvm", "vfio-ioctls/kvm", "vm-device/kvm", "pci/kvm"]
|
||||||
mshv = ["hypervisor/mshv", "vfio-ioctls/mshv", "vm-device/mshv", "pci/mshv"]
|
mshv = ["hypervisor/mshv", "vfio-ioctls/mshv", "vm-device/mshv", "pci/mshv"]
|
||||||
tdx = ["arch/tdx", "hypervisor/tdx"]
|
tdx = ["arch/tdx", "hypervisor/tdx"]
|
||||||
|
@ -36,9 +36,11 @@ use arch::NumaNodes;
|
|||||||
use arch::{DeviceType, MmioDeviceInfo};
|
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_sync::FixedVhdDiskSync, qcow_sync::QcowDiskSync, raw_sync::RawFileDiskSync,
|
||||||
raw_async::RawFileDisk, raw_sync::RawFileDiskSync, vhdx_sync::VhdxDiskSync, ImageType,
|
vhdx_sync::VhdxDiskSync, ImageType,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "io_uring")]
|
||||||
|
use block_util::{fixed_vhd_async::FixedVhdDiskAsync, raw_async::RawFileDisk};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::gic;
|
use devices::gic;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -2225,12 +2227,21 @@ impl DeviceManager {
|
|||||||
ImageType::FixedVhd => {
|
ImageType::FixedVhd => {
|
||||||
// Use asynchronous backend relying on io_uring if the
|
// Use asynchronous backend relying on io_uring if the
|
||||||
// syscalls are supported.
|
// 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)");
|
info!("Using asynchronous fixed VHD disk file (io_uring)");
|
||||||
Box::new(
|
|
||||||
FixedVhdDiskAsync::new(file)
|
#[cfg(not(feature = "io_uring"))]
|
||||||
.map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?,
|
unreachable!("Checked in if statement above");
|
||||||
) as Box<dyn DiskFile>
|
#[cfg(feature = "io_uring")]
|
||||||
|
{
|
||||||
|
Box::new(
|
||||||
|
FixedVhdDiskAsync::new(file)
|
||||||
|
.map_err(DeviceManagerError::CreateFixedVhdDiskAsync)?,
|
||||||
|
) as Box<dyn DiskFile>
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
info!("Using synchronous fixed VHD disk file");
|
info!("Using synchronous fixed VHD disk file");
|
||||||
Box::new(
|
Box::new(
|
||||||
@ -2242,9 +2253,18 @@ impl DeviceManager {
|
|||||||
ImageType::Raw => {
|
ImageType::Raw => {
|
||||||
// Use asynchronous backend relying on io_uring if the
|
// Use asynchronous backend relying on io_uring if the
|
||||||
// syscalls are supported.
|
// 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)");
|
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 {
|
} else {
|
||||||
info!("Using synchronous RAW disk file");
|
info!("Using synchronous RAW disk file");
|
||||||
Box::new(RawFileDiskSync::new(file)) as Box<dyn DiskFile>
|
Box::new(RawFileDiskSync::new(file)) as Box<dyn DiskFile>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user