mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-12 15:02:36 +00:00
runtime-rs: Add BlockDeviceModern driver
Add a modern block device driver using the Arc<Mutex> pattern for interior mutability, matching the VfioDeviceModern approach. The driver implements the Device trait with attach/detach/hotplug lifecycle management, and supports BlockConfigModern with logical and physical sector size fields. Add the DeviceType::BlockModern enum variant so the driver compiles. The device_manager and hypervisor cold-plug wiring follow in subsequent commits. Signed-off-by: Alex Lyn <alex.lyn@antgroup.com> Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
This commit is contained in:
committed by
Fabiano Fidêncio
parent
443dd81f92
commit
4b6d62ca51
@@ -255,7 +255,8 @@ impl DeviceManager {
|
||||
| DeviceType::Vsock(_)
|
||||
| DeviceType::Protection(_)
|
||||
| DeviceType::PortDevice(_)
|
||||
| DeviceType::VfioModern(_) => {
|
||||
| DeviceType::VfioModern(_)
|
||||
| DeviceType::BlockModern(_) => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ mod vhost_user;
|
||||
pub mod vhost_user_blk;
|
||||
mod vhost_user_net;
|
||||
mod virtio_blk;
|
||||
pub mod virtio_blk_modern;
|
||||
mod virtio_fs;
|
||||
mod virtio_net;
|
||||
mod virtio_vsock;
|
||||
@@ -30,6 +31,7 @@ pub use virtio_blk::{
|
||||
KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE, KATA_SCSI_DEV_TYPE, VIRTIO_BLOCK_CCW,
|
||||
VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
|
||||
};
|
||||
pub use virtio_blk_modern::{BlockConfigModern, BlockDeviceModern, BlockDeviceModernHandle};
|
||||
pub use virtio_fs::{
|
||||
ShareFsConfig, ShareFsDevice, ShareFsMountConfig, ShareFsMountOperation, ShareFsMountType,
|
||||
};
|
||||
|
||||
@@ -156,7 +156,6 @@ impl Device for BlockDevice {
|
||||
|
||||
match h.add_device(DeviceType::Block(self.clone())).await {
|
||||
Ok(dev) => {
|
||||
// Update device info with the one received from device attach
|
||||
if let DeviceType::Block(blk) = dev {
|
||||
self.config = blk.config;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
// Copyright (c) 2022-2023 Alibaba Cloud
|
||||
// Copyright (c) 2022-2023 Ant Group
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::device::pci_path::PciPath;
|
||||
use crate::device::topology::PCIeTopology;
|
||||
use crate::device::util::do_decrease_count;
|
||||
use crate::device::util::do_increase_count;
|
||||
use crate::device::Device;
|
||||
use crate::device::DeviceType;
|
||||
use crate::Hypervisor as hypervisor;
|
||||
use anyhow::{Context, Result};
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub enum BlockDeviceAio {
|
||||
// IoUring is the Linux io_uring I/O implementation.
|
||||
#[default]
|
||||
IoUring,
|
||||
|
||||
// Native is the native Linux AIO implementation.
|
||||
Native,
|
||||
|
||||
// Threads is the pthread asynchronous I/O implementation.
|
||||
Threads,
|
||||
}
|
||||
|
||||
impl BlockDeviceAio {
|
||||
pub fn new(aio: &str) -> Self {
|
||||
match aio {
|
||||
"native" => BlockDeviceAio::Native,
|
||||
"threads" => BlockDeviceAio::Threads,
|
||||
_ => BlockDeviceAio::IoUring,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BlockDeviceAio {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let to_string = match *self {
|
||||
BlockDeviceAio::Native => "native".to_string(),
|
||||
BlockDeviceAio::Threads => "threads".to_string(),
|
||||
_ => "iouring".to_string(),
|
||||
};
|
||||
write!(f, "{to_string}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct BlockConfigModern {
|
||||
/// Path of the drive.
|
||||
pub path_on_host: String,
|
||||
|
||||
/// If set to true, the drive is opened in read-only mode. Otherwise, the
|
||||
/// drive is opened as read-write.
|
||||
pub is_readonly: bool,
|
||||
|
||||
/// Don't close `path_on_host` file when dropping the device.
|
||||
pub no_drop: bool,
|
||||
|
||||
/// Specifies cache-related options for block devices.
|
||||
/// Denotes whether use of O_DIRECT (bypass the host page cache) is enabled.
|
||||
/// If not set, use configurarion block_device_cache_direct.
|
||||
pub is_direct: Option<bool>,
|
||||
|
||||
/// device index
|
||||
pub index: u64,
|
||||
|
||||
/// blkdev_aio defines the type of asynchronous I/O the block device should use.
|
||||
pub blkdev_aio: BlockDeviceAio,
|
||||
|
||||
/// driver type for block device
|
||||
pub driver_option: String,
|
||||
|
||||
/// device path in guest
|
||||
pub virt_path: String,
|
||||
|
||||
/// pci path is the slot at which the drive is attached
|
||||
pub pci_path: Option<PciPath>,
|
||||
|
||||
/// scsi_addr of the block device, in case the device is attached using SCSI driver
|
||||
/// scsi_addr is of the format SCSI-Id:LUN
|
||||
pub scsi_addr: Option<String>,
|
||||
|
||||
/// device attach count
|
||||
pub attach_count: u64,
|
||||
|
||||
/// device major number
|
||||
pub major: i64,
|
||||
|
||||
/// device minor number
|
||||
pub minor: i64,
|
||||
|
||||
/// virtio queue size. size: byte
|
||||
pub queue_size: u32,
|
||||
|
||||
/// block device multi-queue
|
||||
pub num_queues: usize,
|
||||
|
||||
/// Logical sector size in bytes reported to the guest. 0 means use hypervisor default.
|
||||
pub logical_sector_size: u32,
|
||||
|
||||
/// Physical sector size in bytes reported to the guest. 0 means use hypervisor default.
|
||||
pub physical_sector_size: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct BlockDeviceModern {
|
||||
pub device_id: String,
|
||||
pub attach_count: u64,
|
||||
pub config: BlockConfigModern,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BlockDeviceModernHandle {
|
||||
inner: Arc<Mutex<BlockDeviceModern>>,
|
||||
}
|
||||
|
||||
impl BlockDeviceModernHandle {
|
||||
pub fn new(device_id: String, config: BlockConfigModern) -> Self {
|
||||
Self {
|
||||
inner: Arc::new(Mutex::new(BlockDeviceModern {
|
||||
device_id,
|
||||
attach_count: 0,
|
||||
config,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arc(&self) -> Arc<Mutex<BlockDeviceModern>> {
|
||||
self.inner.clone()
|
||||
}
|
||||
|
||||
pub async fn snapshot_config(&self) -> BlockConfigModern {
|
||||
self.inner.lock().await.config.clone()
|
||||
}
|
||||
|
||||
pub async fn device_id(&self) -> String {
|
||||
self.inner.lock().await.device_id.clone()
|
||||
}
|
||||
|
||||
pub async fn attach_count(&self) -> u64 {
|
||||
self.inner.lock().await.attach_count
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Device for BlockDeviceModernHandle {
|
||||
async fn attach(
|
||||
&mut self,
|
||||
_pcie_topo: &mut Option<&mut PCIeTopology>,
|
||||
h: &dyn hypervisor,
|
||||
) -> Result<()> {
|
||||
// increase attach count, skip attach the device if the device is already attached
|
||||
if self
|
||||
.increase_attach_count()
|
||||
.await
|
||||
.context("failed to increase attach count")?
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Err(e) = h.add_device(DeviceType::BlockModern(self.arc())).await {
|
||||
error!(sl!(), "failed to attach vfio device: {:?}", e);
|
||||
self.decrease_attach_count().await?;
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn detach(
|
||||
&mut self,
|
||||
_pcie_topo: &mut Option<&mut PCIeTopology>,
|
||||
h: &dyn hypervisor,
|
||||
) -> Result<Option<u64>> {
|
||||
// get the count of device detached, skip detach once it reaches the 0
|
||||
if self
|
||||
.decrease_attach_count()
|
||||
.await
|
||||
.context("failed to decrease attach count")?
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
if let Err(e) = h.remove_device(DeviceType::BlockModern(self.arc())).await {
|
||||
self.increase_attach_count().await?;
|
||||
return Err(e);
|
||||
}
|
||||
Ok(Some(self.snapshot_config().await.index))
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for virtio-blk
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::BlockModern(self.inner.clone())
|
||||
}
|
||||
|
||||
async fn increase_attach_count(&mut self) -> Result<bool> {
|
||||
let mut guard = self.inner.lock().await;
|
||||
do_increase_count(&mut guard.attach_count)
|
||||
}
|
||||
|
||||
async fn decrease_attach_count(&mut self) -> Result<bool> {
|
||||
let mut guard = self.inner.lock().await;
|
||||
do_decrease_count(&mut guard.attach_count)
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use tokio::sync::Mutex;
|
||||
|
||||
use crate::device::driver::vhost_user_blk::VhostUserBlkDevice;
|
||||
use crate::device::driver::vfio_device::VfioDeviceModern;
|
||||
use crate::device::driver::virtio_blk_modern::BlockDeviceModern;
|
||||
use crate::{
|
||||
BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor,
|
||||
NetworkConfig, NetworkDevice, PCIePortDevice, PortDeviceConfig, ProtectionDevice,
|
||||
@@ -57,6 +58,7 @@ pub enum DeviceType {
|
||||
Protection(ProtectionDevice),
|
||||
PortDevice(PCIePortDevice),
|
||||
VfioModern(Arc<Mutex<VfioDeviceModern>>),
|
||||
BlockModern(Arc<Mutex<BlockDeviceModern>>),
|
||||
}
|
||||
|
||||
impl fmt::Display for DeviceType {
|
||||
|
||||
Reference in New Issue
Block a user