kata-types: Add Cloud Hypervisor (CH) definitions

Implement `ConfigPlugin` trait for Cloud Hypervisor (CH).

Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
James O. D. Hunt 2023-02-01 11:13:00 +00:00
parent 95602c8c08
commit 545151829d
4 changed files with 165 additions and 2 deletions

View File

@ -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;

View File

@ -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(())
}
}

View File

@ -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";

View File

@ -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;