runtime-rs: handle sys_dir bind volume

For some cases, users will mount system directories as bind volume.
We should not bind mount these kind of directories in the host as it does
not make sense.

Fixes: #6299

Signed-off-by: Yushuo <y-shuo@linux.alibaba.com>
This commit is contained in:
Yushuo 2023-02-09 17:05:06 +08:00
parent df93439c3b
commit 07802a19dc
2 changed files with 38 additions and 0 deletions

View File

@ -20,6 +20,7 @@ use crate::share_fs::ShareFs;
use self::hugepage::{get_huge_page_limits_map, get_huge_page_option}; use self::hugepage::{get_huge_page_limits_map, get_huge_page_option};
const BIND: &str = "bind"; const BIND: &str = "bind";
#[async_trait] #[async_trait]
pub trait Volume: Send + Sync { pub trait Volume: Send + Sync {
fn get_volume_mount(&self) -> Result<Vec<oci::Mount>>; fn get_volume_mount(&self) -> Result<Vec<oci::Mount>>;

View File

@ -17,6 +17,8 @@ use super::Volume;
use crate::share_fs::{MountedInfo, ShareFs, ShareFsVolumeConfig}; use crate::share_fs::{MountedInfo, ShareFs, ShareFsVolumeConfig};
use kata_types::mount; use kata_types::mount;
const SYS_MOUNT_PREFIX: [&str; 2] = ["/proc", "/sys"];
// copy file to container's rootfs if filesystem sharing is not supported, otherwise // copy file to container's rootfs if filesystem sharing is not supported, otherwise
// bind mount it in the shared directory. // bind mount it in the shared directory.
// Ignore /dev, directories and all other device files. We handle // Ignore /dev, directories and all other device files. We handle
@ -229,6 +231,7 @@ impl Volume for ShareFsVolume {
pub(crate) fn is_share_fs_volume(m: &oci::Mount) -> bool { pub(crate) fn is_share_fs_volume(m: &oci::Mount) -> bool {
(m.r#type == "bind" || m.r#type == mount::KATA_EPHEMERAL_VOLUME_TYPE) (m.r#type == "bind" || m.r#type == mount::KATA_EPHEMERAL_VOLUME_TYPE)
&& !is_host_device(&m.destination) && !is_host_device(&m.destination)
&& !is_system_mount(&m.source)
} }
fn is_host_device(dest: &str) -> bool { fn is_host_device(dest: &str) -> bool {
@ -252,6 +255,20 @@ fn is_host_device(dest: &str) -> bool {
false false
} }
// Skip mounting certain system paths("/sys/*", "/proc/*")
// from source on the host side into the container as it does not
// make sense to do so.
// Agent will support this kind of bind mount.
fn is_system_mount(src: &str) -> bool {
for p in SYS_MOUNT_PREFIX {
let sub_dir_p = format!("{}/", p);
if src == p || src.contains(sub_dir_p.as_str()) {
return true;
}
}
false
}
// Note, don't generate random name, attaching rafs depends on the predictable name. // Note, don't generate random name, attaching rafs depends on the predictable name.
pub fn generate_mount_path(id: &str, file_name: &str) -> String { pub fn generate_mount_path(id: &str, file_name: &str) -> String {
let mut nid = String::from(id); let mut nid = String::from(id);
@ -265,3 +282,23 @@ pub fn generate_mount_path(id: &str, file_name: &str) -> String {
format!("{}-{}-{}", nid, uid, file_name) format!("{}-{}-{}", nid, uid, file_name)
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_is_system_mount() {
let sys_dir = "/sys";
let proc_dir = "/proc";
let sys_sub_dir = "/sys/fs/cgroup";
let proc_sub_dir = "/proc/cgroups";
let not_sys_dir = "/root";
assert!(is_system_mount(sys_dir));
assert!(is_system_mount(proc_dir));
assert!(is_system_mount(sys_sub_dir));
assert!(is_system_mount(proc_sub_dir));
assert!(!is_system_mount(not_sys_dir));
}
}