From cef51a9de08c2046079c26bc01e86f0d8560a478 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 10 Aug 2022 11:24:31 +0100 Subject: [PATCH] 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 --- src/main.rs | 129 +++++++++++++++++++++++----------------------- vmm/src/config.rs | 74 +++++++++++++++++--------- vmm/src/lib.rs | 16 +++--- vmm/src/vm.rs | 35 ++++++++----- 4 files changed, 146 insertions(+), 108 deletions(-) diff --git a/src/main.rs b/src/main.rs index 88e15c154..ab9d13e2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -639,8 +639,8 @@ mod unit_tests { use crate::{create_app, prepare_default_values}; use std::path::PathBuf; use vmm::config::{ - CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, KernelConfig, - MemoryConfig, RngConfig, VmConfig, VmParams, + CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpuFeatures, CpusConfig, MemoryConfig, + PayloadConfig, RngConfig, VmConfig, VmParams, }; fn get_vm_config_from_vec(args: &[&str]) -> VmConfig { @@ -673,7 +673,7 @@ mod unit_tests { #[test] fn test_valid_vm_config_default() { 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. let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true); @@ -701,13 +701,15 @@ mod unit_tests { prefault: false, zones: None, }, - kernel: Some(KernelConfig { - path: PathBuf::from("/path/to/kernel"), - }), - initramfs: None, + kernel: None, cmdline: CmdlineConfig { - args: String::from(""), + args: String::default(), }, + initramfs: None, + payload: Some(PayloadConfig { + kernel: Some(PathBuf::from("/path/to/kernel")), + ..Default::default() + }), disks: None, net: None, rng: RngConfig { @@ -758,7 +760,7 @@ mod unit_tests { "boot=1", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "cpus": {"boot_vcpus": 1, "max_vcpus": 1} }"#, true, @@ -772,7 +774,7 @@ mod unit_tests { "boot=1,max=3", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "cpus": {"boot_vcpus": 1, "max_vcpus": 3} }"#, true, @@ -786,7 +788,7 @@ mod unit_tests { "boot=2,max=4", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "cpus": {"boot_vcpus": 1, "max_vcpus": 3} }"#, false, @@ -804,7 +806,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1073741824"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824} }"#, true, @@ -812,7 +814,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824} }"#, true, @@ -820,7 +822,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824, "mergeable": true} }"#, true, @@ -828,7 +830,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=off"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824, "mergeable": false} }"#, true, @@ -836,7 +838,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824, "mergeable": false} }"#, false, @@ -844,7 +846,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_size=1G"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824, "hotplug_method": "Acpi", "hotplug_size": 1073741824} }"#, 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"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory": {"size": 1073741824, "hotplug_method": "VirtioMem", "hotplug_size": 1073741824} }"#, true, @@ -869,7 +871,7 @@ mod unit_tests { vec![( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], r#"{ - "kernel": {"path": "/path/to/kernel"} + "payload": {"kernel": "/path/to/kernel"} }"#, true, )] @@ -890,8 +892,7 @@ mod unit_tests { "arg1=foo arg2=bar", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, - "cmdline": {"args": "arg1=foo arg2=bar"} + "payload": {"kernel": "/path/to/kernel", "cmdline": "arg1=foo arg2=bar"} }"#, true, )] @@ -914,7 +915,7 @@ mod unit_tests { "path=/path/to/disk/2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "disks": [ {"path": "/path/to/disk/1"}, {"path": "/path/to/disk/2"} @@ -932,7 +933,7 @@ mod unit_tests { "path=/path/to/disk/2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "disks": [ {"path": "/path/to/disk/1"} ] @@ -950,7 +951,7 @@ mod unit_tests { "vhost_user=true,socket=/tmp/sock1", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "disks": [ {"vhost_user":true, "vhost_socket":"/tmp/sock1"} @@ -969,7 +970,7 @@ mod unit_tests { "vhost_user=true,socket=/tmp/sock1", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "disks": [ {"vhost_user":true, "vhost_socket":"/tmp/sock1"} @@ -993,7 +994,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac="], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "net": [] }"#, 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"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "net": [ {"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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "net": [ {"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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "net": [ {"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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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"} ] @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "cpus": {"boot_vcpus": 2, "max_vcpus": 2}, "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} @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "cpus": {"boot_vcpus": 2, "max_vcpus": 2}, "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} @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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"} ] @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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} ] @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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} ] @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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} ], @@ -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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "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} ] @@ -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"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "net": [ {"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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "rng": {"src": "/path/to/entropy/source"} }"#, true, @@ -1207,7 +1208,7 @@ mod unit_tests { "tag=virtiofs2,socket=/path/to/sock2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "fs": [ {"tag": "virtiofs1", "socket": "/path/to/sock1"}, @@ -1225,7 +1226,7 @@ mod unit_tests { "tag=virtiofs2,socket=/path/to/sock2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "fs": [ {"tag": "virtiofs1", "socket": "/path/to/sock1"} @@ -1241,7 +1242,7 @@ mod unit_tests { "tag=virtiofs1,socket=/path/to/sock1,num_queues=4", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "cpus": {"boot_vcpus": 4, "max_vcpus": 4}, "fs": [ @@ -1258,7 +1259,7 @@ mod unit_tests { "tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128" ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "memory" : { "shared": true, "size": 536870912 }, "cpus": {"boot_vcpus": 4, "max_vcpus": 4}, "fs": [ @@ -1287,7 +1288,7 @@ mod unit_tests { "file=/path/to/img/2,size=2G", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "pmem": [ {"file": "/path/to/img/1", "size": 1073741824}, {"file": "/path/to/img/2", "size": 2147483648} @@ -1305,7 +1306,7 @@ mod unit_tests { "file=/path/to/img/1,size=1G,iommu=on", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "pmem": [ {"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", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "pmem": [ {"file": "/path/to/img/1", "size": 1073741824, "iommu": true} ] @@ -1343,7 +1344,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "serial": {"mode": "Null"}, "console": {"mode": "Tty"} }"#, @@ -1360,7 +1361,7 @@ mod unit_tests { "tty", ], r#"{ - "kernel": {"path": "/path/to/kernel"} + "payload": {"kernel": "/path/to/kernel"} }"#, true, ), @@ -1375,7 +1376,7 @@ mod unit_tests { "off", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "serial": {"mode": "Tty"}, "console": {"mode": "Off"} }"#, @@ -1394,7 +1395,7 @@ mod unit_tests { ( vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "serial": {"mode": "Null"}, "console": {"mode": "Tty"} }"#, @@ -1411,7 +1412,7 @@ mod unit_tests { "tty", ], r#"{ - "kernel": {"path": "/path/to/kernel"} + "payload": {"kernel": "/path/to/kernel"} }"#, true, ), @@ -1426,7 +1427,7 @@ mod unit_tests { "pty", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "serial": {"mode": "Pty"}, "console": {"mode": "Pty"} }"#, @@ -1453,7 +1454,7 @@ mod unit_tests { "path=/path/to/device/2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "devices": [ {"path": "/path/to/device/1"}, {"path": "/path/to/device/2"} @@ -1471,7 +1472,7 @@ mod unit_tests { "path=/path/to/device/2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "devices": [ {"path": "/path/to/device/1"} ] @@ -1487,7 +1488,7 @@ mod unit_tests { "path=/path/to/device,iommu=on", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "devices": [ {"path": "/path/to/device", "iommu": true} ], @@ -1504,7 +1505,7 @@ mod unit_tests { "path=/path/to/device,iommu=on", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "devices": [ {"path": "/path/to/device", "iommu": true} ] @@ -1520,7 +1521,7 @@ mod unit_tests { "path=/path/to/device,iommu=off", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "devices": [ {"path": "/path/to/device", "iommu": false} ] @@ -1547,7 +1548,7 @@ mod unit_tests { "path=/path/to/device/2,num_queues=2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vdpa": [ {"path": "/path/to/device/1", "num_queues": 1}, {"path": "/path/to/device/2", "num_queues": 2} @@ -1565,7 +1566,7 @@ mod unit_tests { "path=/path/to/device/2", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vdpa": [ {"path": "/path/to/device/1"} ] @@ -1591,7 +1592,7 @@ mod unit_tests { "cid=123,socket=/path/to/sock/1", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vsock": {"cid": 123, "socket": "/path/to/sock/1"} }"#, true, @@ -1605,7 +1606,7 @@ mod unit_tests { "cid=124,socket=/path/to/sock/1", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vsock": {"cid": 123, "socket": "/path/to/sock/1"} }"#, false, @@ -1620,7 +1621,7 @@ mod unit_tests { "cid=123,socket=/path/to/sock/1,iommu=on", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true}, "iommu": true }"#, @@ -1636,7 +1637,7 @@ mod unit_tests { "cid=123,socket=/path/to/sock/1,iommu=on", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": true} }"#, false, @@ -1650,7 +1651,7 @@ mod unit_tests { "cid=123,socket=/path/to/sock/1,iommu=off", ], r#"{ - "kernel": {"path": "/path/to/kernel"}, + "payload": {"kernel": "/path/to/kernel"}, "vsock": {"cid": 123, "socket": "/path/to/sock/1", "iommu": false} }"#, true, diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 8e4c2d8b9..deba1c576 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -2248,6 +2248,16 @@ impl RestoreConfig { } } +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +pub struct PayloadConfig { + #[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)] @@ -2259,6 +2269,8 @@ pub struct VmConfig { pub initramfs: Option, #[serde(default)] pub cmdline: CmdlineConfig, + #[serde(default)] + pub payload: Option, pub disks: Option>, pub net: Option>, #[serde(default)] @@ -2312,13 +2324,28 @@ impl VmConfig { pub fn validate(&mut self) -> ValidationResult> { 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"))] - self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?; + self.payload + .as_ref() + .ok_or(ValidationError::KernelMissing)?; #[cfg(feature = "tdx")] { 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); } if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) { @@ -2644,19 +2671,15 @@ impl VmConfig { numa = Some(numa_config_list); } - let mut kernel: Option = None; - if let Some(k) = vm_params.kernel { - kernel = Some(KernelConfig { - path: PathBuf::from(k), - }); - } - - let mut initramfs: Option = None; - if let Some(k) = vm_params.initramfs { - initramfs = Some(InitramfsConfig { - path: PathBuf::from(k), - }); - } + let payload = if vm_params.kernel.is_some() { + Some(PayloadConfig { + kernel: vm_params.kernel.map(PathBuf::from), + initramfs: vm_params.initramfs.map(PathBuf::from), + cmdline: vm_params.cmdline.map(|s| s.to_string()), + }) + } else { + None + }; #[cfg(feature = "tdx")] let tdx = vm_params.tdx.map(TdxConfig::parse).transpose()?; @@ -2667,9 +2690,10 @@ impl VmConfig { let mut config = VmConfig { cpus: CpusConfig::parse(vm_params.cpus)?, memory: MemoryConfig::parse(vm_params.memory, vm_params.memory_zones)?, - kernel, - initramfs, - cmdline: CmdlineConfig::parse(vm_params.cmdline)?, + kernel: None, + initramfs: None, + cmdline: CmdlineConfig::default(), + payload, disks, net, rng, @@ -3257,13 +3281,15 @@ mod tests { prefault: false, zones: None, }, - kernel: Some(KernelConfig { - path: PathBuf::from("/path/to/kernel"), - }), - initramfs: None, + kernel: None, cmdline: CmdlineConfig { - args: String::from(""), + args: String::default(), }, + initramfs: None, + payload: Some(PayloadConfig { + kernel: Some(PathBuf::from("/path/to/kernel")), + ..Default::default() + }), disks: None, net: None, rng: RngConfig { @@ -3310,7 +3336,7 @@ mod tests { ); let mut invalid_config = valid_config.clone(); - invalid_config.kernel = None; + invalid_config.payload = None; assert_eq!( invalid_config.validate(), Err(ValidationError::KernelMissing) diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 0e6246816..a114488b3 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1968,8 +1968,8 @@ const DEVICE_MANAGER_SNAPSHOT_ID: &str = "device-manager"; mod unit_tests { use super::*; use config::{ - CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, HotplugMethod, KernelConfig, - MemoryConfig, RngConfig, VmConfig, + CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, HotplugMethod, MemoryConfig, + PayloadConfig, RngConfig, VmConfig, }; fn create_dummy_vmm() -> Vmm { @@ -2010,13 +2010,15 @@ mod unit_tests { prefault: false, zones: None, }, - kernel: Some(KernelConfig { - path: PathBuf::from("/path/to/kernel"), - }), - initramfs: None, + kernel: None, cmdline: CmdlineConfig { - args: String::from(""), + args: String::default(), }, + initramfs: None, + payload: Some(PayloadConfig { + kernel: Some(PathBuf::from("/path/to/kernel")), + ..Default::default() + }), disks: None, net: None, rng: RngConfig { diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 2d62760fe..ec91f2d60 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -494,12 +494,19 @@ impl Vm { restoring: bool, timestamp: Instant, ) -> Result { + let boot_id_list = config + .lock() + .unwrap() + .validate() + .map_err(Error::ConfigValidation)?; + let kernel = config .lock() .unwrap() - .kernel + .payload .as_ref() - .map(|k| File::open(&k.path)) + .map(|p| p.kernel.as_ref().map(File::open)) + .unwrap_or_default() .transpose() .map_err(Error::KernelFile)?; @@ -510,12 +517,6 @@ impl Vm { None }; - let boot_id_list = config - .lock() - .unwrap() - .validate() - .map_err(Error::ConfigValidation)?; - info!("Booting VM from config: {:?}", &config); // Create NUMA nodes based on NumaConfig. @@ -593,9 +594,10 @@ impl Vm { let initramfs = config .lock() .unwrap() - .initramfs + .payload .as_ref() - .map(|i| File::open(&i.path)) + .map(|p| p.initramfs.as_ref().map(File::open)) + .unwrap_or_default() .transpose() .map_err(Error::InitramfsFile)?; @@ -932,9 +934,16 @@ impl Vm { #[cfg(target_arch = "aarch64")] device_manager: &Arc>, ) -> Result { let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE); - cmdline - .insert_str(&config.lock().unwrap().cmdline.args) - .map_err(Error::CmdLineInsertStr)?; + if let Some(s) = config + .lock() + .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")] for entry in device_manager.lock().unwrap().cmdline_additions() {