libs/types: support load Kata hypervisor configuration from file

Add structures to load Kata hypevisor configuration from configuration
files. Also define a mechanisms to:
1) for hypervisors to handle the configuration info.
2) for vendor to extend the Kata configuration structure.

Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
Liu Jiang 2021-12-26 21:32:58 +08:00 committed by Fupan Li
parent 21cc02d724
commit 69f10afb71
10 changed files with 1661 additions and 1 deletions

54
src/libs/Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.57"
@ -225,6 +234,12 @@ dependencies = [
"slab",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hashbrown"
version = "0.11.2"
@ -240,6 +255,15 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.8.1"
@ -287,8 +311,11 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
name = "kata-types"
version = "0.1.0"
dependencies = [
"glob",
"lazy_static",
"num_cpus",
"oci",
"regex",
"serde",
"slog",
"slog-scope",
@ -427,6 +454,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "oci"
version = "0.1.0"
@ -584,6 +621,23 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
version = "0.5.3"

View File

@ -11,7 +11,10 @@ license = "Apache-2.0"
edition = "2018"
[dependencies]
glob = "0.3.0"
lazy_static = "1.4.0"
num_cpus = "1.13.1"
regex = "1.5.4"
serde = { version = "1.0.100", features = ["derive"] }
slog = "2.5.2"
slog-scope = "4.4.0"

View File

@ -21,3 +21,40 @@ lazy_static! {
}
pub const DEFAULT_INTERNETWORKING_MODEL: &str = "tcfilter";
pub const DEFAULT_BLOCK_DEVICE_TYPE: &str = "virtio-blk";
pub const DEFAULT_VHOST_USER_STORE_PATH: &str = "/var/run/vhost-user";
pub const DEFAULT_BLOCK_NVDIMM_MEM_OFFSET: u64 = 0;
pub const DEFAULT_SHARED_FS_TYPE: &str = "virtio-9p";
pub const DEFAULT_VIRTIO_FS_CACHE_MODE: &str = "none";
pub const DEFAULT_VIRTIO_FS_DAX_SIZE_MB: u32 = 1024;
pub const DEFAULT_SHARED_9PFS_SIZE: u32 = 128 * 1024;
pub const MIN_SHARED_9PFS_SIZE: u32 = 4 * 1024;
pub const MAX_SHARED_9PFS_SIZE: u32 = 8 * 1024 * 1024;
pub const DEFAULT_GUEST_HOOK_PATH: &str = "/opt";
pub const DEFAULT_GUEST_VCPUS: u32 = 1;
// Default configuration for Dragonball
pub const DEFAULT_DB_GUEST_KENREL_IMAGE: &str = "vmlinuz";
pub const DEFAULT_DB_GUEST_KENREL_PARAMS: &str = "";
pub const DEFAULT_DB_ENTROPY_SOURCE: &str = "/dev/urandom";
pub const DEFAULT_DB_MEMORY_SIZE: u32 = 128;
pub const DEFAULT_DB_MEMORY_SLOTS: u32 = 128;
pub const MAX_DB_VCPUS: u32 = 256;
// Default configuration for qemu
pub const DEFAULT_QEMU_BINARY_PATH: &str = "qemu";
pub const DEFAULT_QEMU_CONTROL_PATH: &str = "";
pub const DEFAULT_QEMU_MACHINE_TYPE: &str = "q35";
pub const DEFAULT_QEMU_ENTROPY_SOURCE: &str = "/dev/urandom";
pub const DEFAULT_QEMU_GUEST_KENREL_IMAGE: &str = "vmlinuz";
pub const DEFAULT_QEMU_GUEST_KENREL_PARAMS: &str = "";
pub const DEFAULT_QEMU_FIRMWARE_PATH: &str = "";
pub const DEFAULT_QEMU_MEMORY_SIZE: u32 = 128;
pub const DEFAULT_QEMU_MEMORY_SLOTS: u32 = 128;
pub const DEFAULT_QEMU_PCI_BRIDGES: u32 = 2;
pub const MAX_QEMU_PCI_BRIDGES: u32 = 5;
pub const MAX_QEMU_VCPUS: u32 = 256;

View File

@ -0,0 +1,176 @@
// Copyright (c) 2019-2021 Alibaba Cloud
//
// 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::hypervisor::{
VIRTIO_BLK, VIRTIO_BLK_MMIO, VIRTIO_FS, VIRTIO_FS_INLINE, VIRTIO_PMEM,
};
use crate::config::{ConfigPlugin, TomlConfig};
use crate::{eother, resolve_path, validate_path};
/// Hypervisor name for qemu, used to index `TomlConfig::hypervisor`.
pub const HYPERVISOR_NAME_DRAGONBALL: &str = "dragonball";
/// Configuration information for dragonball.
#[derive(Default, Debug)]
pub struct DragonballConfig {}
impl DragonballConfig {
/// Create a new instance of `DragonballConfig`.
pub fn new() -> Self {
DragonballConfig {}
}
/// Register the dragonball plugin.
pub fn register(self) {
let plugin = Arc::new(self);
register_hypervisor_plugin(HYPERVISOR_NAME_DRAGONBALL, plugin);
}
}
impl ConfigPlugin for DragonballConfig {
fn name(&self) -> &str {
HYPERVISOR_NAME_DRAGONBALL
}
/// Adjust the configuration information after loading from configuration file.
fn adjust_configuration(&self, conf: &mut TomlConfig) -> Result<()> {
if let Some(db) = conf.hypervisor.get_mut(HYPERVISOR_NAME_DRAGONBALL) {
resolve_path!(db.jailer_path, "Dragonball jailer path {} is invalid: {}")?;
if db.boot_info.kernel.is_empty() {
db.boot_info.kernel = default::DEFAULT_DB_GUEST_KENREL_IMAGE.to_string();
}
if db.boot_info.kernel_params.is_empty() {
db.boot_info.kernel_params = default::DEFAULT_DB_GUEST_KENREL_PARAMS.to_string();
}
if db.cpu_info.default_maxvcpus > default::MAX_DB_VCPUS {
db.cpu_info.default_maxvcpus = default::MAX_DB_VCPUS;
}
if db.machine_info.entropy_source.is_empty() {
db.machine_info.entropy_source = default::DEFAULT_DB_ENTROPY_SOURCE.to_string();
}
if db.memory_info.default_memory == 0 {
db.memory_info.default_memory = default::DEFAULT_DB_MEMORY_SIZE;
}
if db.memory_info.memory_slots == 0 {
db.memory_info.memory_slots = default::DEFAULT_DB_MEMORY_SLOTS;
}
}
Ok(())
}
/// Validate the configuration information.
fn validate(&self, conf: &TomlConfig) -> Result<()> {
if let Some(db) = conf.hypervisor.get(HYPERVISOR_NAME_DRAGONBALL) {
if !db.path.is_empty() {
return Err(eother!("Path for dragonball hypervisor should be empty"));
}
if !db.valid_hypervisor_paths.is_empty() {
return Err(eother!(
"Valid hypervisor path for dragonball hypervisor should be empty"
));
}
if !db.ctlpath.is_empty() {
return Err(eother!("CtlPath for dragonball hypervisor should be empty"));
}
if !db.valid_ctlpaths.is_empty() {
return Err(eother!("CtlPath for dragonball hypervisor should be empty"));
}
validate_path!(db.jailer_path, "Dragonball jailer path {} is invalid: {}")?;
if db.enable_iothreads {
return Err(eother!("Dragonball hypervisor doesn't support IO threads."));
}
if !db.blockdev_info.disable_block_device_use
&& db.blockdev_info.block_device_driver != VIRTIO_BLK
&& db.blockdev_info.block_device_driver != VIRTIO_BLK_MMIO
&& db.blockdev_info.block_device_driver != VIRTIO_PMEM
{
return Err(eother!(
"{} is unsupported block device type.",
db.blockdev_info.block_device_driver
));
}
if db.boot_info.kernel.is_empty() {
return Err(eother!(
"Guest kernel image for dragonball hypervisor is empty"
));
}
if db.boot_info.image.is_empty() {
return Err(eother!(
"Guest boot image for dragonball hypervisor is empty"
));
}
if !db.boot_info.initrd.is_empty() {
return Err(eother!("Initrd for dragonball hypervisor should be empty"));
}
if !db.boot_info.firmware.is_empty() {
return Err(eother!(
"Firmware for dragonball hypervisor should be empty"
));
}
if (db.cpu_info.default_vcpus > 0
&& db.cpu_info.default_vcpus as u32 > default::MAX_DB_VCPUS)
|| db.cpu_info.default_maxvcpus > default::MAX_DB_VCPUS
{
return Err(eother!(
"Dragonball hypervisor can not support {} vCPUs",
db.cpu_info.default_maxvcpus
));
}
if db.device_info.enable_iommu || db.device_info.enable_iommu_platform {
return Err(eother!("Dragonball hypervisor does not support vIOMMU"));
}
if db.device_info.hotplug_vfio_on_root_bus
|| db.device_info.default_bridges > 0
|| db.device_info.pcie_root_port > 0
{
return Err(eother!(
"Dragonball hypervisor does not support PCI hotplug options"
));
}
if !db.machine_info.machine_type.is_empty() {
return Err(eother!(
"Dragonball hypervisor does not support machine_type"
));
}
if !db.machine_info.pflashes.is_empty() {
return Err(eother!("Dragonball hypervisor does not support pflashes"));
}
if db.memory_info.enable_guest_swap {
return Err(eother!(
"Dragonball hypervisor doesn't support enable_guest_swap"
));
}
if db.security_info.rootless {
return Err(eother!(
"Dragonball hypervisor does not support rootless mode"
));
}
if let Some(v) = db.shared_fs.shared_fs.as_ref() {
if v != VIRTIO_FS && v != VIRTIO_FS_INLINE {
return Err(eother!("Dragonball hypervisor doesn't support {}", v));
}
}
}
Ok(())
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
// Copyright (c) 2019-2021 Alibaba Cloud
//
// 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::hypervisor::VIRTIO_BLK_MMIO;
use crate::config::{ConfigPlugin, TomlConfig};
use crate::{eother, resolve_path, validate_path};
/// Hypervisor name for qemu, used to index `TomlConfig::hypervisor`.
pub const HYPERVISOR_NAME_QEMU: &str = "qemu";
/// Configuration information for qemu.
#[derive(Default, Debug)]
pub struct QemuConfig {}
impl QemuConfig {
/// Create a new instance of `QemuConfig`.
pub fn new() -> Self {
QemuConfig {}
}
/// Register the qemu plugin.
pub fn register(self) {
let plugin = Arc::new(self);
register_hypervisor_plugin(HYPERVISOR_NAME_QEMU, plugin);
}
}
impl ConfigPlugin for QemuConfig {
fn name(&self) -> &str {
HYPERVISOR_NAME_QEMU
}
/// Adjust the configuration information after loading from configuration file.
fn adjust_configuration(&self, conf: &mut TomlConfig) -> Result<()> {
if let Some(qemu) = conf.hypervisor.get_mut(HYPERVISOR_NAME_QEMU) {
if qemu.path.is_empty() {
qemu.path = default::DEFAULT_QEMU_BINARY_PATH.to_string();
}
resolve_path!(qemu.path, "Qemu binary path `{}` is invalid: {}")?;
if qemu.ctlpath.is_empty() {
qemu.ctlpath = default::DEFAULT_QEMU_CONTROL_PATH.to_string();
}
resolve_path!(qemu.ctlpath, "Qemu ctlpath `{}` is invalid: {}")?;
if qemu.boot_info.kernel.is_empty() {
qemu.boot_info.kernel = default::DEFAULT_QEMU_GUEST_KENREL_IMAGE.to_string();
}
if qemu.boot_info.kernel_params.is_empty() {
qemu.boot_info.kernel_params =
default::DEFAULT_QEMU_GUEST_KENREL_PARAMS.to_string();
}
if qemu.boot_info.firmware.is_empty() {
qemu.boot_info.firmware = default::DEFAULT_QEMU_FIRMWARE_PATH.to_string();
}
if qemu.device_info.default_bridges == 0 {
qemu.device_info.default_bridges = default::DEFAULT_QEMU_PCI_BRIDGES;
if qemu.device_info.default_bridges > default::MAX_QEMU_PCI_BRIDGES {
qemu.device_info.default_bridges = default::MAX_QEMU_PCI_BRIDGES;
}
}
if qemu.machine_info.machine_type.is_empty() {
qemu.machine_info.machine_type = default::DEFAULT_QEMU_MACHINE_TYPE.to_string();
}
if qemu.machine_info.entropy_source.is_empty() {
qemu.machine_info.entropy_source = default::DEFAULT_QEMU_ENTROPY_SOURCE.to_string();
}
if qemu.memory_info.default_memory == 0 {
qemu.memory_info.default_memory = default::DEFAULT_QEMU_MEMORY_SIZE;
}
if qemu.memory_info.memory_slots == 0 {
qemu.memory_info.memory_slots = default::DEFAULT_QEMU_MEMORY_SLOTS;
}
}
Ok(())
}
/// Validate the configuration information.
fn validate(&self, conf: &TomlConfig) -> Result<()> {
if let Some(qemu) = conf.hypervisor.get(HYPERVISOR_NAME_QEMU) {
validate_path!(qemu.path, "Qemu binary path `{}` is invalid: {}")?;
validate_path!(qemu.ctlpath, "Qemu control path `{}` is invalid: {}")?;
if !qemu.jailer_path.is_empty() {
return Err(eother!("Path for Qemu jailer should be empty"));
}
if !qemu.valid_jailer_paths.is_empty() {
return Err(eother!("Valid Qemu jailer path list should be empty"));
}
if !qemu.blockdev_info.disable_block_device_use
&& qemu.blockdev_info.block_device_driver == VIRTIO_BLK_MMIO
{
return Err(eother!("Qemu doesn't support virtio-blk-mmio"));
}
if qemu.boot_info.kernel.is_empty() {
return Err(eother!("Guest kernel image for qemu is empty"));
}
if qemu.boot_info.image.is_empty() && qemu.boot_info.initrd.is_empty() {
return Err(eother!(
"Both guest boot image and initrd for qemu are empty"
));
}
if (qemu.cpu_info.default_vcpus > 0
&& qemu.cpu_info.default_vcpus as u32 > default::MAX_QEMU_VCPUS)
|| qemu.cpu_info.default_maxvcpus > default::MAX_QEMU_VCPUS
{
return Err(eother!(
"Qemu hypervisor can not support {} vCPUs",
qemu.cpu_info.default_maxvcpus
));
}
if qemu.device_info.default_bridges > default::MAX_QEMU_PCI_BRIDGES {
return Err(eother!(
"Qemu hypervisor can not support {} PCI bridges",
qemu.device_info.default_bridges
));
}
}
Ok(())
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) 2021 Alibaba Cloud
//
// SPDX-License-Identifier: Apache-2.0
//
//! A sample for vendor to customize the hypervisor implementation.
use super::*;
/// Vendor customization runtime configuration.
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct HypervisorVendor {}
impl ConfigOps for HypervisorVendor {}

View File

@ -4,19 +4,38 @@
// SPDX-License-Identifier: Apache-2.0
//
use std::collections::HashMap;
use std::fs;
use std::io::{self, Result};
use std::path::{Path, PathBuf};
use crate::sl;
use crate::{eother, sl};
/// Default configuration values.
pub mod default;
mod hypervisor;
pub use self::hypervisor::{
BootInfo, DragonballConfig, Hypervisor, QemuConfig, HYPERVISOR_NAME_DRAGONBALL,
HYPERVISOR_NAME_QEMU,
};
mod runtime;
pub use self::runtime::{Runtime, RuntimeVendor};
/// Trait to manipulate global Kata configuration information.
pub trait ConfigPlugin: Send + Sync {
/// Get the plugin name.
fn name(&self) -> &str;
/// Adjust the configuration information after loading from configuration file.
fn adjust_configuration(&self, _conf: &mut TomlConfig) -> Result<()>;
/// Validate the configuration information.
fn validate(&self, _conf: &TomlConfig) -> Result<()>;
}
/// Trait to manipulate Kata configuration information.
pub trait ConfigOps {
/// Adjust the configuration information after loading from configuration file.
fn adjust_configuration(_conf: &mut TomlConfig) -> Result<()> {
@ -45,6 +64,9 @@ pub trait ConfigObjectOps {
/// Kata configuration information.
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct TomlConfig {
/// Configuration information for hypervisors.
#[serde(default)]
pub hypervisor: HashMap<String, Hypervisor>,
/// Kata runtime configuration information.
#[serde(default)]
pub runtime: Runtime,
@ -99,6 +121,7 @@ impl TomlConfig {
pub fn load(content: &str) -> Result<TomlConfig> {
let mut config: TomlConfig = toml::from_str(content)?;
Hypervisor::adjust_configuration(&mut config)?;
Runtime::adjust_configuration(&mut config)?;
info!(sl!(), "get kata config: {:?}", config);
@ -107,6 +130,7 @@ impl TomlConfig {
/// Validate Kata configuration information.
pub fn validate(&self) -> Result<()> {
Hypervisor::validate(self)?;
Runtime::validate(self)?;
Ok(())
@ -123,3 +147,49 @@ impl TomlConfig {
Err(io::Error::from(io::ErrorKind::NotFound))
}
}
/// Validate the `path` matches one of the pattern in `patterns`.
///
/// Each member in `patterns` is a path pattern as described by glob(3)
pub fn validate_path_pattern<P: AsRef<Path>>(patterns: &[String], path: P) -> Result<()> {
let path = path
.as_ref()
.to_str()
.ok_or_else(|| eother!("Invalid path {}", path.as_ref().to_string_lossy()))?;
for p in patterns.iter() {
if let Ok(glob) = glob::Pattern::new(p) {
if glob.matches(path) {
return Ok(());
}
}
}
Err(eother!("Path {} is not permitted", path))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_path_pattern() {
let patterns = [];
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
let patterns = ["/bin".to_string()];
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
let patterns = ["/bin/*/ls".to_string()];
validate_path_pattern(&patterns, "/bin/ls").unwrap_err();
let patterns = ["/bin/*".to_string()];
validate_path_pattern(&patterns, "/bin/ls").unwrap();
let patterns = ["/*".to_string()];
validate_path_pattern(&patterns, "/bin/ls").unwrap();
let patterns = ["/usr/share".to_string(), "/bin/*".to_string()];
validate_path_pattern(&patterns, "/bin/ls").unwrap();
}
}

View File

@ -0,0 +1,41 @@
use kata_types::config::{QemuConfig, TomlConfig, HYPERVISOR_NAME_QEMU};
use std::fs;
use std::path::Path;
#[test]
fn test_load_qemu_config() {
let plugin = QemuConfig::new();
plugin.register();
let path = env!("CARGO_MANIFEST_DIR");
let path = Path::new(path).join("tests/texture/configuration-qemu.toml");
let content = fs::read_to_string(&path).unwrap();
let config = TomlConfig::load(&content).unwrap();
let qemu = config.hypervisor.get(HYPERVISOR_NAME_QEMU).unwrap();
assert_eq!(qemu.path, "/usr/bin/ls");
assert_eq!(qemu.valid_hypervisor_paths.len(), 2);
assert_eq!(qemu.valid_hypervisor_paths[0], "/usr/bin/qemu*");
assert_eq!(qemu.valid_hypervisor_paths[1], "/opt/qemu?");
qemu.validate_hypervisor_path("/usr/bin/qemu0").unwrap();
qemu.validate_hypervisor_path("/usr/bin/qemu1").unwrap();
qemu.validate_hypervisor_path("/usr/bin/qemu2222").unwrap();
qemu.validate_hypervisor_path("/opt/qemu3").unwrap();
qemu.validate_hypervisor_path("/opt/qemu").unwrap_err();
qemu.validate_hypervisor_path("/opt/qemu33").unwrap_err();
assert_eq!(qemu.ctlpath, "/usr/bin/ls");
assert_eq!(qemu.valid_ctlpaths.len(), 0);
assert!(qemu.jailer_path.is_empty());
assert_eq!(qemu.valid_jailer_paths.len(), 0);
assert_eq!(qemu.disable_nesting_checks, true);
assert_eq!(qemu.enable_iothreads, true);
assert_eq!(qemu.boot_info.image, "/usr/bin/echo");
assert_eq!(qemu.boot_info.kernel, "/usr/bin/id");
assert_eq!(qemu.boot_info.kernel_params, "ro");
assert_eq!(qemu.boot_info.firmware, "/etc/hostname");
assert_eq!(qemu.cpu_info.cpu_features, "pmu=off,vmx=off");
assert_eq!(qemu.cpu_info.default_vcpus, 2);
assert_eq!(qemu.cpu_info.default_maxvcpus, 64);
}

View File

@ -0,0 +1,78 @@
[hypervisor.qemu]
path = "/usr/bin/ls"
valid_hypervisor_paths = ["/usr/bin/qemu*", "/opt/qemu?"]
ctlpath = "/usr/bin/ls"
disable_nesting_checks = true
enable_iothreads = true
kernel = "/usr/bin/../bin/id"
image = "/usr/bin/./echo"
kernel_params = "ro"
firmware = "/etc/hostname"
cpu_features="pmu=off,vmx=off"
default_vcpus = 2
default_maxvcpus = 64
machine_type = "q35"
confidential_guest = true
rootless = true
enable_annotations = ["path", "ctlpath"]
machine_accelerators="noapic"
default_bridges = 2
default_memory = 128
memory_slots = 128
memory_offset = 0x100000
enable_virtio_mem = true
disable_block_device_use = false
shared_fs = "virtio-fs"
virtio_fs_daemon = "/usr/bin/id"
valid_virtio_fs_daemon_paths = ["/usr/local/bin/virtiofsd*"]
virtio_fs_cache_size = 512
virtio_fs_extra_args = ["-o", "arg1=xxx,arg2", "-o", "hello world", "--arg3=yyy"]
virtio_fs_cache = "always"
block_device_driver = "virtio-blk"
block_device_cache_set = true
block_device_cache_direct = true
block_device_cache_noflush = true
enable_mem_prealloc = true
enable_hugepages = true
enable_vhost_user_store = true
vhost_user_store_path = "/tmp"
valid_vhost_user_store_paths = ["/var/kata/vhost-user-store*", "/tmp/kata?"]
enable_iommu = true
enable_iommu_platform = true
file_mem_backend = "/dev/shm"
valid_file_mem_backends = ["/dev/shm"]
enable_swap = true
pflashes = ["/proc/mounts"]
enable_debug = true
msize_9p = 16384
disable_image_nvdimm = true
hotplug_vfio_on_root_bus = true
pcie_root_port = 2
disable_vhost_net = true
entropy_source= "/dev/urandom"
valid_entropy_sources = ["/dev/urandom", "/dev/random"]
guest_hook_path = "/usr/share/oci/hooks"
rx_rate_limiter_max_rate = 10000
tx_rate_limiter_max_rate = 10000
guest_memory_dump_path="/var/crash/kata"
guest_memory_dump_paging = true
enable_guest_swap = true
[runtime]
enable_debug = true
internetworking_model="macvtap"
disable_guest_seccomp=true
enable_tracing = true
jaeger_endpoint = "localhost:1234"
jaeger_user = "user"
jaeger_password = "pw"
disable_new_netns = true
sandbox_cgroup_only=true
sandbox_bind_mounts=["/proc/self"]
vfio_mode="vfio"
experimental=["a", "b"]
enable_pprof = true