diff --git a/vmm/src/config.rs b/vmm/src/config.rs index b7b18ee57..4381b599c 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 // +pub use crate::vm_config::*; use clap::ArgMatches; -use net_util::MacAddr; use option_parser::{ ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, Tuple, }; @@ -12,7 +12,6 @@ use serde::{Deserialize, Serialize}; use std::collections::{BTreeSet, HashMap}; use std::convert::From; use std::fmt; -use std::net::Ipv4Addr; use std::path::PathBuf; use std::result; use std::str::FromStr; @@ -22,18 +21,8 @@ use virtio_devices::{RateLimiterConfig, TokenBucketConfig}; pub const DEFAULT_VCPUS: u8 = 1; pub const DEFAULT_MEMORY_MB: u64 = 512; -// 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 const DEFAULT_RNG_SOURCE: &str = "/dev/urandom"; -pub const DEFAULT_NUM_QUEUES_VUNET: usize = 2; -pub const DEFAULT_QUEUE_SIZE_VUNET: u16 = 256; -pub const DEFAULT_NUM_QUEUES_VUBLK: usize = 1; -pub const DEFAULT_QUEUE_SIZE_VUBLK: u16 = 128; -pub const DEFAULT_NUM_PCI_SEGMENTS: u16 = 1; const MAX_NUM_PCI_SEGMENTS: u16 = 16; /// Errors associated with VM configuration parameters. @@ -464,12 +453,6 @@ impl<'a> VmParams<'a> { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub enum HotplugMethod { - Acpi, - VirtioMem, -} - impl Default for HotplugMethod { fn default() -> Self { HotplugMethod::Acpi @@ -493,31 +476,10 @@ impl FromStr for HotplugMethod { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct CpuAffinity { - pub vcpu: u8, - pub host_cpus: Vec, -} - -#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] -pub struct CpuFeatures { - #[cfg(target_arch = "x86_64")] - #[serde(default)] - pub amx: bool, -} - pub enum CpuTopologyParseError { InvalidValue(String), } -#[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, -} - impl FromStr for CpuTopology { type Err = CpuTopologyParseError; @@ -547,26 +509,6 @@ impl FromStr for CpuTopology { } } -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, - #[serde(default)] - pub kvm_hyperv: bool, - #[serde(default = "default_cpuconfig_max_phys_bits")] - pub max_phys_bits: u8, - #[serde(default)] - pub affinity: Option>, - #[serde(default)] - pub features: CpuFeatures, -} - impl CpusConfig { pub fn parse(cpus: &str) -> Result { let mut parser = OptionParser::new(); @@ -657,27 +599,6 @@ impl Default for CpusConfig { } } -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>, - #[serde(default)] - pub serial_number: Option, - #[serde(default)] - pub uuid: Option, - #[serde(default)] - pub oem_strings: Option>, - #[cfg(feature = "tdx")] - #[serde(default)] - pub tdx: bool, -} - impl PlatformConfig { pub fn parse(platform: &str) -> Result { let mut parser = OptionParser::new(); @@ -757,51 +678,6 @@ impl Default for PlatformConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct MemoryZoneConfig { - pub id: String, - pub size: u64, - #[serde(default)] - pub file: Option, - #[serde(default)] - pub shared: bool, - #[serde(default)] - pub hugepages: bool, - #[serde(default)] - pub hugepage_size: Option, - #[serde(default)] - pub host_numa_node: Option, - #[serde(default)] - pub hotplug_size: Option, - #[serde(default)] - pub hotplugged_size: Option, - #[serde(default)] - pub prefault: bool, -} - -#[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, - #[serde(default)] - pub hotplugged_size: Option, - #[serde(default)] - pub shared: bool, - #[serde(default)] - pub hugepages: bool, - #[serde(default)] - pub hugepage_size: Option, - #[serde(default)] - pub prefault: bool, - #[serde(default)] - pub zones: Option>, -} - impl MemoryConfig { pub fn parse(memory: &str, memory_zones: Option>) -> Result { let mut parser = OptionParser::new(); @@ -984,21 +860,6 @@ impl Default for MemoryConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct KernelConfig { - pub path: PathBuf, -} - -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct InitramfsConfig { - pub path: PathBuf, -} - -#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] -pub struct CmdlineConfig { - pub args: String, -} - impl CmdlineConfig { pub fn parse(cmdline: Option<&str>) -> Result { let args = cmdline @@ -1009,41 +870,6 @@ impl CmdlineConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct DiskConfig { - pub path: Option, - #[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, - #[serde(default)] - pub rate_limiter_config: Option, - #[serde(default)] - pub id: Option, - // For testing use only. Not exposed in API. - #[serde(default)] - pub disable_io_uring: bool, - #[serde(default)] - pub pci_segment: u16, -} - -fn default_diskconfig_num_queues() -> usize { - DEFAULT_NUM_QUEUES_VUBLK -} - -fn default_diskconfig_queue_size() -> u16 { - DEFAULT_QUEUE_SIZE_VUBLK -} - impl Default for DiskConfig { fn default() -> Self { Self { @@ -1226,12 +1052,6 @@ impl DiskConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub enum VhostMode { - Client, - Server, -} - impl Default for VhostMode { fn default() -> Self { VhostMode::Client @@ -1255,65 +1075,6 @@ impl FromStr for VhostMode { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct NetConfig { - #[serde(default = "default_netconfig_tap")] - pub tap: Option, - #[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, - #[serde(default)] - pub mtu: Option, - #[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, - #[serde(default)] - pub vhost_mode: VhostMode, - #[serde(default)] - pub id: Option, - #[serde(default)] - pub fds: Option>, - #[serde(default)] - pub rate_limiter_config: Option, - #[serde(default)] - pub pci_segment: u16, -} - -fn default_netconfig_tap() -> Option { - None -} - -fn default_netconfig_ip() -> Ipv4Addr { - Ipv4Addr::new(192, 168, 249, 1) -} - -fn default_netconfig_mask() -> Ipv4Addr { - Ipv4Addr::new(255, 255, 255, 0) -} - -fn default_netconfig_mac() -> MacAddr { - MacAddr::local_random() -} - -fn default_netconfig_num_queues() -> usize { - DEFAULT_NUM_QUEUES_VUNET -} - -fn default_netconfig_queue_size() -> u16 { - DEFAULT_QUEUE_SIZE_VUNET -} - impl Default for NetConfig { fn default() -> Self { Self { @@ -1538,13 +1299,6 @@ impl NetConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct RngConfig { - pub src: PathBuf, - #[serde(default)] - pub iommu: bool, -} - impl RngConfig { pub fn parse(rng: &str) -> Result { let mut parser = OptionParser::new(); @@ -1575,17 +1329,6 @@ impl Default for RngConfig { } } -#[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, -} - impl BalloonConfig { pub const SYNTAX: &'static str = "Balloon parameters \"size=,deflate_on_oom=on|off,\ @@ -1624,28 +1367,6 @@ impl BalloonConfig { } } -#[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, - #[serde(default)] - pub pci_segment: u16, -} - -fn default_fsconfig_num_queues() -> usize { - 1 -} - -fn default_fsconfig_queue_size() -> u16 { - 1024 -} - impl Default for FsConfig { fn default() -> Self { Self { @@ -1727,21 +1448,6 @@ impl FsConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] -pub struct PmemConfig { - pub file: PathBuf, - #[serde(default)] - pub size: Option, - #[serde(default)] - pub iommu: bool, - #[serde(default)] - pub discard_writes: bool, - #[serde(default)] - pub id: Option, - #[serde(default)] - pub pci_segment: u16, -} - impl PmemConfig { pub const SYNTAX: &'static str = "Persistent memory parameters \ \"file=,size=,iommu=on|off,\ @@ -1805,28 +1511,6 @@ impl PmemConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub enum ConsoleOutputMode { - Off, - Pty, - Tty, - File, - Null, -} - -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct ConsoleConfig { - #[serde(default = "default_consoleconfig_file")] - pub file: Option, - pub mode: ConsoleOutputMode, - #[serde(default)] - pub iommu: bool, -} - -fn default_consoleconfig_file() -> Option { - None -} - impl ConsoleConfig { pub fn parse(console: &str) -> Result { let mut parser = OptionParser::new(); @@ -1884,17 +1568,6 @@ impl ConsoleConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] -pub struct DeviceConfig { - pub path: PathBuf, - #[serde(default)] - pub iommu: bool, - #[serde(default)] - pub id: Option, - #[serde(default)] - pub pci_segment: u16, -} - impl DeviceConfig { pub const SYNTAX: &'static str = "Direct device assignment parameters \"path=,iommu=on|off,id=,pci_segment=\""; @@ -1943,15 +1616,6 @@ impl DeviceConfig { } } -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] -pub struct UserDeviceConfig { - pub socket: PathBuf, - #[serde(default)] - pub id: Option, - #[serde(default)] - pub pci_segment: u16, -} - impl UserDeviceConfig { pub const SYNTAX: &'static str = "Userspace device socket=,id=,pci_segment=\""; @@ -1996,23 +1660,6 @@ impl UserDeviceConfig { } } -#[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, - #[serde(default)] - pub pci_segment: u16, -} - -fn default_vdpaconfig_num_queues() -> usize { - 1 -} - impl VdpaConfig { pub const SYNTAX: &'static str = "vDPA device \ \"path=,num_queues=,iommu=on|off,\ @@ -2072,18 +1719,6 @@ impl VdpaConfig { } } -#[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, - #[serde(default)] - pub pci_segment: u16, -} - impl VsockConfig { pub const SYNTAX: &'static str = "Virtio VSOCK parameters \ \"cid=,socket=,iommu=on|off,id=,pci_segment=\""; @@ -2142,16 +1777,6 @@ impl VsockConfig { } } -#[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, -} - #[cfg(target_arch = "x86_64")] impl SgxEpcConfig { pub const SYNTAX: &'static str = "SGX EPC parameters \ @@ -2177,29 +1802,6 @@ impl SgxEpcConfig { } } -#[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>, - #[serde(default)] - pub distances: Option>, - #[serde(default)] - pub memory_zones: Option>, - #[cfg(target_arch = "x86_64")] - #[serde(default)] - pub sgx_epc_sections: Option>, -} - impl NumaConfig { pub const SYNTAX: &'static str = "Settings related to a given NUMA node \ \"guest_numa_id=,cpus=,distances=,\ @@ -2288,58 +1890,6 @@ impl RestoreConfig { } } -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] -pub struct PayloadConfig { - #[serde(default)] - pub firmware: Option, - #[serde(default)] - pub kernel: Option, - #[serde(default)] - pub cmdline: Option, - #[serde(default)] - pub initramfs: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -pub struct VmConfig { - #[serde(default)] - pub cpus: CpusConfig, - #[serde(default)] - pub memory: MemoryConfig, - pub kernel: Option, - #[serde(default)] - pub initramfs: Option, - #[serde(default)] - pub cmdline: CmdlineConfig, - #[serde(default)] - pub payload: Option, - pub disks: Option>, - pub net: Option>, - #[serde(default)] - pub rng: RngConfig, - pub balloon: Option, - pub fs: Option>, - pub pmem: Option>, - #[serde(default = "ConsoleConfig::default_serial")] - pub serial: ConsoleConfig, - #[serde(default = "ConsoleConfig::default_console")] - pub console: ConsoleConfig, - pub devices: Option>, - pub user_devices: Option>, - pub vdpa: Option>, - pub vsock: Option, - #[serde(default)] - pub iommu: bool, - #[cfg(target_arch = "x86_64")] - pub sgx_epc: Option>, - pub numa: Option>, - #[serde(default)] - pub watchdog: bool, - #[cfg(feature = "guest_debug")] - pub gdb: bool, - pub platform: Option, -} - impl VmConfig { fn validate_identifier( id_list: &mut BTreeSet, @@ -2767,6 +2317,7 @@ impl VmConfig { #[cfg(test)] mod tests { use super::*; + use net_util::MacAddr; #[test] fn test_cpu_parsing() -> Result<()> { diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 408c74f17..94c8cddab 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -74,6 +74,7 @@ pub mod seccomp_filters; mod serial_manager; mod sigwinch_listener; pub mod vm; +pub mod vm_config; type GuestMemoryMmap = vm_memory::GuestMemoryMmap; type GuestRegionMmap = vm_memory::GuestRegionMmap; diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs new file mode 100644 index 000000000..9cb1c8e3d --- /dev/null +++ b/vmm/src/vm_config.rs @@ -0,0 +1,458 @@ +// 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, +} + +#[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, + #[serde(default)] + pub kvm_hyperv: bool, + #[serde(default = "default_cpuconfig_max_phys_bits")] + pub max_phys_bits: u8, + #[serde(default)] + pub affinity: Option>, + #[serde(default)] + pub features: CpuFeatures, +} + +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>, + #[serde(default)] + pub serial_number: Option, + #[serde(default)] + pub uuid: Option, + #[serde(default)] + pub oem_strings: Option>, + #[cfg(feature = "tdx")] + #[serde(default)] + pub tdx: bool, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct MemoryZoneConfig { + pub id: String, + pub size: u64, + #[serde(default)] + pub file: Option, + #[serde(default)] + pub shared: bool, + #[serde(default)] + pub hugepages: bool, + #[serde(default)] + pub hugepage_size: Option, + #[serde(default)] + pub host_numa_node: Option, + #[serde(default)] + pub hotplug_size: Option, + #[serde(default)] + pub hotplugged_size: Option, + #[serde(default)] + pub prefault: bool, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub enum HotplugMethod { + Acpi, + VirtioMem, +} + +#[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, + #[serde(default)] + pub hotplugged_size: Option, + #[serde(default)] + pub shared: bool, + #[serde(default)] + pub hugepages: bool, + #[serde(default)] + pub hugepage_size: Option, + #[serde(default)] + pub prefault: bool, + #[serde(default)] + pub zones: Option>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub enum VhostMode { + Client, + Server, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct KernelConfig { + pub path: PathBuf, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct InitramfsConfig { + pub path: PathBuf, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] +pub struct CmdlineConfig { + pub args: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct DiskConfig { + pub path: Option, + #[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, + #[serde(default)] + pub rate_limiter_config: Option, + #[serde(default)] + pub id: Option, + // For testing use only. Not exposed in API. + #[serde(default)] + pub disable_io_uring: bool, + #[serde(default)] + pub pci_segment: u16, +} + +pub const DEFAULT_NUM_QUEUES_VUBLK: usize = 1; + +pub fn default_diskconfig_num_queues() -> usize { + DEFAULT_NUM_QUEUES_VUBLK +} + +pub const DEFAULT_QUEUE_SIZE_VUBLK: u16 = 128; +pub fn default_diskconfig_queue_size() -> u16 { + DEFAULT_QUEUE_SIZE_VUBLK +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct NetConfig { + #[serde(default = "default_netconfig_tap")] + pub tap: Option, + #[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, + #[serde(default)] + pub mtu: Option, + #[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, + #[serde(default)] + pub vhost_mode: VhostMode, + #[serde(default)] + pub id: Option, + #[serde(default)] + pub fds: Option>, + #[serde(default)] + pub rate_limiter_config: Option, + #[serde(default)] + pub pci_segment: u16, +} + +pub fn default_netconfig_tap() -> Option { + 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_NUM_QUEUES_VUNET: usize = 2; +pub fn default_netconfig_num_queues() -> usize { + DEFAULT_NUM_QUEUES_VUNET +} + +pub const DEFAULT_QUEUE_SIZE_VUNET: u16 = 256; +pub fn default_netconfig_queue_size() -> u16 { + DEFAULT_QUEUE_SIZE_VUNET +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct RngConfig { + pub src: PathBuf, + #[serde(default)] + pub iommu: bool, +} + +#[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, + #[serde(default)] + pub pci_segment: u16, +} + +pub fn default_fsconfig_num_queues() -> usize { + 1 +} + +pub fn default_fsconfig_queue_size() -> u16 { + 1024 +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] +pub struct PmemConfig { + pub file: PathBuf, + #[serde(default)] + pub size: Option, + #[serde(default)] + pub iommu: bool, + #[serde(default)] + pub discard_writes: bool, + #[serde(default)] + pub id: Option, + #[serde(default)] + pub pci_segment: u16, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub enum ConsoleOutputMode { + Off, + Pty, + Tty, + File, + Null, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct ConsoleConfig { + #[serde(default = "default_consoleconfig_file")] + pub file: Option, + pub mode: ConsoleOutputMode, + #[serde(default)] + pub iommu: bool, +} + +pub fn default_consoleconfig_file() -> Option { + 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, + #[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, + #[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, + #[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, + #[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>, + #[serde(default)] + pub distances: Option>, + #[serde(default)] + pub memory_zones: Option>, + #[cfg(target_arch = "x86_64")] + #[serde(default)] + pub sgx_epc_sections: Option>, +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +pub struct PayloadConfig { + #[serde(default)] + pub firmware: Option, + #[serde(default)] + pub kernel: Option, + #[serde(default)] + pub cmdline: Option, + #[serde(default)] + pub initramfs: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct VmConfig { + #[serde(default)] + pub cpus: CpusConfig, + #[serde(default)] + pub memory: MemoryConfig, + pub kernel: Option, + #[serde(default)] + pub initramfs: Option, + #[serde(default)] + pub cmdline: CmdlineConfig, + #[serde(default)] + pub payload: Option, + pub disks: Option>, + pub net: Option>, + #[serde(default)] + pub rng: RngConfig, + pub balloon: Option, + pub fs: Option>, + pub pmem: Option>, + #[serde(default = "ConsoleConfig::default_serial")] + pub serial: ConsoleConfig, + #[serde(default = "ConsoleConfig::default_console")] + pub console: ConsoleConfig, + pub devices: Option>, + pub user_devices: Option>, + pub vdpa: Option>, + pub vsock: Option, + #[serde(default)] + pub iommu: bool, + #[cfg(target_arch = "x86_64")] + pub sgx_epc: Option>, + pub numa: Option>, + #[serde(default)] + pub watchdog: bool, + #[cfg(feature = "guest_debug")] + pub gdb: bool, + pub platform: Option, +}