diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index a6a464c9ae..f09ae2ca44 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -101,6 +101,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitmask-enum" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9e32d7420c85055e8107e5b2463c4eeefeaac18b52359fe9f9c08a18f342b2" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "bumpalo" version = "3.10.0" @@ -715,6 +725,7 @@ dependencies = [ name = "kata-types" version = "0.1.0" dependencies = [ + "bitmask-enum", "byte-unit", "glob", "lazy_static", diff --git a/src/libs/Cargo.lock b/src/libs/Cargo.lock index 655c116782..66090c19c5 100644 --- a/src/libs/Cargo.lock +++ b/src/libs/Cargo.lock @@ -46,6 +46,16 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitmask-enum" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9e32d7420c85055e8107e5b2463c4eeefeaac18b52359fe9f9c08a18f342b2" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "bumpalo" version = "3.11.0" @@ -410,6 +420,7 @@ dependencies = [ name = "kata-types" version = "0.1.0" dependencies = [ + "bitmask-enum", "byte-unit", "glob", "lazy_static", diff --git a/src/libs/kata-types/Cargo.toml b/src/libs/kata-types/Cargo.toml index 5a2560457a..01456b4f6f 100644 --- a/src/libs/kata-types/Cargo.toml +++ b/src/libs/kata-types/Cargo.toml @@ -11,6 +11,7 @@ license = "Apache-2.0" edition = "2018" [dependencies] +bitmask-enum = "2.1.0" byte-unit = "3.1.4" glob = "0.3.0" lazy_static = "1.4.0" diff --git a/src/libs/kata-types/src/capabilities.rs b/src/libs/kata-types/src/capabilities.rs new file mode 100644 index 0000000000..15207e6136 --- /dev/null +++ b/src/libs/kata-types/src/capabilities.rs @@ -0,0 +1,107 @@ +// Copyright (c) 2019-2022 Alibaba Cloud +// Copyright (c) 2019-2022 Ant Group +// +// SPDX-License-Identifier: Apache-2.0 +// + +use bitmask_enum::bitmask; + +/// CapabilityBits +#[bitmask(u8)] +pub enum CapabilityBits { + /// hypervisor supports use block device + BlockDeviceSupport, + /// hypervisor supports block device hotplug + BlockDeviceHotplugSupport, + /// hypervisor supports multi queue + MultiQueueSupport, + /// hypervisor supports filesystem share + FsSharingSupport, +} + +/// Capabilities describe a virtcontainers hypervisor capabilities through a bit mask. +#[derive(Debug, Clone)] +pub struct Capabilities { + /// Capability flags + flags: CapabilityBits, +} + +impl Default for Capabilities { + fn default() -> Self { + Self::new() + } +} + +impl Capabilities { + /// new Capabilities struct + pub fn new() -> Self { + Capabilities { + flags: CapabilityBits { bits: 0 }, + } + } + + /// set CapabilityBits + pub fn set(&mut self, flags: CapabilityBits) { + self.flags = flags; + } + + /// is_block_device_supported tells if an hypervisor supports block devices. + pub fn is_block_device_supported(&self) -> bool { + self.flags.and(CapabilityBits::BlockDeviceSupport) != 0 + } + + /// is_block_device_hotplug_supported tells if an hypervisor supports block devices. + pub fn is_block_device_hotplug_supported(&self) -> bool { + self.flags.and(CapabilityBits::BlockDeviceHotplugSupport) != 0 + } + + /// is_multi_queue_supported tells if an hypervisor supports device multi queue support. + pub fn is_multi_queue_supported(&self) -> bool { + self.flags.and(CapabilityBits::MultiQueueSupport) != 0 + } + + /// is_fs_sharing_supported tells if an hypervisor supports host filesystem sharing. + pub fn is_fs_sharing_supported(&self) -> bool { + self.flags.and(CapabilityBits::FsSharingSupport) != 0 + } +} + +#[cfg(test)] +mod tests { + use crate::capabilities::CapabilityBits; + + use super::Capabilities; + + #[test] + fn test_set_hypervisor_capabilities() { + let mut cap = Capabilities::new(); + assert!(!cap.is_block_device_supported()); + + // test set block device support + cap.set(CapabilityBits::BlockDeviceSupport); + assert!(cap.is_block_device_supported()); + assert!(!cap.is_block_device_hotplug_supported()); + + // test set block device hotplug support + cap.set(CapabilityBits::BlockDeviceSupport | CapabilityBits::BlockDeviceHotplugSupport); + assert!(cap.is_block_device_hotplug_supported()); + assert!(!cap.is_multi_queue_supported()); + + // test set multi queue support + cap.set( + CapabilityBits::BlockDeviceSupport + | CapabilityBits::BlockDeviceHotplugSupport + | CapabilityBits::MultiQueueSupport, + ); + assert!(cap.is_multi_queue_supported()); + + // test set host filesystem sharing support + cap.set( + CapabilityBits::BlockDeviceSupport + | CapabilityBits::BlockDeviceHotplugSupport + | CapabilityBits::MultiQueueSupport + | CapabilityBits::FsSharingSupport, + ); + assert!(cap.is_fs_sharing_supported()) + } +} diff --git a/src/libs/kata-types/src/lib.rs b/src/libs/kata-types/src/lib.rs index ce43d29607..5eb407561c 100644 --- a/src/libs/kata-types/src/lib.rs +++ b/src/libs/kata-types/src/lib.rs @@ -31,6 +31,9 @@ pub mod mount; pub(crate) mod utils; +/// hypervisor capabilities +pub mod capabilities; + /// Common error codes. #[derive(thiserror::Error, Debug)] pub enum Error { diff --git a/src/runtime-rs/Cargo.lock b/src/runtime-rs/Cargo.lock index 6327884ddc..d0fed4efc5 100644 --- a/src/runtime-rs/Cargo.lock +++ b/src/runtime-rs/Cargo.lock @@ -254,6 +254,16 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitmask-enum" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9e32d7420c85055e8107e5b2463c4eeefeaac18b52359fe9f9c08a18f342b2" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "blake3" version = "1.3.1" @@ -1373,6 +1383,7 @@ dependencies = [ name = "kata-types" version = "0.1.0" dependencies = [ + "bitmask-enum", "byte-unit", "glob", "lazy_static", diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs index 851f2b66ae..7db3f3278c 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs @@ -16,7 +16,10 @@ use dragonball::{ vm::VmConfigInfo, }; use kata_sys_util::mount; -use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; +use kata_types::{ + capabilities::{Capabilities, CapabilityBits}, + config::hypervisor::Hypervisor as HypervisorConfig, +}; use persist::{sandbox_persist::Persist, KATA_PATH}; use std::{collections::HashSet, fs::create_dir_all, path::PathBuf}; @@ -58,10 +61,19 @@ pub struct DragonballInner { /// cached block device pub(crate) cached_block_devices: HashSet, + + /// dragonball capabilities + pub(crate) capabilities: Capabilities, } impl DragonballInner { pub fn new() -> DragonballInner { + let mut capabilities = Capabilities::new(); + capabilities.set( + CapabilityBits::BlockDeviceSupport + | CapabilityBits::BlockDeviceHotplugSupport + | CapabilityBits::FsSharingSupport, + ); DragonballInner { id: "".to_string(), vm_path: "".to_string(), @@ -74,6 +86,7 @@ impl DragonballInner { vmm_instance: VmmInstance::new(""), run_dir: "".to_string(), cached_block_devices: Default::default(), + capabilities, } } @@ -351,6 +364,7 @@ impl Persist for DragonballInner { run_dir: hypervisor_state.run_dir, pending_devices: vec![], cached_block_devices: hypervisor_state.cached_block_devices, + capabilities: Capabilities::new(), }) } } diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/inner_hypervisor.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/inner_hypervisor.rs index 3b5bd02af0..8a26f84651 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/inner_hypervisor.rs @@ -9,7 +9,8 @@ use std::{ iter::FromIterator, }; -use anyhow::{Context, Result}; +use anyhow::{Context, Ok, Result}; +use kata_types::capabilities::Capabilities; use super::inner::DragonballInner; use crate::{utils, VcpuThreadIds, VmmState}; @@ -133,4 +134,8 @@ impl DragonballInner { pub(crate) async fn get_jailer_root(&self) -> Result { Ok(self.jailer_root.clone()) } + + pub(crate) async fn capabilities(&self) -> Result { + Ok(self.capabilities.clone()) + } } diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs index aaadd068a2..37ffd69b97 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use anyhow::{Context, Result}; use async_trait::async_trait; +use kata_types::capabilities::Capabilities; use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; use tokio::sync::RwLock; @@ -131,6 +132,11 @@ impl Hypervisor for Dragonball { async fn save_state(&self) -> Result { self.save().await } + + async fn capabilities(&self) -> Result { + let inner = self.inner.read().await; + inner.capabilities().await + } } #[async_trait] diff --git a/src/runtime-rs/crates/hypervisor/src/lib.rs b/src/runtime-rs/crates/hypervisor/src/lib.rs index b9296d81ef..6b499d0bac 100644 --- a/src/runtime-rs/crates/hypervisor/src/lib.rs +++ b/src/runtime-rs/crates/hypervisor/src/lib.rs @@ -21,8 +21,8 @@ use std::collections::HashMap; use anyhow::Result; use async_trait::async_trait; use hypervisor_persist::HypervisorState; +use kata_types::capabilities::Capabilities; use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; - // Config which driver to use as vm root dev const VM_ROOTFS_DRIVER_BLK: &str = "virtio-blk"; const VM_ROOTFS_DRIVER_PMEM: &str = "virtio-pmem"; @@ -65,4 +65,5 @@ pub trait Hypervisor: Send + Sync { async fn check(&self) -> Result<()>; async fn get_jailer_root(&self) -> Result; async fn save_state(&self) -> Result; + async fn capabilities(&self) -> Result; } diff --git a/src/runtime-rs/crates/resource/src/manager_inner.rs b/src/runtime-rs/crates/resource/src/manager_inner.rs index dac07d02bb..3088673132 100644 --- a/src/runtime-rs/crates/resource/src/manager_inner.rs +++ b/src/runtime-rs/crates/resource/src/manager_inner.rs @@ -71,12 +71,21 @@ impl ResourceManagerInner { for dc in device_configs { match dc { ResourceConfig::ShareFs(c) => { - let share_fs = share_fs::new(&self.sid, &c).context("new share fs")?; - share_fs - .setup_device_before_start_vm(self.hypervisor.as_ref()) - .await - .context("setup share fs device before start vm")?; - self.share_fs = Some(share_fs); + self.share_fs = if self + .hypervisor + .capabilities() + .await? + .is_fs_sharing_supported() + { + let share_fs = share_fs::new(&self.sid, &c).context("new share fs")?; + share_fs + .setup_device_before_start_vm(self.hypervisor.as_ref()) + .await + .context("setup share fs device before start vm")?; + Some(share_fs) + } else { + None + }; } ResourceConfig::Network(c) => { let d = network::new(&c).await.context("new network")?;