[libvirt PATCH v2 0/5] Cleanup and test more firmware handling scenarios

There are a mind bending number of possible ways to configure the firmware with/without NVRAM. Only a small portion are tested and many error scenarios are silently ignored. This series attempts to get coverage of every possible XML config scenario and report explicit errors in all invalid configs. There is an open question on patch 4. Essentially the use of NVRAM combined with writable executable feels like an accidental feature in libvirt that hasn't really been thought through. I'd like to better define expectations here but there are several possible strategies and I'm undecided which is best. Changed in v2: - Merged 5 self contained patches already reviewed - Moved checks out of post-parse, into validate methods - Instead of rejecting R/W loader with NVRAM template honour the template in QEMU driver. A R/W loader is conceptually relevant if the loader allows guest to live flash upgrade itself. Not possible today but we shouldn't reject this combo since QEMU allows it. Daniel P. Berrangé (5): qemu: fix populating NVRAM vars from template with R/W loader tests: don't permit NVRAM path when using firmware auto-select conf: switch nvram parsing to use XML node / property helpers conf: move nvram parsing into virDomainLoaderDefParseXML conf: stop ignoring <loader>/<nvram> with firmware auto-select src/conf/domain_conf.c | 67 ++++++++---------- src/conf/domain_validate.c | 32 +++++++++ src/qemu/qemu_domain.c | 6 +- ...-nvram-rw-template-vars.x86_64-latest.args | 41 +++++++++++ .../bios-nvram-rw-template-vars.xml | 36 ++++++++++ .../bios-nvram-rw-template.x86_64-latest.args | 41 +++++++++++ .../bios-nvram-rw-template.xml | 36 ++++++++++ .../bios-nvram-rw-vars.x86_64-latest.args | 41 +++++++++++ tests/qemuxml2argvdata/bios-nvram-rw-vars.xml | 36 ++++++++++ tests/qemuxml2argvdata/os-firmware-bios.xml | 1 - ...ware-efi-bad-loader-path.x86_64-latest.err | 1 + .../os-firmware-efi-bad-loader-path.xml | 67 ++++++++++++++++++ ...ware-efi-bad-loader-type.x86_64-latest.err | 1 + .../os-firmware-efi-bad-loader-type.xml | 67 ++++++++++++++++++ ...mware-efi-bad-nvram-path.x86_64-latest.err | 1 + .../os-firmware-efi-bad-nvram-path.xml | 68 +++++++++++++++++++ ...e-efi-bad-nvram-template.x86_64-latest.err | 1 + .../os-firmware-efi-bad-nvram-template.xml | 68 +++++++++++++++++++ .../os-firmware-efi-secboot.xml | 1 - tests/qemuxml2argvdata/os-firmware-efi.xml | 1 - tests/qemuxml2argvtest.c | 7 ++ .../os-firmware-bios.x86_64-latest.xml | 1 - .../os-firmware-efi-secboot.x86_64-latest.xml | 1 - .../os-firmware-efi.x86_64-latest.xml | 1 - 24 files changed, 578 insertions(+), 45 deletions(-) create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template-vars.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template-vars.xml create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template.xml create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-vars.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-vars.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml -- 2.34.1

