vmm: Encompass guest payload configuration in PayloadConfig

Introduce a new top level member of VmConfig called PayloadConfig that
(currently) encompasses the kernel, commandline and initramfs for the
guest to use.

In future this can be extended for firmware use. The existing
"--kernel", "--cmdline" and "initramfs" CLI parameters now fill the
PayloadConfig.

Any config supplied which uses the now deprecated config members have
those members mapped to the new version with a warning.

See: #4445

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-08-10 11:24:31 +01:00
parent 5810e3bee8
commit cef51a9de0
4 changed files with 146 additions and 108 deletions

View File

@ -639,8 +639,8 @@ mod unit_tests {
use crate::{create_app, prepare_default_values}; use crate::{create_app, prepare_default_values};
use std::path::PathBuf; use std::path::PathBuf;
use vmm::config::{ use vmm::config::{
CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, KernelConfig, CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig,
MemoryConfig, RngConfig, VmConfig, VmParams, PayloadConfig, RngConfig, VmConfig, VmParams,
}; };
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig { fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
@ -673,7 +673,7 @@ mod unit_tests {
#[test] #[test]
fn test_valid_vm_config_default() { fn test_valid_vm_config_default() {
let cli = vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"]; let cli = vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"];
let openapi = r#"{ "kernel": {"path": "/path/to/kernel"} }"#; let openapi = r#"{ "payload": {"kernel": "/path/to/kernel"} }"#;
// First we check we get identical VmConfig structures. // First we check we get identical VmConfig structures.
let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true); let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true);
@ -701,13 +701,15 @@ mod unit_tests {
prefault: false, prefault: false,
zones: None, zones: None,
}, },
kernel: Some(KernelConfig { kernel: None,
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None,
cmdline: CmdlineConfig { cmdline: CmdlineConfig {
args: String::from(""), args: String::default(),
}, },
initramfs: None,
payload: Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
..Default::default()
}),
disks: None, disks: None,
net: None, net: None,
rng: RngConfig { rng: RngConfig {
@ -758,7 +760,7 @@ mod unit_tests {
"boot=1", "boot=1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 1} "cpus": {"boot_vcpus": 1, "max_vcpus": 1}
}"#, }"#,
true, true,
@ -772,7 +774,7 @@ mod unit_tests {
"boot=1,max=3", "boot=1,max=3",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 3} "cpus": {"boot_vcpus": 1, "max_vcpus": 3}
}"#, }"#,
true, true,
@ -786,7 +788,7 @@ mod unit_tests {
"boot=2,max=4", "boot=2,max=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 3} "cpus": {"boot_vcpus": 1, "max_vcpus": 3}
}"#, }"#,
false, false,
@ -804,7 +806,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1073741824"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1073741824"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824} "memory": {"size": 1073741824}
}"#, }"#,
true, true,
@ -812,7 +814,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824} "memory": {"size": 1073741824}
}"#, }"#,
true, true,
@ -820,7 +822,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": true} "memory": {"size": 1073741824, "mergeable": true}
}"#, }"#,
true, true,
@ -828,7 +830,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=off"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=off"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": false} "memory": {"size": 1073741824, "mergeable": false}
}"#, }"#,
true, true,
@ -836,7 +838,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": false} "memory": {"size": 1073741824, "mergeable": false}
}"#, }"#,
false, false,
@ -844,7 +846,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824, "hotplug_method": "Acpi", "hotplug_size": 1073741824} "memory": {"size": 1073741824, "hotplug_method": "Acpi", "hotplug_size": 1073741824}
}"#, }"#,
true, true,
@ -852,7 +854,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_method=virtio-mem,hotplug_size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_method=virtio-mem,hotplug_size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory": {"size": 1073741824, "hotplug_method": "VirtioMem", "hotplug_size": 1073741824} "memory": {"size": 1073741824, "hotplug_method": "VirtioMem", "hotplug_size": 1073741824}
}"#, }"#,
true, true,
@ -869,7 +871,7 @@ mod unit_tests {
vec![( vec![(
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"} "payload": {"kernel": "/path/to/kernel"}
}"#, }"#,
true, true,
)] )]
@ -890,8 +892,7 @@ mod unit_tests {
"arg1=foo arg2=bar", "arg1=foo arg2=bar",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel", "cmdline": "arg1=foo arg2=bar"}
"cmdline": {"args": "arg1=foo arg2=bar"}
}"#, }"#,
true, true,
)] )]
@ -914,7 +915,7 @@ mod unit_tests {
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"disks": [ "disks": [
{"path": "/path/to/disk/1"}, {"path": "/path/to/disk/1"},
{"path": "/path/to/disk/2"} {"path": "/path/to/disk/2"}
@ -932,7 +933,7 @@ mod unit_tests {
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"disks": [ "disks": [
{"path": "/path/to/disk/1"} {"path": "/path/to/disk/1"}
] ]
@ -950,7 +951,7 @@ mod unit_tests {
"vhost_user=true,socket=/tmp/sock1", "vhost_user=true,socket=/tmp/sock1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"disks": [ "disks": [
{"vhost_user":true, "vhost_socket":"/tmp/sock1"} {"vhost_user":true, "vhost_socket":"/tmp/sock1"}
@ -969,7 +970,7 @@ mod unit_tests {
"vhost_user=true,socket=/tmp/sock1", "vhost_user=true,socket=/tmp/sock1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"disks": [ "disks": [
{"vhost_user":true, "vhost_socket":"/tmp/sock1"} {"vhost_user":true, "vhost_socket":"/tmp/sock1"}
@ -993,7 +994,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac="], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac="],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [] "net": []
}"#, }"#,
false, false,
@ -1001,7 +1002,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd"}
] ]
@ -1015,7 +1016,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0"}
] ]
@ -1029,7 +1030,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4"}
] ]
@ -1043,7 +1044,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
@ -1058,7 +1059,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"cpus": {"boot_vcpus": 2, "max_vcpus": 2}, "cpus": {"boot_vcpus": 2, "max_vcpus": 2},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4}
@ -1074,7 +1075,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"cpus": {"boot_vcpus": 2, "max_vcpus": 2}, "cpus": {"boot_vcpus": 2, "max_vcpus": 2},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128}
@ -1089,7 +1090,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
@ -1103,7 +1104,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256}
] ]
@ -1118,7 +1119,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
] ]
@ -1133,7 +1134,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
], ],
@ -1148,7 +1149,7 @@ mod unit_tests {
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false}
] ]
@ -1158,7 +1159,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "shared=true", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,vhost_user=true,socket=/tmp/sock"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "shared=true", "--net", "mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,vhost_user=true,socket=/tmp/sock"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "vhost_user": true, "vhost_socket": "/tmp/sock"} {"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "vhost_user": true, "vhost_socket": "/tmp/sock"}
@ -1184,7 +1185,7 @@ mod unit_tests {
"src=/path/to/entropy/source", "src=/path/to/entropy/source",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"rng": {"src": "/path/to/entropy/source"} "rng": {"src": "/path/to/entropy/source"}
}"#, }"#,
true, true,
@ -1207,7 +1208,7 @@ mod unit_tests {
"tag=virtiofs2,socket=/path/to/sock2", "tag=virtiofs2,socket=/path/to/sock2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"fs": [ "fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1"}, {"tag": "virtiofs1", "socket": "/path/to/sock1"},
@ -1225,7 +1226,7 @@ mod unit_tests {
"tag=virtiofs2,socket=/path/to/sock2", "tag=virtiofs2,socket=/path/to/sock2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"fs": [ "fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1"} {"tag": "virtiofs1", "socket": "/path/to/sock1"}
@ -1241,7 +1242,7 @@ mod unit_tests {
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4", "tag=virtiofs1,socket=/path/to/sock1,num_queues=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4}, "cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [ "fs": [
@ -1258,7 +1259,7 @@ mod unit_tests {
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128" "tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 }, "memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4}, "cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [ "fs": [
@ -1287,7 +1288,7 @@ mod unit_tests {
"file=/path/to/img/2,size=2G", "file=/path/to/img/2,size=2G",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824}, {"file": "/path/to/img/1", "size": 1073741824},
{"file": "/path/to/img/2", "size": 2147483648} {"file": "/path/to/img/2", "size": 2147483648}
@ -1305,7 +1306,7 @@ mod unit_tests {
"file=/path/to/img/1,size=1G,iommu=on", "file=/path/to/img/1,size=1G,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "iommu": true} {"file": "/path/to/img/1", "size": 1073741824, "iommu": true}
], ],
@ -1323,7 +1324,7 @@ mod unit_tests {
"file=/path/to/img/1,size=1G,iommu=on", "file=/path/to/img/1,size=1G,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "iommu": true} {"file": "/path/to/img/1", "size": 1073741824, "iommu": true}
] ]
@ -1343,7 +1344,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"serial": {"mode": "Null"}, "serial": {"mode": "Null"},
"console": {"mode": "Tty"} "console": {"mode": "Tty"}
}"#, }"#,
@ -1360,7 +1361,7 @@ mod unit_tests {
"tty", "tty",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"} "payload": {"kernel": "/path/to/kernel"}
}"#, }"#,
true, true,
), ),
@ -1375,7 +1376,7 @@ mod unit_tests {
"off", "off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"serial": {"mode": "Tty"}, "serial": {"mode": "Tty"},
"console": {"mode": "Off"} "console": {"mode": "Off"}
}"#, }"#,
@ -1394,7 +1395,7 @@ mod unit_tests {
( (
vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"serial": {"mode": "Null"}, "serial": {"mode": "Null"},
"console": {"mode": "Tty"} "console": {"mode": "Tty"}
}"#, }"#,
@ -1411,7 +1412,7 @@ mod unit_tests {
"tty", "tty",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"} "payload": {"kernel": "/path/to/kernel"}
}"#, }"#,
true, true,
), ),
@ -1426,7 +1427,7 @@ mod unit_tests {
"pty", "pty",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"serial": {"mode": "Pty"}, "serial": {"mode": "Pty"},
"console": {"mode": "Pty"} "console": {"mode": "Pty"}
}"#, }"#,
@ -1453,7 +1454,7 @@ mod unit_tests {
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device/1"}, {"path": "/path/to/device/1"},
{"path": "/path/to/device/2"} {"path": "/path/to/device/2"}
@ -1471,7 +1472,7 @@ mod unit_tests {
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device/1"} {"path": "/path/to/device/1"}
] ]
@ -1487,7 +1488,7 @@ mod unit_tests {
"path=/path/to/device,iommu=on", "path=/path/to/device,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": true} {"path": "/path/to/device", "iommu": true}
], ],
@ -1504,7 +1505,7 @@ mod unit_tests {
"path=/path/to/device,iommu=on", "path=/path/to/device,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": true} {"path": "/path/to/device", "iommu": true}
] ]
@ -1520,7 +1521,7 @@ mod unit_tests {
"path=/path/to/device,iommu=off", "path=/path/to/device,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": false} {"path": "/path/to/device", "iommu": false}
] ]
@ -1547,7 +1548,7 @@ mod unit_tests {
"path=/path/to/device/2,num_queues=2", "path=/path/to/device/2,num_queues=2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vdpa": [ "vdpa": [
{"path": "/path/to/device/1", "num_queues": 1}, {"path": "/path/to/device/1", "num_queues": 1},
{"path": "/path/to/device/2", "num_queues": 2} {"path": "/path/to/device/2", "num_queues": 2}
@ -1565,7 +1566,7 @@ mod unit_tests {
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vdpa": [ "vdpa": [
{"path": "/path/to/device/1"} {"path": "/path/to/device/1"}
] ]
@ -1591,7 +1592,7 @@ mod unit_tests {
"cid=123,socket=/path/to/sock/1", "cid=123,socket=/path/to/sock/1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vsock": {"cid": 123, "socket": "/path/to/sock/1"} "vsock": {"cid": 123, "socket": "/path/to/sock/1"}
}"#, }"#,
true, true,
@ -1605,7 +1606,7 @@ mod unit_tests {
"cid=124,socket=/path/to/sock/1", "cid=124,socket=/path/to/sock/1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vsock": {"cid": 123, "socket": "/path/to/sock/1"} "vsock": {"cid": 123, "socket": "/path/to/sock/1"}
}"#, }"#,
false, false,
@ -1620,7 +1621,7 @@ mod unit_tests {
"cid=123,socket=/path/to/sock/1,iommu=on", "cid=123,socket=/path/to/sock/1,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true}, "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true},
"iommu": true "iommu": true
}"#, }"#,
@ -1636,7 +1637,7 @@ mod unit_tests {
"cid=123,socket=/path/to/sock/1,iommu=on", "cid=123,socket=/path/to/sock/1,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true} "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true}
}"#, }"#,
false, false,
@ -1650,7 +1651,7 @@ mod unit_tests {
"cid=123,socket=/path/to/sock/1,iommu=off", "cid=123,socket=/path/to/sock/1,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"}, "payload": {"kernel": "/path/to/kernel"},
"vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": false} "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": false}
}"#, }"#,
true, true,

