-
Notifications
You must be signed in to change notification settings - Fork 996
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8301 from Apokleos/do-direct-volume
runtime-rs: Enhancing DirectVolMount Handling with Patching Support
- Loading branch information
Showing
10 changed files
with
407 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
src/runtime-rs/crates/resource/src/volume/direct_volume.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright (c) 2023 Ant Group | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
use std::sync::Arc; | ||
|
||
use anyhow::{anyhow, Context, Result}; | ||
use kata_types::mount::DirectVolumeMountInfo; | ||
use nix::sys::{stat, stat::SFlag}; | ||
use tokio::sync::RwLock; | ||
|
||
use hypervisor::device::device_manager::DeviceManager; | ||
|
||
use crate::volume::{ | ||
direct_volumes::{ | ||
get_direct_volume_path, rawblock_volume, spdk_volume, vfio_volume, volume_mount_info, | ||
KATA_DIRECT_VOLUME_TYPE, KATA_SPDK_VOLUME_TYPE, KATA_SPOOL_VOLUME_TYPE, | ||
KATA_VFIO_VOLUME_TYPE, | ||
}, | ||
utils::KATA_MOUNT_BIND_TYPE, | ||
Volume, | ||
}; | ||
|
||
enum DirectVolumeType { | ||
RawBlock, | ||
Spdk, | ||
Vfio, | ||
} | ||
|
||
fn to_volume_type(volume_type: &str) -> DirectVolumeType { | ||
match volume_type { | ||
KATA_SPDK_VOLUME_TYPE | KATA_SPOOL_VOLUME_TYPE => DirectVolumeType::Spdk, | ||
KATA_VFIO_VOLUME_TYPE => DirectVolumeType::Vfio, | ||
_ => DirectVolumeType::RawBlock, | ||
} | ||
} | ||
|
||
pub(crate) async fn handle_direct_volume( | ||
d: &RwLock<DeviceManager>, | ||
m: &oci::Mount, | ||
read_only: bool, | ||
sid: &str, | ||
) -> Result<Option<Arc<dyn Volume>>> { | ||
// In the direct volume scenario, we check if the source of a mount is in the | ||
// /run/kata-containers/shared/direct-volumes/SID path by iterating over all the mounts. | ||
// If the source is not in the path with error kind *NotFound*, we ignore the error | ||
// and we treat it as block volume with oci Mount.type *bind*. Just fill in the block | ||
// volume info in the DirectVolumeMountInfo | ||
let mount_info: DirectVolumeMountInfo = match volume_mount_info(&m.source) { | ||
Ok(mount_info) => mount_info, | ||
Err(e) => { | ||
// First, We need filter the non-io::ErrorKind. | ||
if !e.is::<std::io::ErrorKind>() { | ||
return Err(anyhow!(format!( | ||
"unexpected error occurs when parse mount info for {:?}, with error {:?}", | ||
&m.source, | ||
e.to_string() | ||
))); | ||
} | ||
|
||
// Second, we need filter non-NotFound error. | ||
// Safe to unwrap here, as the error is of type std::io::ErrorKind. | ||
let error_kind = e.downcast_ref::<std::io::ErrorKind>().unwrap(); | ||
if *error_kind != std::io::ErrorKind::NotFound { | ||
return Err(anyhow!(format!( | ||
"failed to parse volume mount info for {:?}, with error {:?}", | ||
&m.source, | ||
e.to_string() | ||
))); | ||
} | ||
|
||
// Third, if the case is *NotFound* , we just return Ok(None). | ||
return Ok(None); | ||
} | ||
}; | ||
|
||
let direct_volume: Arc<dyn Volume> = match to_volume_type(mount_info.volume_type.as_str()) { | ||
DirectVolumeType::RawBlock => Arc::new( | ||
rawblock_volume::RawblockVolume::new(d, m, &mount_info, read_only, sid) | ||
.await | ||
.with_context(|| format!("new sid {:?} rawblock volume {:?}", &sid, m))?, | ||
), | ||
DirectVolumeType::Spdk => Arc::new( | ||
spdk_volume::SPDKVolume::new(d, m, &mount_info, read_only, sid) | ||
.await | ||
.with_context(|| format!("create spdk volume {:?}", m))?, | ||
), | ||
DirectVolumeType::Vfio => Arc::new( | ||
vfio_volume::VfioVolume::new(d, m, &mount_info, read_only, sid) | ||
.await | ||
.with_context(|| format!("new vfio volume {:?}", m))?, | ||
), | ||
}; | ||
|
||
Ok(Some(direct_volume)) | ||
} | ||
|
||
pub(crate) fn is_direct_volume(m: &oci::Mount) -> Result<bool> { | ||
let mount_type = m.r#type.as_str(); | ||
// Filter the non-bind volume and non-direct-vol volume | ||
let vol_types = [ | ||
KATA_MOUNT_BIND_TYPE, | ||
KATA_DIRECT_VOLUME_TYPE, | ||
KATA_VFIO_VOLUME_TYPE, | ||
KATA_SPDK_VOLUME_TYPE, | ||
KATA_SPOOL_VOLUME_TYPE, | ||
]; | ||
if !vol_types.contains(&mount_type) { | ||
return Ok(false); | ||
} | ||
|
||
match get_direct_volume_path(&m.source) { | ||
Ok(directvol_path) => { | ||
let fstat = stat::stat(directvol_path.as_str()) | ||
.context(format!("stat mount source {} failed.", directvol_path))?; | ||
Ok(SFlag::from_bits_truncate(fstat.st_mode) == SFlag::S_IFDIR) | ||
} | ||
Err(_) => Ok(false), | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/runtime-rs/crates/resource/src/volume/direct_volumes/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) 2023 Ant Group | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
use anyhow::{Context, Result}; | ||
|
||
use kata_types::mount::{ | ||
get_volume_mount_info, join_path, DirectVolumeMountInfo, KATA_DIRECT_VOLUME_ROOT_PATH, | ||
}; | ||
|
||
pub mod rawblock_volume; | ||
pub mod spdk_volume; | ||
pub mod vfio_volume; | ||
|
||
pub const KATA_DIRECT_VOLUME_TYPE: &str = "directvol"; | ||
pub const KATA_VFIO_VOLUME_TYPE: &str = "vfiovol"; | ||
pub const KATA_SPDK_VOLUME_TYPE: &str = "spdkvol"; | ||
pub const KATA_SPOOL_VOLUME_TYPE: &str = "spoolvol"; | ||
|
||
// volume mount info load infomation from mountinfo.json | ||
pub fn volume_mount_info(volume_path: &str) -> Result<DirectVolumeMountInfo> { | ||
get_volume_mount_info(volume_path) | ||
} | ||
|
||
// get direct volume path whose volume_path encoded with base64 | ||
pub fn get_direct_volume_path(volume_path: &str) -> Result<String> { | ||
let volume_full_path = | ||
join_path(KATA_DIRECT_VOLUME_ROOT_PATH, volume_path).context("failed to join path.")?; | ||
|
||
Ok(volume_full_path.display().to_string()) | ||
} |
Oops, something went wrong.