The QEMU driver will populate the template to the nvram file any time it sees both the template and nvram paths present. It will auto-generate a nvram path per-VM if not provided by the user, but only if the loader is marked R/O. So with a R/O loader we have these possible scenarios - No NVRAM path or template -> try to infer a template based on the loader path, if not possible, fatal error. Auto-generate NVRAM per per VM - NVRAM path only -> try to infer a template based on the loader path, if not possible, app must have pre-created NVRAM - NVRAM path + template -> QEMU driver will copy template to NVRAM - NVRAM template only -> auto-generate NVRAM path per VM and then copy template While with a R/W loader we have these possible scenarios - No NVRAM path or template -> do nothing - NVRAM path only -> app must have pre-created NVRAM - NVRAM path + template -> QEMU driver will copy template to NVRAM - NVRAM template only -> silently ignored This change fixses the last scenario by making us auto-generate an NVRAM path per VM, and then copy the template. We can't infer a template based on the loaer path, but we align in other key areas. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_domain.c | 6 ++- ...-nvram-rw-template-vars.x86_64-latest.args | 41 +++++++++++++++++++ .../bios-nvram-rw-template-vars.xml | 36 ++++++++++++++++ .../bios-nvram-rw-template.x86_64-latest.args | 41 +++++++++++++++++++ .../bios-nvram-rw-template.xml | 36 ++++++++++++++++ .../bios-nvram-rw-vars.x86_64-latest.args | 41 +++++++++++++++++++ tests/qemuxml2argvdata/bios-nvram-rw-vars.xml | 36 ++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 8 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template-vars.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template-vars.xml create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-template.xml create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-vars.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/bios-nvram-rw-vars.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index acc76c1cd6..14a558a7ac 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4451,8 +4451,10 @@ qemuDomainDefPostParse(virDomainDef *def, def->os.machine = g_strdup(machine); } - if (virDomainDefHasOldStyleROUEFI(def) && - !def->os.loader->nvram) + if (virDomainDefHasOldStyleUEFI(def) && + !def->os.loader->nvram && + (def->os.loader->readonly == VIR_TRISTATE_BOOL_YES || + def->os.loader->nvramTemplate)) qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram); if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0) diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.x86_64-latest.args b/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.x86_64-latest.args new file mode 100644 index 0000000000..8d971ec29b --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.x86_64-latest.args @@ -0,0 +1,41 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-test-bios \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-test-bios/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-test-bios/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-test-bios/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=test-bios,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-test-bios/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/test-bios.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/some/vars/path.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \ +-machine pc,usb=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=pc.ram \ +-accel tcg \ +-cpu qemu64 \ +-m 1024 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot menu=on,strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ +-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}' \ +-device '{"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.xml b/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.xml new file mode 100644 index 0000000000..fe6a064c84 --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-template-vars.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>test-bios</name> + <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <loader readonly='no' type='pflash'>/var/lib/libvirt/qemu/nvram/test-bios.fd</loader> + <nvram template="/some/vars/template/path.fd">/some/vars/path.fd</nvram> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='tablet' bus='usb'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-template.x86_64-latest.args b/tests/qemuxml2argvdata/bios-nvram-rw-template.x86_64-latest.args new file mode 100644 index 0000000000..2900571473 --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-template.x86_64-latest.args @@ -0,0 +1,41 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-test-bios \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-test-bios/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-test-bios/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-test-bios/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=test-bios,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-test-bios/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/test-bios.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/test-bios_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \ +-machine pc,usb=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=pc.ram \ +-accel tcg \ +-cpu qemu64 \ +-m 1024 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot menu=on,strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ +-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}' \ +-device '{"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-template.xml b/tests/qemuxml2argvdata/bios-nvram-rw-template.xml new file mode 100644 index 0000000000..334ed1425b --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-template.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>test-bios</name> + <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <loader readonly='no' type='pflash'>/var/lib/libvirt/qemu/nvram/test-bios.fd</loader> + <nvram template="/some/vars/template/path.fd"/> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='tablet' bus='usb'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-vars.x86_64-latest.args b/tests/qemuxml2argvdata/bios-nvram-rw-vars.x86_64-latest.args new file mode 100644 index 0000000000..8d971ec29b --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-vars.x86_64-latest.args @@ -0,0 +1,41 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-test-bios \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-test-bios/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-test-bios/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-test-bios/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=test-bios,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-test-bios/master-key.aes"}' \ +-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/test-bios.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \ +-blockdev '{"driver":"file","filename":"/some/vars/path.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \ +-machine pc,usb=off,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=pc.ram \ +-accel tcg \ +-cpu qemu64 \ +-m 1024 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot menu=on,strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ +-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}' \ +-device '{"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/bios-nvram-rw-vars.xml b/tests/qemuxml2argvdata/bios-nvram-rw-vars.xml new file mode 100644 index 0000000000..12fdb251f3 --- /dev/null +++ b/tests/qemuxml2argvdata/bios-nvram-rw-vars.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>test-bios</name> + <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <loader readonly='no' type='pflash'>/var/lib/libvirt/qemu/nvram/test-bios.fd</loader> + <nvram>/some/vars/path.fd</nvram> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='tablet' bus='usb'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 9378125da1..d2a53d35a8 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1191,6 +1191,9 @@ mymain(void) DO_TEST_PARSE_ERROR_NOCAPS("bios-nvram-no-path"); DO_TEST_CAPS_LATEST("bios-nvram-rw"); DO_TEST_CAPS_LATEST("bios-nvram-rw-implicit"); + DO_TEST_CAPS_LATEST("bios-nvram-rw-template"); + DO_TEST_CAPS_LATEST("bios-nvram-rw-template-vars"); + DO_TEST_CAPS_LATEST("bios-nvram-rw-vars"); DO_TEST("bios-nvram-secure", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_PCI_BRIDGE, -- 2.34.1

