runtime-rs: Use bind mounts for direct volume targets

Treat SPDK and VFIO direct volumes as a two-step mount. The agent
storage entry mounts the device inside the guest with block storage
options, while the OCI mount bind-mounts that guest path into the
container.

Filter bind flags from storage options, preserve direct-volume
mountInfo options when present, and add ro when the volume is
read-only.

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
Alex Lyn
2026-07-03 16:19:00 +08:00
committed by Fabiano Fidêncio
parent 22f2d57e4f
commit 37739bcc69
2 changed files with 43 additions and 17 deletions

View File

@@ -23,7 +23,10 @@ use tokio::sync::RwLock;
use crate::volume::{
direct_volumes::{KATA_SPDK_VOLUME_TYPE, KATA_SPOOL_VOLUME_TYPE},
utils::{generate_shared_path, DEFAULT_VOLUME_FS_TYPE},
utils::{
build_bind_mount_options, filter_block_storage_options, generate_shared_path,
KATA_MOUNT_BIND_TYPE, DEFAULT_VOLUME_FS_TYPE,
},
Volume,
};
@@ -100,13 +103,21 @@ impl SPDKVolume {
.await
.context("do handle device failed.")?;
// storage
let mut storage = agent::Storage {
options: if read_only {
vec!["ro".to_string()]
let oci_opts = get_mount_options(m.options());
let mut storage_options: Vec<String> = filter_block_storage_options(
if !mount_info.options.is_empty() {
&mount_info.options
} else {
Vec::new()
&oci_opts
},
);
if read_only && !storage_options.iter().any(|o| o == "ro") {
storage_options.push("ro".to_string());
}
let mut storage = agent::Storage {
options: storage_options,
..Default::default()
};
@@ -139,9 +150,12 @@ impl SPDKVolume {
storage.fs_group = None;
let mut oci_mount = oci::Mount::default();
oci_mount.set_destination(m.destination().clone());
oci_mount.set_typ(Some(storage.fs_type.clone()));
oci_mount.set_typ(Some(KATA_MOUNT_BIND_TYPE.to_string()));
oci_mount.set_source(Some(PathBuf::from(&guest_path)));
oci_mount.set_options(m.options().clone());
oci_mount.set_options(Some(build_bind_mount_options(
&mount_info.options,
m.options(),
)));
Ok(Self {
storage: Some(storage),

View File

@@ -15,13 +15,16 @@ use hypervisor::{
},
get_vfio_device, VfioConfig,
};
use kata_sys_util::mount::get_mount_type;
use kata_sys_util::mount::{get_mount_options, get_mount_type};
use kata_types::mount::DirectVolumeMountInfo;
use oci_spec::runtime as oci;
use tokio::sync::RwLock;
use crate::volume::{
utils::{generate_shared_path, DEFAULT_VOLUME_FS_TYPE},
utils::{
build_bind_mount_options, filter_block_storage_options, generate_shared_path,
KATA_MOUNT_BIND_TYPE, DEFAULT_VOLUME_FS_TYPE,
},
Volume,
};
@@ -55,11 +58,17 @@ impl VfioVolume {
.await
.context("do handle device failed.")?;
let storage_options = if read_only {
vec!["ro".to_string()]
} else {
Vec::new()
};
let oci_opts = get_mount_options(m.options());
let mut storage_options: Vec<String> = filter_block_storage_options(
if !mount_info.options.is_empty() {
&mount_info.options
} else {
&oci_opts
},
);
if read_only && !storage_options.iter().any(|o| o == "ro") {
storage_options.push("ro".to_string());
}
let mut storage = agent::Storage {
options: storage_options,
@@ -88,9 +97,12 @@ impl VfioVolume {
let mut oci_mount = oci::Mount::default();
oci_mount.set_destination(m.destination().clone());
oci_mount.set_typ(Some(mount_info.fs_type.clone()));
oci_mount.set_typ(Some(KATA_MOUNT_BIND_TYPE.to_string()));
oci_mount.set_source(Some(PathBuf::from(&guest_path)));
oci_mount.set_options(m.options().clone());
oci_mount.set_options(Some(build_bind_mount_options(
&mount_info.options,
m.options(),
)));
Ok(Self {
storage: Some(storage),