mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Add a 'rate_limit_groups' field to VmConfig that defines a set of named RateLimiterGroups. When the 'rate_limit_group' field of DiskConfig is defined, all virtio-blk queues will be rate-limited by a shared RateLimiterGroup. The lifecycle of all RateLimiterGroups is tied to the Vm. A RateLimiterGroup may exist even if no Disks are configured to use the RateLimiterGroup. Disks may be hot-added or hot-removed from the RateLimiterGroup. When the 'rate_limiter' field of DiskConfig is defined, we construct an anonymous RateLimiterGroup whose lifecycle is tied to the Disk. This is primarily done for api backwards compatability. Importantly, the behavior is not the same! This implementation rate_limits the aggregate bandwidth / iops of an individual disk rather than the bandwidth / iops of an individual queue of a disk. When neither the 'rate_limit_group' or the 'rate_limiter' fields of DiskConfig is defined, the Disk is not rate-limited. Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
651 lines
17 KiB
Rust
651 lines
17 KiB
Rust
// Copyright © 2022 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
use net_util::MacAddr;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{net::Ipv4Addr, path::PathBuf};
|
|
use virtio_devices::RateLimiterConfig;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct CpuAffinity {
|
|
pub vcpu: u8,
|
|
pub host_cpus: Vec<u8>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct CpuFeatures {
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[serde(default)]
|
|
pub amx: bool,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct CpuTopology {
|
|
pub threads_per_core: u8,
|
|
pub cores_per_die: u8,
|
|
pub dies_per_package: u8,
|
|
pub packages: u8,
|
|
}
|
|
|
|
// When booting with PVH boot the maximum physical addressable size
|
|
// is a 46 bit address space even when the host supports with 5-level
|
|
// paging.
|
|
pub const DEFAULT_MAX_PHYS_BITS: u8 = 46;
|
|
|
|
pub fn default_cpuconfig_max_phys_bits() -> u8 {
|
|
DEFAULT_MAX_PHYS_BITS
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct CpusConfig {
|
|
pub boot_vcpus: u8,
|
|
pub max_vcpus: u8,
|
|
#[serde(default)]
|
|
pub topology: Option<CpuTopology>,
|
|
#[serde(default)]
|
|
pub kvm_hyperv: bool,
|
|
#[serde(default = "default_cpuconfig_max_phys_bits")]
|
|
pub max_phys_bits: u8,
|
|
#[serde(default)]
|
|
pub affinity: Option<Vec<CpuAffinity>>,
|
|
#[serde(default)]
|
|
pub features: CpuFeatures,
|
|
}
|
|
|
|
pub const DEFAULT_VCPUS: u8 = 1;
|
|
|
|
impl Default for CpusConfig {
|
|
fn default() -> Self {
|
|
CpusConfig {
|
|
boot_vcpus: DEFAULT_VCPUS,
|
|
max_vcpus: DEFAULT_VCPUS,
|
|
topology: None,
|
|
kvm_hyperv: false,
|
|
max_phys_bits: DEFAULT_MAX_PHYS_BITS,
|
|
affinity: None,
|
|
features: CpuFeatures::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub const DEFAULT_NUM_PCI_SEGMENTS: u16 = 1;
|
|
pub fn default_platformconfig_num_pci_segments() -> u16 {
|
|
DEFAULT_NUM_PCI_SEGMENTS
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct PlatformConfig {
|
|
#[serde(default = "default_platformconfig_num_pci_segments")]
|
|
pub num_pci_segments: u16,
|
|
#[serde(default)]
|
|
pub iommu_segments: Option<Vec<u16>>,
|
|
#[serde(default)]
|
|
pub serial_number: Option<String>,
|
|
#[serde(default)]
|
|
pub uuid: Option<String>,
|
|
#[serde(default)]
|
|
pub oem_strings: Option<Vec<String>>,
|
|
#[cfg(feature = "tdx")]
|
|
#[serde(default)]
|
|
pub tdx: bool,
|
|
#[cfg(feature = "sev_snp")]
|
|
#[serde(default)]
|
|
pub sev_snp: bool,
|
|
}
|
|
|
|
impl Default for PlatformConfig {
|
|
fn default() -> Self {
|
|
PlatformConfig {
|
|
num_pci_segments: DEFAULT_NUM_PCI_SEGMENTS,
|
|
iommu_segments: None,
|
|
serial_number: None,
|
|
uuid: None,
|
|
oem_strings: None,
|
|
#[cfg(feature = "tdx")]
|
|
tdx: false,
|
|
#[cfg(feature = "sev_snp")]
|
|
sev_snp: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct MemoryZoneConfig {
|
|
pub id: String,
|
|
pub size: u64,
|
|
#[serde(default)]
|
|
pub file: Option<PathBuf>,
|
|
#[serde(default)]
|
|
pub shared: bool,
|
|
#[serde(default)]
|
|
pub hugepages: bool,
|
|
#[serde(default)]
|
|
pub hugepage_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub host_numa_node: Option<u32>,
|
|
#[serde(default)]
|
|
pub hotplug_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub hotplugged_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub prefault: bool,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub enum HotplugMethod {
|
|
#[default]
|
|
Acpi,
|
|
VirtioMem,
|
|
}
|
|
|
|
fn default_memoryconfig_thp() -> bool {
|
|
true
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct MemoryConfig {
|
|
pub size: u64,
|
|
#[serde(default)]
|
|
pub mergeable: bool,
|
|
#[serde(default)]
|
|
pub hotplug_method: HotplugMethod,
|
|
#[serde(default)]
|
|
pub hotplug_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub hotplugged_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub shared: bool,
|
|
#[serde(default)]
|
|
pub hugepages: bool,
|
|
#[serde(default)]
|
|
pub hugepage_size: Option<u64>,
|
|
#[serde(default)]
|
|
pub prefault: bool,
|
|
#[serde(default)]
|
|
pub zones: Option<Vec<MemoryZoneConfig>>,
|
|
#[serde(default = "default_memoryconfig_thp")]
|
|
pub thp: bool,
|
|
}
|
|
|
|
pub const DEFAULT_MEMORY_MB: u64 = 512;
|
|
|
|
impl Default for MemoryConfig {
|
|
fn default() -> Self {
|
|
MemoryConfig {
|
|
size: DEFAULT_MEMORY_MB << 20,
|
|
mergeable: false,
|
|
hotplug_method: HotplugMethod::Acpi,
|
|
hotplug_size: None,
|
|
hotplugged_size: None,
|
|
shared: false,
|
|
hugepages: false,
|
|
hugepage_size: None,
|
|
prefault: false,
|
|
zones: None,
|
|
thp: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub enum VhostMode {
|
|
#[default]
|
|
Client,
|
|
Server,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct RateLimiterGroupConfig {
|
|
#[serde(default)]
|
|
pub id: String,
|
|
#[serde(default)]
|
|
pub rate_limiter_config: RateLimiterConfig,
|
|
}
|
|
|
|
impl Default for RateLimiterGroupConfig {
|
|
fn default() -> Self {
|
|
RateLimiterGroupConfig {
|
|
id: "".to_string(),
|
|
rate_limiter_config: RateLimiterConfig::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct DiskConfig {
|
|
pub path: Option<PathBuf>,
|
|
#[serde(default)]
|
|
pub readonly: bool,
|
|
#[serde(default)]
|
|
pub direct: bool,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default = "default_diskconfig_num_queues")]
|
|
pub num_queues: usize,
|
|
#[serde(default = "default_diskconfig_queue_size")]
|
|
pub queue_size: u16,
|
|
#[serde(default)]
|
|
pub vhost_user: bool,
|
|
pub vhost_socket: Option<String>,
|
|
#[serde(default)]
|
|
pub rate_limit_group: Option<String>,
|
|
#[serde(default)]
|
|
pub rate_limiter_config: Option<RateLimiterConfig>,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
// For testing use only. Not exposed in API.
|
|
#[serde(default)]
|
|
pub disable_io_uring: bool,
|
|
// For testing use only. Not exposed in API.
|
|
#[serde(default)]
|
|
pub disable_aio: bool,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
#[serde(default)]
|
|
pub serial: Option<String>,
|
|
}
|
|
|
|
pub const DEFAULT_DISK_NUM_QUEUES: usize = 1;
|
|
|
|
pub fn default_diskconfig_num_queues() -> usize {
|
|
DEFAULT_DISK_NUM_QUEUES
|
|
}
|
|
|
|
pub const DEFAULT_DISK_QUEUE_SIZE: u16 = 128;
|
|
|
|
pub fn default_diskconfig_queue_size() -> u16 {
|
|
DEFAULT_DISK_QUEUE_SIZE
|
|
}
|
|
|
|
impl Default for DiskConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
path: None,
|
|
readonly: false,
|
|
direct: false,
|
|
iommu: false,
|
|
num_queues: default_diskconfig_num_queues(),
|
|
queue_size: default_diskconfig_queue_size(),
|
|
vhost_user: false,
|
|
vhost_socket: None,
|
|
id: None,
|
|
disable_io_uring: false,
|
|
disable_aio: false,
|
|
rate_limit_group: None,
|
|
rate_limiter_config: None,
|
|
pci_segment: 0,
|
|
serial: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct NetConfig {
|
|
#[serde(default = "default_netconfig_tap")]
|
|
pub tap: Option<String>,
|
|
#[serde(default = "default_netconfig_ip")]
|
|
pub ip: Ipv4Addr,
|
|
#[serde(default = "default_netconfig_mask")]
|
|
pub mask: Ipv4Addr,
|
|
#[serde(default = "default_netconfig_mac")]
|
|
pub mac: MacAddr,
|
|
#[serde(default)]
|
|
pub host_mac: Option<MacAddr>,
|
|
#[serde(default)]
|
|
pub mtu: Option<u16>,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default = "default_netconfig_num_queues")]
|
|
pub num_queues: usize,
|
|
#[serde(default = "default_netconfig_queue_size")]
|
|
pub queue_size: u16,
|
|
#[serde(default)]
|
|
pub vhost_user: bool,
|
|
pub vhost_socket: Option<String>,
|
|
#[serde(default)]
|
|
pub vhost_mode: VhostMode,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub fds: Option<Vec<i32>>,
|
|
#[serde(default)]
|
|
pub rate_limiter_config: Option<RateLimiterConfig>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
#[serde(default = "default_netconfig_true")]
|
|
pub offload_tso: bool,
|
|
#[serde(default = "default_netconfig_true")]
|
|
pub offload_ufo: bool,
|
|
#[serde(default = "default_netconfig_true")]
|
|
pub offload_csum: bool,
|
|
}
|
|
|
|
pub fn default_netconfig_true() -> bool {
|
|
true
|
|
}
|
|
|
|
pub fn default_netconfig_tap() -> Option<String> {
|
|
None
|
|
}
|
|
|
|
pub fn default_netconfig_ip() -> Ipv4Addr {
|
|
Ipv4Addr::new(192, 168, 249, 1)
|
|
}
|
|
|
|
pub fn default_netconfig_mask() -> Ipv4Addr {
|
|
Ipv4Addr::new(255, 255, 255, 0)
|
|
}
|
|
|
|
pub fn default_netconfig_mac() -> MacAddr {
|
|
MacAddr::local_random()
|
|
}
|
|
|
|
pub const DEFAULT_NET_NUM_QUEUES: usize = 2;
|
|
|
|
pub fn default_netconfig_num_queues() -> usize {
|
|
DEFAULT_NET_NUM_QUEUES
|
|
}
|
|
|
|
pub const DEFAULT_NET_QUEUE_SIZE: u16 = 256;
|
|
|
|
pub fn default_netconfig_queue_size() -> u16 {
|
|
DEFAULT_NET_QUEUE_SIZE
|
|
}
|
|
|
|
impl Default for NetConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
tap: default_netconfig_tap(),
|
|
ip: default_netconfig_ip(),
|
|
mask: default_netconfig_mask(),
|
|
mac: default_netconfig_mac(),
|
|
host_mac: None,
|
|
mtu: None,
|
|
iommu: false,
|
|
num_queues: default_netconfig_num_queues(),
|
|
queue_size: default_netconfig_queue_size(),
|
|
vhost_user: false,
|
|
vhost_socket: None,
|
|
vhost_mode: VhostMode::Client,
|
|
id: None,
|
|
fds: None,
|
|
rate_limiter_config: None,
|
|
pci_segment: 0,
|
|
offload_tso: true,
|
|
offload_ufo: true,
|
|
offload_csum: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct RngConfig {
|
|
pub src: PathBuf,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
}
|
|
|
|
pub const DEFAULT_RNG_SOURCE: &str = "/dev/urandom";
|
|
|
|
impl Default for RngConfig {
|
|
fn default() -> Self {
|
|
RngConfig {
|
|
src: PathBuf::from(DEFAULT_RNG_SOURCE),
|
|
iommu: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct BalloonConfig {
|
|
pub size: u64,
|
|
/// Option to deflate the balloon in case the guest is out of memory.
|
|
#[serde(default)]
|
|
pub deflate_on_oom: bool,
|
|
/// Option to enable free page reporting from the guest.
|
|
#[serde(default)]
|
|
pub free_page_reporting: bool,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct FsConfig {
|
|
pub tag: String,
|
|
pub socket: PathBuf,
|
|
#[serde(default = "default_fsconfig_num_queues")]
|
|
pub num_queues: usize,
|
|
#[serde(default = "default_fsconfig_queue_size")]
|
|
pub queue_size: u16,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
pub fn default_fsconfig_num_queues() -> usize {
|
|
1
|
|
}
|
|
|
|
pub fn default_fsconfig_queue_size() -> u16 {
|
|
1024
|
|
}
|
|
|
|
impl Default for FsConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
tag: "".to_owned(),
|
|
socket: PathBuf::new(),
|
|
num_queues: default_fsconfig_num_queues(),
|
|
queue_size: default_fsconfig_queue_size(),
|
|
id: None,
|
|
pci_segment: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct PmemConfig {
|
|
pub file: PathBuf,
|
|
#[serde(default)]
|
|
pub size: Option<u64>,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default)]
|
|
pub discard_writes: bool,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub enum ConsoleOutputMode {
|
|
Off,
|
|
Pty,
|
|
Tty,
|
|
File,
|
|
Socket,
|
|
Null,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct ConsoleConfig {
|
|
#[serde(default = "default_consoleconfig_file")]
|
|
pub file: Option<PathBuf>,
|
|
pub mode: ConsoleOutputMode,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
pub socket: Option<PathBuf>,
|
|
}
|
|
|
|
pub fn default_consoleconfig_file() -> Option<PathBuf> {
|
|
None
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct DeviceConfig {
|
|
pub path: PathBuf,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct UserDeviceConfig {
|
|
pub socket: PathBuf,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct VdpaConfig {
|
|
pub path: PathBuf,
|
|
#[serde(default = "default_vdpaconfig_num_queues")]
|
|
pub num_queues: usize,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
pub fn default_vdpaconfig_num_queues() -> usize {
|
|
1
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct VsockConfig {
|
|
pub cid: u64,
|
|
pub socket: PathBuf,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[serde(default)]
|
|
pub id: Option<String>,
|
|
#[serde(default)]
|
|
pub pci_segment: u16,
|
|
}
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct SgxEpcConfig {
|
|
pub id: String,
|
|
#[serde(default)]
|
|
pub size: u64,
|
|
#[serde(default)]
|
|
pub prefault: bool,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct NumaDistance {
|
|
#[serde(default)]
|
|
pub destination: u32,
|
|
#[serde(default)]
|
|
pub distance: u8,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
pub struct NumaConfig {
|
|
#[serde(default)]
|
|
pub guest_numa_id: u32,
|
|
#[serde(default)]
|
|
pub cpus: Option<Vec<u8>>,
|
|
#[serde(default)]
|
|
pub distances: Option<Vec<NumaDistance>>,
|
|
#[serde(default)]
|
|
pub memory_zones: Option<Vec<String>>,
|
|
#[cfg(target_arch = "x86_64")]
|
|
#[serde(default)]
|
|
pub sgx_epc_sections: Option<Vec<String>>,
|
|
#[serde(default)]
|
|
pub pci_segments: Option<Vec<u16>>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
|
pub struct PayloadConfig {
|
|
#[serde(default)]
|
|
pub firmware: Option<PathBuf>,
|
|
#[serde(default)]
|
|
pub kernel: Option<PathBuf>,
|
|
#[serde(default)]
|
|
pub cmdline: Option<String>,
|
|
#[serde(default)]
|
|
pub initramfs: Option<PathBuf>,
|
|
#[cfg(feature = "igvm")]
|
|
#[serde(default)]
|
|
pub igvm: Option<PathBuf>,
|
|
}
|
|
|
|
pub fn default_serial() -> ConsoleConfig {
|
|
ConsoleConfig {
|
|
file: None,
|
|
mode: ConsoleOutputMode::Null,
|
|
iommu: false,
|
|
socket: None,
|
|
}
|
|
}
|
|
|
|
pub fn default_console() -> ConsoleConfig {
|
|
ConsoleConfig {
|
|
file: None,
|
|
mode: ConsoleOutputMode::Tty,
|
|
iommu: false,
|
|
socket: None,
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct TpmConfig {
|
|
pub socket: PathBuf,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
|
|
pub struct VmConfig {
|
|
#[serde(default)]
|
|
pub cpus: CpusConfig,
|
|
#[serde(default)]
|
|
pub memory: MemoryConfig,
|
|
pub payload: Option<PayloadConfig>,
|
|
pub rate_limit_groups: Option<Vec<RateLimiterGroupConfig>>,
|
|
pub disks: Option<Vec<DiskConfig>>,
|
|
pub net: Option<Vec<NetConfig>>,
|
|
#[serde(default)]
|
|
pub rng: RngConfig,
|
|
pub balloon: Option<BalloonConfig>,
|
|
pub fs: Option<Vec<FsConfig>>,
|
|
pub pmem: Option<Vec<PmemConfig>>,
|
|
#[serde(default = "default_serial")]
|
|
pub serial: ConsoleConfig,
|
|
#[serde(default = "default_console")]
|
|
pub console: ConsoleConfig,
|
|
pub devices: Option<Vec<DeviceConfig>>,
|
|
pub user_devices: Option<Vec<UserDeviceConfig>>,
|
|
pub vdpa: Option<Vec<VdpaConfig>>,
|
|
pub vsock: Option<VsockConfig>,
|
|
#[serde(default)]
|
|
pub pvpanic: bool,
|
|
#[serde(default)]
|
|
pub iommu: bool,
|
|
#[cfg(target_arch = "x86_64")]
|
|
pub sgx_epc: Option<Vec<SgxEpcConfig>>,
|
|
pub numa: Option<Vec<NumaConfig>>,
|
|
#[serde(default)]
|
|
pub watchdog: bool,
|
|
#[cfg(feature = "guest_debug")]
|
|
#[serde(default)]
|
|
pub gdb: bool,
|
|
pub platform: Option<PlatformConfig>,
|
|
pub tpm: Option<TpmConfig>,
|
|
// Preserved FDs are the ones that share the same life-time as its holding
|
|
// VmConfig instance, such as FDs for creating TAP devices.
|
|
// Preserved FDs will stay open as long as the holding VmConfig instance is
|
|
// valid, and will be closed when the holding VmConfig instance is destroyed.
|
|
#[serde(skip)]
|
|
pub preserved_fds: Option<Vec<i32>>,
|
|
}
|