When using <os firmware='...'/> we still parse the <nvram> path, but completely ignore it, replacing any user provided content with a custom generated path. This makes sense since when undefining the guest, the code to cleanup NVRAM also uses the same generated path. Instead of silently ignoring user config, we should report an explicit error message. This shows that some of our tests had the bogus config scenario present. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_validate.c | 8 +++ tests/qemuxml2argvdata/os-firmware-bios.xml | 1 - ...mware-efi-bad-nvram-path.x86_64-latest.err | 1 + .../os-firmware-efi-bad-nvram-path.xml | 68 +++++++++++++++++++ .../os-firmware-efi-secboot.xml | 1 - tests/qemuxml2argvdata/os-firmware-efi.xml | 1 - tests/qemuxml2argvtest.c | 1 + .../os-firmware-bios.x86_64-latest.xml | 1 - .../os-firmware-efi-secboot.x86_64-latest.xml | 1 - .../os-firmware-efi.x86_64-latest.xml | 1 - 10 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f0b8aa2655..22bfb3b59d 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1504,6 +1504,14 @@ virDomainDefOSValidate(const virDomainDef *def, return -1; } + if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { + if (def->os.loader->nvram) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("NVRAM path is not permitted with firmware attribute")); + return -1; + } + } + return 0; } diff --git a/tests/qemuxml2argvdata/os-firmware-bios.xml b/tests/qemuxml2argvdata/os-firmware-bios.xml index 63886666dd..d89fcb6c58 100644 --- a/tests/qemuxml2argvdata/os-firmware-bios.xml +++ b/tests/qemuxml2argvdata/os-firmware-bios.xml @@ -7,7 +7,6 @@ <os firmware='bios'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='no'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.x86_64-latest.err new file mode 100644 index 0000000000..2ba8135ad4 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.x86_64-latest.err @@ -0,0 +1 @@ +XML error: NVRAM path is not permitted with firmware attribute diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.xml new file mode 100644 index 0000000000..a4afdb6d0b --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-path.xml @@ -0,0 +1,68 @@ +<domain type='kvm'> + <name>fedora</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>8192</memory> + <currentMemory unit='KiB'>8192</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> + <loader secure='no'/> + <nvram>/some/path</nvram> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/os-firmware-efi-secboot.xml b/tests/qemuxml2argvdata/os-firmware-efi-secboot.xml index a285e06334..51faac54bf 100644 --- a/tests/qemuxml2argvdata/os-firmware-efi-secboot.xml +++ b/tests/qemuxml2argvdata/os-firmware-efi-secboot.xml @@ -7,7 +7,6 @@ <os firmware='efi'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='yes'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> diff --git a/tests/qemuxml2argvdata/os-firmware-efi.xml b/tests/qemuxml2argvdata/os-firmware-efi.xml index 46a7b1b780..cb21437ed8 100644 --- a/tests/qemuxml2argvdata/os-firmware-efi.xml +++ b/tests/qemuxml2argvdata/os-firmware-efi.xml @@ -7,7 +7,6 @@ <os firmware='efi'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='no'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d2a53d35a8..693566f2d4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3406,6 +3406,7 @@ mymain(void) DO_TEST_CAPS_LATEST("os-firmware-bios"); DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-efi-bad-nvram-path"); DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); diff --git a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml index df6f61421a..a278ff059c 100644 --- a/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/os-firmware-bios.x86_64-latest.xml @@ -7,7 +7,6 @@ <os firmware='bios'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='no'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml index c383546cc6..e7224896aa 100644 --- a/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/os-firmware-efi-secboot.x86_64-latest.xml @@ -7,7 +7,6 @@ <os firmware='efi'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='yes'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> diff --git a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml index 04d57860e7..73f4b9a033 100644 --- a/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/os-firmware-efi.x86_64-latest.xml @@ -7,7 +7,6 @@ <os firmware='efi'> <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> <loader secure='no'/> - <nvram>/var/lib/libvirt/qemu/nvram/fedora_VARS.fd</nvram> <boot dev='hd'/> <bootmenu enable='yes'/> </os> -- 2.34.1

