diff --git a/src/libs/Cargo.lock b/src/libs/Cargo.lock index 31ea66328638..74a342ef67cf 100644 --- a/src/libs/Cargo.lock +++ b/src/libs/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.18" @@ -139,6 +141,7 @@ dependencies = [ "lazy_static", "libc", "nix", + "oci", "once_cell", "serial_test", "slog", diff --git a/src/libs/sys-util-rs/Cargo.toml b/src/libs/sys-util-rs/Cargo.toml index b4c761614ad4..2368f884a98d 100644 --- a/src/libs/sys-util-rs/Cargo.toml +++ b/src/libs/sys-util-rs/Cargo.toml @@ -22,6 +22,7 @@ slog = "2.5.2" slog-scope = "4.4.0" thiserror = "1.0.30" +oci = { path = "../../agent/oci" } kata-types = { path = "../types-rs" } [dev-dependencies] diff --git a/src/libs/sys-util-rs/src/cgroup.rs b/src/libs/sys-util-rs/src/cgroup.rs index e9aca1cbff30..62d350a5d9cf 100644 --- a/src/libs/sys-util-rs/src/cgroup.rs +++ b/src/libs/sys-util-rs/src/cgroup.rs @@ -390,7 +390,7 @@ mod tests { assert_eq!(c.subsystems().len(), 0); assert!(!c.v2()); - let c = V1Customized::new(vec![Controllers::Cpu, Controllers::Mem]); + let c = V1Customized::new(vec![Controllers::Cpu, Controllers::CpuSet]); assert_eq!(c.subsystems().len(), 2); assert!(!c.v2()); } @@ -619,7 +619,7 @@ mod tests { clean_cgroup_v1(cg_path_2); // check customized cgroup - let controllers_1 = vec![Controllers::BlkIo, Controllers::Mem]; + let controllers_1 = vec![Controllers::Cpu]; let controllers_2 = vec![Controllers::Cpu, Controllers::CpuSet, Controllers::CpuAcct]; let cg_1 = Cgroup::new(get_hierarchy(controllers_1.clone()), cg_path_1); let cg_2 = Cgroup::new(get_hierarchy(controllers_2.clone()), cg_path_2); @@ -654,7 +654,7 @@ mod tests { clean_cgroup_v1(cg_path_1); clean_cgroup_v1(cg_path_2); - let controllers = vec![Controllers::BlkIo, Controllers::Mem]; + let controllers = vec![Controllers::Cpu]; let cg_1 = Cgroup::new(get_hierarchy(controllers.clone()), cg_path_1); let cg_2 = Cgroup::new(get_hierarchy(controllers.clone()), cg_path_2); diff --git a/src/libs/sys-util-rs/src/k8s.rs b/src/libs/sys-util-rs/src/k8s.rs new file mode 100644 index 000000000000..11e44d3d3158 --- /dev/null +++ b/src/libs/sys-util-rs/src/k8s.rs @@ -0,0 +1,71 @@ +// Copyright (c) 2019-2021 Alibaba Cloud +// Copyright (c) 2019-2021 Ant Group +// +// SPDX-License-Identifier: Apache-2.0 +// + +//! Utilities to support K8S. +//! +//! This module depends on kubelet internal implementation details, a better way is needed +//! to detect K8S EmptyDir medium type from `oci::spec::Mount` objects. + +use kata_types::mount; +use oci::Spec; + +use crate::mount::get_device_path_and_fs_type; + +pub use kata_types::k8s::is_k8s_empty_dir; + +/// Check whether the given path is a kubernetes ephemeral volume. +/// +/// This method depends on a specific path used by k8s to detect if it's type of ephemeral. +/// As of now, this is a very k8s specific solution that works but in future there should be a +/// better way for this method to determine if the path is for ephemeral volume type. +pub fn is_k8s_ephemeral_volume(path: &str) -> bool { + if is_k8s_empty_dir(path) { + if let Ok((_dev_path, fs_type)) = get_device_path_and_fs_type(path) { + if fs_type == "tmpfs" { + return true; + } + } + } + + false +} + +/// Check whether the given path is a kubernetes empty-dir volume of medium "default". +/// +/// K8s `EmptyDir` volumes are directories on the host. If the fs type is tmpfs, it's a ephemeral +/// volume instead of a `EmptyDir` volume. +pub fn is_k8s_host_empty_dir(path: &str) -> bool { + if is_k8s_empty_dir(path) { + if let Ok((_dev_path, fs_type)) = get_device_path_and_fs_type(path) { + if fs_type != "tmpfs" { + return true; + } + } + } + + false +} + +// set_ephemeral_storage_type sets the mount type to 'ephemeral' +// if the mount source path is provisioned by k8s for ephemeral storage. +// For the given pod ephemeral volume is created only once +// backed by tmpfs inside the VM. For successive containers +// of the same pod the already existing volume is reused. +pub fn update_k8s_ephemeral_storage_type(oci_spec: &mut Spec) { + for m in oci_spec.mounts.iter_mut() { + if mount::is_kata_guest_mount_volume(&m.r#type) { + continue; + } + + if is_k8s_ephemeral_volume(&m.source) { + m.r#type = String::from(mount::KATA_EPHEMERAL_VOLUME_TYPE); + } + + if is_k8s_host_empty_dir(&m.source) { + m.r#type = String::from(mount::KATA_HOST_DIR_VOLUME_TYPE); + } + } +} diff --git a/src/libs/sys-util-rs/src/lib.rs b/src/libs/sys-util-rs/src/lib.rs index 3e01f166c95e..d145fa613264 100644 --- a/src/libs/sys-util-rs/src/lib.rs +++ b/src/libs/sys-util-rs/src/lib.rs @@ -10,6 +10,7 @@ pub mod cgroup; pub mod cpu; pub mod device; pub mod fs; +pub mod k8s; pub mod mount; pub mod numa; diff --git a/src/libs/sys-util-rs/src/mount.rs b/src/libs/sys-util-rs/src/mount.rs index c00ce15da810..6b43d1bc5c67 100644 --- a/src/libs/sys-util-rs/src/mount.rs +++ b/src/libs/sys-util-rs/src/mount.rs @@ -606,12 +606,13 @@ mod tests { let tmpdir = tempfile::tempdir().unwrap(); let tmpdir2 = tempfile::tempdir().unwrap(); tmpdir.path().canonicalize().unwrap(); - bind_mount(tmpdir2.path(), tmpdir.path(), true).unwrap(); - bind_remount_read_only(tmpdir.path()).unwrap(); - umount_timeout(tmpdir.path().to_str().unwrap(), 0).unwrap(); bind_remount_read_only(&PathBuf::from("")).unwrap_err(); bind_remount_read_only(&PathBuf::from("../______doesn't____exist____nnn")).unwrap_err(); + + bind_mount(tmpdir2.path(), tmpdir.path(), true).unwrap(); + bind_remount_read_only(tmpdir.path()).unwrap(); + umount_timeout(tmpdir.path().to_str().unwrap(), 0).unwrap(); } #[test] @@ -625,11 +626,12 @@ mod tests { bind_mount(Path::new(""), Path::new(""), false).unwrap_err(); bind_mount(tmpdir2.path(), Path::new(""), false).unwrap_err(); + bind_mount(Path::new("/tmp"), Path::new("/"), false).unwrap_err(); + bind_mount(tmpdir2.path(), &dst, true).unwrap(); umount_timeout(dst.to_str().unwrap(), 0).unwrap(); bind_mount(&src, &dst, false).unwrap(); umount_timeout(dst.to_str().unwrap(), 0).unwrap(); - bind_mount(Path::new("/tmp"), Path::new("/"), false).unwrap_err(); } #[test]