View File

@ -2248,6 +2248,16 @@ impl RestoreConfig {
} }
} }
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct PayloadConfig {
#[serde(default)]
pub kernel: Option<PathBuf>,
#[serde(default)]
pub cmdline: Option<String>,
#[serde(default)]
pub initramfs: Option<PathBuf>,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct VmConfig { pub struct VmConfig {
#[serde(default)] #[serde(default)]
@ -2259,6 +2269,8 @@ pub struct VmConfig {
pub initramfs: Option<InitramfsConfig>, pub initramfs: Option<InitramfsConfig>,
#[serde(default)] #[serde(default)]
pub cmdline: CmdlineConfig, pub cmdline: CmdlineConfig,
#[serde(default)]
pub payload: Option<PayloadConfig>,
pub disks: Option<Vec<DiskConfig>>, pub disks: Option<Vec<DiskConfig>>,
pub net: Option<Vec<NetConfig>>, pub net: Option<Vec<NetConfig>>,
#[serde(default)] #[serde(default)]
@ -2312,13 +2324,28 @@ impl VmConfig {
pub fn validate(&mut self) -> ValidationResult<BTreeSet<String>> { pub fn validate(&mut self) -> ValidationResult<BTreeSet<String>> {
let mut id_list = BTreeSet::new(); let mut id_list = BTreeSet::new();
if self.kernel.is_some() {
warn!("The \"VmConfig\" members \"kernel\", \"cmdline\" and \"initramfs\" are deprecated. Use \"payload\" member instead.");
self.payload = Some(PayloadConfig {
kernel: self.kernel.take().map(|k| k.path),
cmdline: if self.cmdline.args.is_empty() {
None
} else {
Some(self.cmdline.args.drain(..).collect())
},
initramfs: self.initramfs.take().map(|i| i.path),
})
}
#[cfg(not(feature = "tdx"))] #[cfg(not(feature = "tdx"))]
self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?; self.payload
.as_ref()
.ok_or(ValidationError::KernelMissing)?;
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
{ {
let tdx_enabled = self.tdx.is_some(); let tdx_enabled = self.tdx.is_some();
if !tdx_enabled && self.kernel.is_none() { if !tdx_enabled && self.payload.is_none() {
return Err(ValidationError::KernelMissing); return Err(ValidationError::KernelMissing);
} }
if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) { if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) {
@ -2644,19 +2671,15 @@ impl VmConfig {
numa = Some(numa_config_list); numa = Some(numa_config_list);
} }
let mut kernel: Option<KernelConfig> = None; let payload = if vm_params.kernel.is_some() {
if let Some(k) = vm_params.kernel { Some(PayloadConfig {
kernel = Some(KernelConfig { kernel: vm_params.kernel.map(PathBuf::from),
path: PathBuf::from(k), initramfs: vm_params.initramfs.map(PathBuf::from),
}); cmdline: vm_params.cmdline.map(|s| s.to_string()),
} })
} else {
let mut initramfs: Option<InitramfsConfig> = None; None
if let Some(k) = vm_params.initramfs { };
initramfs = Some(InitramfsConfig {
path: PathBuf::from(k),
});
}
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
let tdx = vm_params.tdx.map(TdxConfig::parse).transpose()?; let tdx = vm_params.tdx.map(TdxConfig::parse).transpose()?;
@ -2667,9 +2690,10 @@ impl VmConfig {
let mut config = VmConfig { let mut config = VmConfig {
cpus: CpusConfig::parse(vm_params.cpus)?, cpus: CpusConfig::parse(vm_params.cpus)?,
memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?, memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?,
kernel, kernel: None,
initramfs, initramfs: None,
cmdline: CmdlineConfig::parse(vm_params.cmdline)?, cmdline: CmdlineConfig::default(),
payload,
disks, disks,
net, net,
rng, rng,
@ -3257,13 +3281,15 @@ mod tests {
prefault: false, prefault: false,
zones: None, zones: None,
}, },
kernel: Some(KernelConfig { kernel: None,
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None,
cmdline: CmdlineConfig { cmdline: CmdlineConfig {
args: String::from(""), args: String::default(),
}, },
initramfs: None,
payload: Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
..Default::default()
}),
disks: None, disks: None,
net: None, net: None,
rng: RngConfig { rng: RngConfig {
@ -3310,7 +3336,7 @@ mod tests {
); );
let mut invalid_config = valid_config.clone(); let mut invalid_config = valid_config.clone();
invalid_config.kernel = None; invalid_config.payload = None;
assert_eq!( assert_eq!(
invalid_config.validate(), invalid_config.validate(),
Err(ValidationError::KernelMissing) Err(ValidationError::KernelMissing)

View File

@ -1968,8 +1968,8 @@ const DEVICE_MANAGER_SNAPSHOT_ID: &str = "device-manager";
mod unit_tests { mod unit_tests {
use super::*; use super::*;
use config::{ use config::{
CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, HotplugMethod, KernelConfig, CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, HotplugMethod, MemoryConfig,
MemoryConfig, RngConfig, VmConfig, PayloadConfig, RngConfig, VmConfig,
}; };
fn create_dummy_vmm() -> Vmm { fn create_dummy_vmm() -> Vmm {
@ -2010,13 +2010,15 @@ mod unit_tests {
prefault: false, prefault: false,
zones: None, zones: None,
}, },
kernel: Some(KernelConfig { kernel: None,
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None,
cmdline: CmdlineConfig { cmdline: CmdlineConfig {
args: String::from(""), args: String::default(),
}, },
initramfs: None,
payload: Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
..Default::default()
}),
disks: None, disks: None,
net: None, net: None,
rng: RngConfig { rng: RngConfig {

View File

@ -494,12 +494,19 @@ impl Vm {
restoring: bool, restoring: bool,
timestamp: Instant, timestamp: Instant,
) -> Result<Self> { ) -> Result<Self> {
let boot_id_list = config
.lock()
.unwrap()
.validate()
.map_err(Error::ConfigValidation)?;
let kernel = config let kernel = config
.lock() .lock()
.unwrap() .unwrap()
.kernel .payload
.as_ref() .as_ref()
.map(|k| File::open(&k.path)) .map(|p| p.kernel.as_ref().map(File::open))
.unwrap_or_default()
.transpose() .transpose()
.map_err(Error::KernelFile)?; .map_err(Error::KernelFile)?;
@ -510,12 +517,6 @@ impl Vm {
None None
}; };
let boot_id_list = config
.lock()
.unwrap()
.validate()
.map_err(Error::ConfigValidation)?;
info!("Booting VM from config: {:?}", &config); info!("Booting VM from config: {:?}", &config);
// Create NUMA nodes based on NumaConfig. // Create NUMA nodes based on NumaConfig.
@ -593,9 +594,10 @@ impl Vm {
let initramfs = config let initramfs = config
.lock() .lock()
.unwrap() .unwrap()
.initramfs .payload
.as_ref() .as_ref()
.map(|i| File::open(&i.path)) .map(|p| p.initramfs.as_ref().map(File::open))
.unwrap_or_default()
.transpose() .transpose()
.map_err(Error::InitramfsFile)?; .map_err(Error::InitramfsFile)?;
@ -932,9 +934,16 @@ impl Vm {
#[cfg(target_arch = "aarch64")] device_manager: &Arc<Mutex<DeviceManager>>, #[cfg(target_arch = "aarch64")] device_manager: &Arc<Mutex<DeviceManager>>,
) -> Result<Cmdline> { ) -> Result<Cmdline> {
let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE); let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE);
cmdline if let Some(s) = config
.insert_str(&config.lock().unwrap().cmdline.args) .lock()
.map_err(Error::CmdLineInsertStr)?; .unwrap()
.payload
.as_ref()
.map(|p| p.cmdline.as_ref())
.unwrap_or_default()
{
cmdline.insert_str(s).map_err(Error::CmdLineInsertStr)?;
}
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
for entry in device_manager.lock().unwrap().cmdline_additions() { for entry in device_manager.lock().unwrap().cmdline_additions() {