Instead of using XPath, parse the <nvram> using the XML node and property helpers so the code is consistent with the parsing of <loader>. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 34fec887a3..1b423298ce 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18211,21 +18211,30 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def, xmlXPathContextPtr ctxt) { xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); + xmlNodePtr nvram_node = virXPathNode("./os/nvram[1]", ctxt); const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; + virDomainLoaderDef *loader; if (!loader_node) return 0; - def->os.loader = g_new0(virDomainLoaderDef, 1); + def->os.loader = loader = g_new0(virDomainLoaderDef, 1); if (virDomainLoaderDefParseXML(loader_node, def->os.loader, fwAutoSelect) < 0) return -1; - def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt); - if (!fwAutoSelect) - def->os.loader->nvramTemplate = virXPathString("string(./os/nvram[1]/@template)", ctxt); + if (nvram_node) { + if (!(loader->nvram = virXMLNodeContentString(nvram_node))) + return -1; + + if (STREQ(loader->nvram, "")) + VIR_FREE(loader->nvram); + + if (!fwAutoSelect) + def->os.loader->nvramTemplate = virXMLPropString(nvram_node, "template"); + } return 0; } -- 2.34.1

The virDomainLoaderDef struct contains fields for both <loader> and <nvram> elements, so it makes sense to parse them in the same method, just like we'll format them in the same method. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 92 ++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1b423298ce..d79af0b6c8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17795,29 +17795,51 @@ virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDef *def) } static int -virDomainLoaderDefParseXML(xmlNodePtr node, - virDomainLoaderDef *loader, - bool fwAutoSelect) +virDomainLoaderDefParseXML(virDomainDef *def, + xmlXPathContextPtr ctxt) { - if (!fwAutoSelect) { - if (virXMLPropTristateBool(node, "readonly", VIR_XML_PROP_NONE, - &loader->readonly) < 0) - return -1; + xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); + xmlNodePtr nvram_node = virXPathNode("./os/nvram[1]", ctxt); + const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; + virDomainLoaderDef *loader; + + if (!loader_node && !nvram_node) + return 0; + + def->os.loader = loader = g_new0(virDomainLoaderDef, 1); + + if (loader_node) { + if (!fwAutoSelect) { + if (virXMLPropTristateBool(loader_node, "readonly", VIR_XML_PROP_NONE, + &loader->readonly) < 0) + return -1; + + if (virXMLPropEnum(loader_node, "type", virDomainLoaderTypeFromString, + VIR_XML_PROP_NONZERO, &loader->type) < 0) + return -1; - if (virXMLPropEnum(node, "type", virDomainLoaderTypeFromString, - VIR_XML_PROP_NONZERO, &loader->type) < 0) + if (!(loader->path = virXMLNodeContentString(loader_node))) + return -1; + + if (STREQ(loader->path, "")) + VIR_FREE(loader->path); + } + + if (virXMLPropTristateBool(loader_node, "secure", VIR_XML_PROP_NONE, + &loader->secure) < 0) return -1; + } - if (!(loader->path = virXMLNodeContentString(node))) + if (nvram_node) { + if (!(loader->nvram = virXMLNodeContentString(nvram_node))) return -1; - if (STREQ(loader->path, "")) - VIR_FREE(loader->path); - } + if (STREQ(loader->nvram, "")) + VIR_FREE(loader->nvram); - if (virXMLPropTristateBool(node, "secure", VIR_XML_PROP_NONE, - &loader->secure) < 0) - return -1; + if (!fwAutoSelect) + loader->nvramTemplate = virXMLPropString(nvram_node, "template"); + } return 0; } @@ -18206,40 +18228,6 @@ virDomainDefParseBootFirmwareOptions(virDomainDef *def, } -static int -virDomainDefParseBootLoaderOptions(virDomainDef *def, - xmlXPathContextPtr ctxt) -{ - xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); - xmlNodePtr nvram_node = virXPathNode("./os/nvram[1]", ctxt); - const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; - virDomainLoaderDef *loader; - - if (!loader_node) - return 0; - - def->os.loader = loader = g_new0(virDomainLoaderDef, 1); - - if (virDomainLoaderDefParseXML(loader_node, - def->os.loader, - fwAutoSelect) < 0) - return -1; - - if (nvram_node) { - if (!(loader->nvram = virXMLNodeContentString(nvram_node))) - return -1; - - if (STREQ(loader->nvram, "")) - VIR_FREE(loader->nvram); - - if (!fwAutoSelect) - def->os.loader->nvramTemplate = virXMLPropString(nvram_node, "template"); - } - - return 0; -} - - static int virDomainDefParseBootAcpiOptions(virDomainDef *def, xmlXPathContextPtr ctxt) @@ -18304,7 +18292,7 @@ virDomainDefParseBootOptions(virDomainDef *def, if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) return -1; - if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + if (virDomainLoaderDefParseXML(def, ctxt) < 0) return -1; if (virDomainDefParseBootAcpiOptions(def, ctxt) < 0) @@ -18320,7 +18308,7 @@ virDomainDefParseBootOptions(virDomainDef *def, case VIR_DOMAIN_OSTYPE_UML: virDomainDefParseBootKernelOptions(def, ctxt); - if (virDomainDefParseBootLoaderOptions(def, ctxt) < 0) + if (virDomainLoaderDefParseXML(def, ctxt) < 0) return -1; break; -- 2.34.1

