runtime-rs: Wire BlockDeviceModern into rawblock volume and container

Use BlockCfgModern for rawblock volumes when the hypervisor supports it,
passing logical and physical sector sizes from the volume metadata.

In the container manager, clear Linux.Resources fields (Pids, BlockIO,
Network) that genpolicy expects to be null, and filter VFIO character
devices from Linux.Devices to avoid policy rejection.

Update Dragonball's inner_device to handle the DeviceType::VfioModern
variant in its no-op match arm.

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
This commit is contained in:
Alex Lyn
2026-04-12 16:30:45 +02:00
committed by Fabiano Fidêncio
parent d217f2efda
commit eeaf1017cd
4 changed files with 56 additions and 6 deletions

View File

@@ -114,7 +114,7 @@ impl DragonballInner {
.context("add vhost-user-net device")?;
Ok(DeviceType::VhostUserNetwork(dev))
}
DeviceType::Vsock(_) | DeviceType::Protection(_) | DeviceType::PortDevice(_) => todo!(),
_ => Err(anyhow!("unsupported device {:?}", device)),
}
}

View File

@@ -11,7 +11,7 @@ use hypervisor::{
device_manager::{do_handle_device, get_block_device_info, DeviceManager},
DeviceConfig,
},
BlockConfig, BlockDeviceAio,
BlockConfigModern, BlockDeviceAio,
};
use kata_types::mount::DirectVolumeMountInfo;
use nix::sys::{stat, stat::SFlag};
@@ -58,7 +58,7 @@ impl RawblockVolume {
));
}
let block_config = BlockConfig {
let block_config = BlockConfigModern {
path_on_host: mount_info.device.clone(),
driver_option: blkdev_info.block_device_driver,
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
@@ -70,7 +70,7 @@ impl RawblockVolume {
};
// create and insert block device into Kata VM
let device_info = do_handle_device(d, &DeviceConfig::BlockCfg(block_config.clone()))
let device_info = do_handle_device(d, &DeviceConfig::BlockCfgModern(block_config.clone()))
.await
.context("do handle device failed.")?;

View File

@@ -86,6 +86,32 @@ pub async fn handle_block_volume(
// BlockVolume.
// safe here, device_info is correct and only unwrap it.
let mut device_id = String::new();
if let DeviceType::BlockModern(device_mod) = device_info.clone() {
let device = &device_mod.lock().await;
let blk_driver = device.config.driver_option.clone();
// blk, mmioblk
storage.driver = blk_driver.clone();
storage.source = match blk_driver.as_str() {
KATA_BLK_DEV_TYPE => {
if let Some(pci_path) = &device.config.pci_path {
pci_path.to_string()
} else {
return Err(anyhow!("block driver is blk but no pci path exists"));
}
}
KATA_SCSI_DEV_TYPE => {
if let Some(scsi_addr) = &device.config.scsi_addr {
scsi_addr.to_string()
} else {
return Err(anyhow!("block driver is scsi but no scsi address exists"));
}
}
_ => device.config.virt_path.clone(),
};
device_id = device.device_id.clone();
}
if let DeviceType::Block(device) = device_info {
let blk_driver = device.config.driver_option;
// blk, mmioblk

View File

@@ -217,11 +217,35 @@ impl Container {
if let Some(linux) = &mut spec.linux_mut() {
linux.set_resources(resources);
// In certain scenarios, particularly under CoCo/Agent Policy enforcement,
// the value of `Linux.Resources.Devices` should be empty.
// Only CPU and Memory constraints are supported in the guest.
// Clear unsupported resource fields to match the Go runtime
// and satisfy the agent policy checks.
if let Some(resource) = linux.resources_mut() {
resource.set_devices(None);
resource.set_pids(None);
resource.set_block_io(None);
resource.set_network(None);
}
// VFIO char devices are handled by the VM's device driver, not
// presented to the container directly. Remove them from the OCI
// spec to match the Go runtime (kata_agent.go:1093-1105) and
// satisfy the agent policy's allow_linux_devices check.
const VFIO_PATH: &str = "/dev/vfio/";
let filtered = linux.devices().as_ref().map(|devices| {
devices
.iter()
.filter(|d| {
!(d.typ() == oci::LinuxDeviceType::C
&& d.path().to_str().is_some_and(|p| p.starts_with(VFIO_PATH)))
})
.cloned()
.collect::<Vec<_>>()
});
linux.set_devices(match filtered {
Some(v) if v.is_empty() => None,
other => other,
});
}
let container_name = k8s::container_name(&spec);