From 545151829d517f77962cfa6577274587b120b580 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 1 Feb 2023 11:13:00 +0000 Subject: [PATCH] kata-types: Add Cloud Hypervisor (CH) definitions Implement `ConfigPlugin` trait for Cloud Hypervisor (CH). Signed-off-by: James O. D. Hunt --- src/libs/kata-types/src/config/default.rs | 14 ++ .../kata-types/src/config/hypervisor/ch.rs | 146 ++++++++++++++++++ .../kata-types/src/config/hypervisor/mod.rs | 3 + src/libs/kata-types/src/config/mod.rs | 4 +- 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 src/libs/kata-types/src/config/hypervisor/ch.rs diff --git a/src/libs/kata-types/src/config/default.rs b/src/libs/kata-types/src/config/default.rs index bf6b36a40..aa32b59fc 100644 --- a/src/libs/kata-types/src/config/default.rs +++ b/src/libs/kata-types/src/config/default.rs @@ -67,3 +67,17 @@ pub const DEFAULT_QEMU_PCI_BRIDGES: u32 = 2; pub const MAX_QEMU_PCI_BRIDGES: u32 = 5; pub const MAX_QEMU_VCPUS: u32 = 256; pub const MIN_QEMU_MEMORY_SIZE_MB: u32 = 64; + +// Default configuration for Cloud Hypervisor (CH) +pub const DEFAULT_CH_BINARY_PATH: &str = "/usr/bin/cloud-hypervisor"; +pub const DEFAULT_CH_CONTROL_PATH: &str = ""; +pub const DEFAULT_CH_ENTROPY_SOURCE: &str = "/dev/urandom"; +pub const DEFAULT_CH_GUEST_KERNEL_IMAGE: &str = "vmlinuz"; +pub const DEFAULT_CH_GUEST_KERNEL_PARAMS: &str = ""; +pub const DEFAULT_CH_FIRMWARE_PATH: &str = ""; +pub const DEFAULT_CH_MEMORY_SIZE_MB: u32 = 128; +pub const DEFAULT_CH_MEMORY_SLOTS: u32 = 128; +pub const DEFAULT_CH_PCI_BRIDGES: u32 = 2; +pub const MAX_CH_PCI_BRIDGES: u32 = 5; +pub const MAX_CH_VCPUS: u32 = 256; +pub const MIN_CH_MEMORY_SIZE_MB: u32 = 64; diff --git a/src/libs/kata-types/src/config/hypervisor/ch.rs b/src/libs/kata-types/src/config/hypervisor/ch.rs new file mode 100644 index 000000000..cc752e385 --- /dev/null +++ b/src/libs/kata-types/src/config/hypervisor/ch.rs @@ -0,0 +1,146 @@ +// Copyright (c) 2019-2021 Alibaba Cloud +// Copyright (c) 2022-2023 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use std::io::Result; +use std::path::Path; +use std::sync::Arc; + +use super::{default, register_hypervisor_plugin}; + +use crate::config::default::MAX_CH_VCPUS; +use crate::config::default::MIN_CH_MEMORY_SIZE_MB; + +use crate::config::hypervisor::VIRTIO_BLK_MMIO; +use crate::config::{ConfigPlugin, TomlConfig}; +use crate::{eother, resolve_path, validate_path}; + +/// Hypervisor name for CH, used to index `TomlConfig::hypervisor`. +pub const HYPERVISOR_NAME_CH: &str = "cloud-hypervisor"; + +/// Configuration information for CH. +#[derive(Default, Debug)] +pub struct CloudHypervisorConfig {} + +impl CloudHypervisorConfig { + /// Create a new instance of `CloudHypervisorConfig`. + pub fn new() -> Self { + CloudHypervisorConfig {} + } + + /// Register the CH plugin. + pub fn register(self) { + let plugin = Arc::new(self); + register_hypervisor_plugin(HYPERVISOR_NAME_CH, plugin); + } +} + +impl ConfigPlugin for CloudHypervisorConfig { + fn get_max_cpus(&self) -> u32 { + MAX_CH_VCPUS + } + + fn get_min_memory(&self) -> u32 { + MIN_CH_MEMORY_SIZE_MB + } + + fn name(&self) -> &str { + HYPERVISOR_NAME_CH + } + + /// Adjust the configuration information after loading from configuration file. + fn adjust_config(&self, conf: &mut TomlConfig) -> Result<()> { + if let Some(ch) = conf.hypervisor.get_mut(HYPERVISOR_NAME_CH) { + if ch.path.is_empty() { + ch.path = default::DEFAULT_CH_BINARY_PATH.to_string(); + } + resolve_path!(ch.path, "CH binary path `{}` is invalid: {}")?; + if ch.ctlpath.is_empty() { + ch.ctlpath = default::DEFAULT_CH_CONTROL_PATH.to_string(); + } + resolve_path!(ch.ctlpath, "CH ctlpath `{}` is invalid: {}")?; + + if ch.boot_info.kernel.is_empty() { + ch.boot_info.kernel = default::DEFAULT_CH_GUEST_KERNEL_IMAGE.to_string(); + } + if ch.boot_info.kernel_params.is_empty() { + ch.boot_info.kernel_params = default::DEFAULT_CH_GUEST_KERNEL_PARAMS.to_string(); + } + if ch.boot_info.firmware.is_empty() { + ch.boot_info.firmware = default::DEFAULT_CH_FIRMWARE_PATH.to_string(); + } + + if ch.device_info.default_bridges == 0 { + ch.device_info.default_bridges = default::DEFAULT_CH_PCI_BRIDGES; + } + + if ch.machine_info.entropy_source.is_empty() { + ch.machine_info.entropy_source = default::DEFAULT_CH_ENTROPY_SOURCE.to_string(); + } + + if ch.memory_info.default_memory == 0 { + ch.memory_info.default_memory = default::DEFAULT_CH_MEMORY_SIZE_MB; + } + if ch.memory_info.memory_slots == 0 { + ch.memory_info.memory_slots = default::DEFAULT_CH_MEMORY_SLOTS; + } + } + + Ok(()) + } + + /// Validate the configuration information. + fn validate(&self, conf: &TomlConfig) -> Result<()> { + if let Some(ch) = conf.hypervisor.get(HYPERVISOR_NAME_CH) { + validate_path!(ch.path, "CH binary path `{}` is invalid: {}")?; + validate_path!(ch.ctlpath, "CH control path `{}` is invalid: {}")?; + if !ch.jailer_path.is_empty() { + return Err(eother!("Path for CH jailer should be empty")); + } + if !ch.valid_jailer_paths.is_empty() { + return Err(eother!("Valid CH jailer path list should be empty")); + } + + if !ch.blockdev_info.disable_block_device_use + && ch.blockdev_info.block_device_driver == VIRTIO_BLK_MMIO + { + return Err(eother!("CH doesn't support virtio-blk-mmio")); + } + + if ch.boot_info.kernel.is_empty() { + return Err(eother!("Guest kernel image for CH is empty")); + } + if ch.boot_info.image.is_empty() && ch.boot_info.initrd.is_empty() { + return Err(eother!("Both guest boot image and initrd for CH are empty")); + } + + if (ch.cpu_info.default_vcpus > 0 + && ch.cpu_info.default_vcpus as u32 > default::MAX_CH_VCPUS) + || ch.cpu_info.default_maxvcpus > default::MAX_CH_VCPUS + { + return Err(eother!( + "CH hypervisor cannot support {} vCPUs", + ch.cpu_info.default_maxvcpus + )); + } + + if ch.device_info.default_bridges > default::MAX_CH_PCI_BRIDGES { + return Err(eother!( + "CH hypervisor cannot support {} PCI bridges", + ch.device_info.default_bridges + )); + } + + if ch.memory_info.default_memory < MIN_CH_MEMORY_SIZE_MB { + return Err(eother!( + "CH hypervisor has minimal memory limitation {}", + MIN_CH_MEMORY_SIZE_MB + )); + } + } + + Ok(()) + } +} diff --git a/src/libs/kata-types/src/config/hypervisor/mod.rs b/src/libs/kata-types/src/config/hypervisor/mod.rs index 2eaa3443b..98ae2cc79 100644 --- a/src/libs/kata-types/src/config/hypervisor/mod.rs +++ b/src/libs/kata-types/src/config/hypervisor/mod.rs @@ -40,6 +40,9 @@ pub use self::dragonball::{DragonballConfig, HYPERVISOR_NAME_DRAGONBALL}; mod qemu; pub use self::qemu::{QemuConfig, HYPERVISOR_NAME_QEMU}; +mod ch; +pub use self::ch::{CloudHypervisorConfig, HYPERVISOR_NAME_CH}; + const VIRTIO_BLK: &str = "virtio-blk"; const VIRTIO_BLK_MMIO: &str = "virtio-mmio"; const VIRTIO_BLK_CCW: &str = "virtio-blk-ccw"; diff --git a/src/libs/kata-types/src/config/mod.rs b/src/libs/kata-types/src/config/mod.rs index 863dd7590..173026921 100644 --- a/src/libs/kata-types/src/config/mod.rs +++ b/src/libs/kata-types/src/config/mod.rs @@ -25,8 +25,8 @@ pub mod hypervisor; pub use self::agent::Agent; use self::default::DEFAULT_AGENT_DBG_CONSOLE_PORT; pub use self::hypervisor::{ - BootInfo, DragonballConfig, Hypervisor, QemuConfig, HYPERVISOR_NAME_DRAGONBALL, - HYPERVISOR_NAME_QEMU, + BootInfo, CloudHypervisorConfig, DragonballConfig, Hypervisor, QemuConfig, + HYPERVISOR_NAME_DRAGONBALL, HYPERVISOR_NAME_QEMU, }; mod runtime;