Currently if the <os> firmware attribute is set then we silently ignore most of the <loader> and <nvram> element configs. This changes the code so that we always fully parse the <loader> and <nvram> but then use a post-parse method to explicitly reject invalid combinations. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 26 +++---- src/conf/domain_validate.c | 24 +++++++ ...ware-efi-bad-loader-path.x86_64-latest.err | 1 + .../os-firmware-efi-bad-loader-path.xml | 67 ++++++++++++++++++ ...ware-efi-bad-loader-type.x86_64-latest.err | 1 + .../os-firmware-efi-bad-loader-type.xml | 67 ++++++++++++++++++ ...e-efi-bad-nvram-template.x86_64-latest.err | 1 + .../os-firmware-efi-bad-nvram-template.xml | 68 +++++++++++++++++++ tests/qemuxml2argvtest.c | 3 + 9 files changed, 243 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.x86_64-latest.err create mode 100644 tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d79af0b6c8..e8ce0caa85 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17800,7 +17800,6 @@ virDomainLoaderDefParseXML(virDomainDef *def, { xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt); xmlNodePtr nvram_node = virXPathNode("./os/nvram[1]", ctxt); - const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE; virDomainLoaderDef *loader; if (!loader_node && !nvram_node) @@ -17809,21 +17808,19 @@ virDomainLoaderDefParseXML(virDomainDef *def, def->os.loader = loader = g_new0(virDomainLoaderDef, 1); if (loader_node) { - if (!fwAutoSelect) { - if (virXMLPropTristateBool(loader_node, "readonly", VIR_XML_PROP_NONE, - &loader->readonly) < 0) - return -1; + if (virXMLPropTristateBool(loader_node, "readonly", VIR_XML_PROP_NONE, + &loader->readonly) < 0) + return -1; - if (virXMLPropEnum(loader_node, "type", virDomainLoaderTypeFromString, - VIR_XML_PROP_NONZERO, &loader->type) < 0) - return -1; + if (virXMLPropEnum(loader_node, "type", virDomainLoaderTypeFromString, + VIR_XML_PROP_NONZERO, &loader->type) < 0) + return -1; - if (!(loader->path = virXMLNodeContentString(loader_node))) - return -1; + if (!(loader->path = virXMLNodeContentString(loader_node))) + return -1; - if (STREQ(loader->path, "")) - VIR_FREE(loader->path); - } + if (STREQ(loader->path, "")) + VIR_FREE(loader->path); if (virXMLPropTristateBool(loader_node, "secure", VIR_XML_PROP_NONE, &loader->secure) < 0) @@ -17837,8 +17834,7 @@ virDomainLoaderDefParseXML(virDomainDef *def, if (STREQ(loader->nvram, "")) VIR_FREE(loader->nvram); - if (!fwAutoSelect) - loader->nvramTemplate = virXMLPropString(nvram_node, "template"); + loader->nvramTemplate = virXMLPropString(nvram_node, "template"); } return 0; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 22bfb3b59d..9ccb5d0dc2 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1505,6 +1505,30 @@ virDomainDefOSValidate(const virDomainDef *def, } if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { + if (def->os.loader->path) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Loader path is not permitted with firmware attribute")); + return -1; + } + + if (def->os.loader->type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Loader type is not permitted with firmware attribute")); + return -1; + } + + if (def->os.loader->readonly) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Loader read-only attribute is not permitted with firmware attribute")); + return -1; + } + + if (def->os.loader->nvramTemplate) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("NVRAM template path is not permitted with firmware attribute")); + return -1; + } + if (def->os.loader->nvram) { virReportError(VIR_ERR_XML_ERROR, "%s", _("NVRAM path is not permitted with firmware attribute")); diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.x86_64-latest.err new file mode 100644 index 0000000000..a8dbd0d6d8 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.x86_64-latest.err @@ -0,0 +1 @@ +XML error: Loader path is not permitted with firmware attribute diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml new file mode 100644 index 0000000000..02eec67c35 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-path.xml @@ -0,0 +1,67 @@ +<domain type='kvm'> + <name>fedora</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>8192</memory> + <currentMemory unit='KiB'>8192</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> + <loader secure='no'>/some/path</loader> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.x86_64-latest.err new file mode 100644 index 0000000000..2824399628 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.x86_64-latest.err @@ -0,0 +1 @@ +XML error: Loader type is not permitted with firmware attribute diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml new file mode 100644 index 0000000000..9091a2a8ce --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-loader-type.xml @@ -0,0 +1,67 @@ +<domain type='kvm'> + <name>fedora</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>8192</memory> + <currentMemory unit='KiB'>8192</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> + <loader secure='no' type='pflash'/> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.x86_64-latest.err b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.x86_64-latest.err new file mode 100644 index 0000000000..866ef34ec4 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.x86_64-latest.err @@ -0,0 +1 @@ +XML error: NVRAM template path is not permitted with firmware attribute diff --git a/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml new file mode 100644 index 0000000000..cf77ca5433 --- /dev/null +++ b/tests/qemuxml2argvdata/os-firmware-efi-bad-nvram-template.xml @@ -0,0 +1,68 @@ +<domain type='kvm'> + <name>fedora</name> + <uuid>63840878-0deb-4095-97e6-fc444d9bc9fa</uuid> + <memory unit='KiB'>8192</memory> + <currentMemory unit='KiB'>8192</currentMemory> + <vcpu placement='static'>1</vcpu> + <os firmware='efi'> + <type arch='x86_64' machine='pc-q35-4.0'>hvm</type> + <loader secure='no'/> + <nvram template="/some/path">/some/vars</nvram> + <boot dev='hd'/> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='ich9-ehci1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/> + </controller> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='dmi-to-pci-bridge'> + <model name='i82801b11-bridge'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/> + </controller> + <controller type='pci' index='2' model='pci-bridge'> + <model name='pci-bridge'/> + <target chassisNr='2'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </controller> + <controller type='pci' index='3' model='pcie-root-port'> + <model name='ioh3420'/> + <target chassis='3' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 693566f2d4..35a5c6d555 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3406,7 +3406,10 @@ mymain(void) DO_TEST_CAPS_LATEST("os-firmware-bios"); DO_TEST_CAPS_LATEST("os-firmware-efi"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-efi-bad-loader-path"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-efi-bad-loader-type"); DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-efi-bad-nvram-path"); + DO_TEST_CAPS_LATEST_PARSE_ERROR("os-firmware-efi-bad-nvram-template"); DO_TEST_CAPS_LATEST("os-firmware-efi-secboot"); DO_TEST_CAPS_LATEST("os-firmware-efi-no-enrolled-keys"); DO_TEST_CAPS_ARCH_LATEST("aarch64-os-firmware-efi", "aarch64"); -- 2.34.1
participants (1)
-
Daniel P. Berrangé