[libvirt] [PATCH 3/3] qemu: add support for simpler UEFI config
John Ferlan
jferlan at redhat.com
Wed Oct 12 01:40:55 UTC 2016
On 10/03/2016 11:49 AM, Daniel P. Berrange wrote:
> This wires up the domain XML post-parse callback so that
> it can fill in the loader/nvram paths, when seeing the
> "firmware" attribute set.
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> src/qemu/qemu_command.c | 6 ++-
> src/qemu/qemu_conf.c | 12 ++---
> src/qemu/qemu_conf.h | 7 +++
> src/qemu/qemu_domain.c | 60 +++++++++++++++++++---
> .../qemuxml2argv-bios-firmware.args | 26 ++++++++++
> .../qemuxml2argv-bios-firmware.xml | 41 +++++++++++++++
> tests/qemuxml2argvtest.c | 1 +
> .../qemuxml2xmlout-bios-firmware.xml | 48 +++++++++++++++++
> tests/qemuxml2xmltest.c | 1 +
> tests/testutilsqemu.c | 30 ++++++++++-
> 10 files changed, 214 insertions(+), 18 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.xml
> create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-firmware.xml
>
The xml2xml tests could go in patch2 I suppose, but they're fine here
too - at least they're provided.
Could add that empty path for bios/rom type test too if you felt so
compelled.
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 7e52963..a7529bf 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -8927,8 +8927,10 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
>
> switch ((virDomainLoader) loader->type) {
> case VIR_DOMAIN_LOADER_TYPE_ROM:
> - virCommandAddArg(cmd, "-bios");
> - virCommandAddArg(cmd, loader->path);
> + if (loader->path) {
> + virCommandAddArg(cmd, "-bios");
> + virCommandAddArg(cmd, loader->path);
If !loader->path then -bios has no path? Is that OK from QEMU?
> + }
> break;
>
> case VIR_DOMAIN_LOADER_TYPE_PFLASH:
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index 635fa27..879e2aa 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -124,13 +124,6 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def)
> }
>
>
> -#define VIR_QEMU_OVMF_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.fd"
> -#define VIR_QEMU_OVMF_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd"
> -#define VIR_QEMU_OVMF_SEC_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.secboot.fd"
> -#define VIR_QEMU_OVMF_SEC_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd"
> -#define VIR_QEMU_AAVMF_LOADER_PATH "/usr/share/AAVMF/AAVMF_CODE.fd"
> -#define VIR_QEMU_AAVMF_NVRAM_PATH "/usr/share/AAVMF/AAVMF_VARS.fd"
> -
> virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
> {
> virQEMUDriverConfigPtr cfg;
> @@ -334,6 +327,11 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
> VIR_STRDUP(cfg->firmwares[2]->name, VIR_QEMU_OVMF_SEC_LOADER_PATH) < 0 ||
> VIR_STRDUP(cfg->firmwares[2]->nvram, VIR_QEMU_OVMF_SEC_NVRAM_PATH) < 0)
> goto error;
> +
> + cfg->firmwares[0]->arch = VIR_ARCH_AARCH64;
> + cfg->firmwares[1]->arch = VIR_ARCH_X86_64;
> + cfg->firmwares[2]->arch = VIR_ARCH_X86_64;
> + cfg->firmwares[2]->secboot = true;
> #endif
>
> return cfg;
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index d32689a..2f0c91f 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -66,6 +66,13 @@ typedef virQEMUDriver *virQEMUDriverPtr;
> typedef struct _virQEMUDriverConfig virQEMUDriverConfig;
> typedef virQEMUDriverConfig *virQEMUDriverConfigPtr;
>
> +# define VIR_QEMU_OVMF_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.fd"
> +# define VIR_QEMU_OVMF_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd"
> +# define VIR_QEMU_OVMF_SEC_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.secboot.fd"
> +# define VIR_QEMU_OVMF_SEC_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd"
> +# define VIR_QEMU_AAVMF_LOADER_PATH "/usr/share/AAVMF/AAVMF_CODE.fd"
> +# define VIR_QEMU_AAVMF_NVRAM_PATH "/usr/share/AAVMF/AAVMF_VARS.fd"
> +
> /* Main driver config. The data in these object
> * instances is immutable, so can be accessed
> * without locking. Threads must, however, hold
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 9b1a32e..3badd38 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -2346,13 +2346,59 @@ qemuDomainDefPostParse(virDomainDefPtr def,
> goto cleanup;
> }
>
> - if (def->os.loader &&
> - def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
> - def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&
> - !def->os.loader->nvram) {
> - if (virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd",
> - cfg->nvramDir, def->name) < 0)
> - goto cleanup;
> + if (def->os.loader) {
> + switch (def->os.loader->firmware) {
> + case VIR_DOMAIN_LOADER_FIRMWARE_DEFAULT:
> + break;
Again, is having !def->os.loader.path OK here? or will it be a problem?
It seems from qemu-kvm --help it will be:
-bios file set the filename for the BIOS
> +
> + case VIR_DOMAIN_LOADER_FIRMWARE_BIOS:
> + if (def->os.arch != VIR_ARCH_I686 &&
> + def->os.arch != VIR_ARCH_X86_64) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("BIOS firmware only supported on i686/x86_64"));
> + goto cleanup;
> + }
> + break;
> +
> + case VIR_DOMAIN_LOADER_FIRMWARE_UEFI:
> + if (def->os.arch != VIR_ARCH_X86_64 &&
> + def->os.arch != VIR_ARCH_AARCH64) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("BIOS firmware only supported on x86_64/i686"));
UEFI on x86_64/aarch
Could also use the virArchToString for both failure messages to be precise.
ACK w/ fixed error message and handling that empty -bios arg.
John
> + goto cleanup;
> + }
> +
> + if (def->os.loader->path == NULL) {
> + virFirmwarePtr firmware;
> +
> + if (!(firmware = virFirmwareFind(cfg->firmwares,
> + cfg->nfirmwares,
> + def->os.arch,
> + def->os.loader->secure ==
> + VIR_TRISTATE_SWITCH_ON)))
> + goto cleanup;
> +
> + if (VIR_STRDUP(def->os.loader->path,
> + firmware->name) < 0)
> + goto cleanup;
> +
> + if (def->os.loader->templt == NULL &&
> + VIR_STRDUP(def->os.loader->templt,
> + firmware->nvram) < 0)
> + goto cleanup;
> + }
> +
> + case VIR_DOMAIN_LOADER_FIRMWARE_LAST:
> + break;
> + }
> +
> + if (def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
> + def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&
> + !def->os.loader->nvram) {
> + if (virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd",
> + cfg->nvramDir, def->name) < 0)
> + goto cleanup;
> + }
> }
>
> /* check for emulator and create a default one if needed */
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.args b/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.args
> new file mode 100644
> index 0000000..e10f4ec
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.args
> @@ -0,0 +1,26 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu \
> +-name test-bios \
> +-S \
> +-M pc \
> +-drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,\
> +readonly=on \
> +-drive file=/tmp/nvram/test-bios_VARS.fd,if=pflash,format=raw,unit=1 \
> +-m 1024 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \
> +-nographic \
> +-nodefaults \
> +-monitor unix:/tmp/lib/domain--1-test-bios/monitor.sock,server,nowait \
> +-boot c \
> +-usb \
> +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
> +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
> +-serial pty \
> +-device usb-tablet,id=input0,bus=usb.0,port=1 \
> +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.xml b/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.xml
> new file mode 100644
> index 0000000..cea1efc
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-firmware.xml
> @@ -0,0 +1,41 @@
> +<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 firmware='uefi'/>
> + <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</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'/>
> + <serial type='pty'>
> + <target port='0'/>
> + </serial>
> + <console type='pty'>
> + <target type='serial' port='0'/>
> + </console>
> + <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 903276d..5a45f17 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -727,6 +727,7 @@ mymain(void)
> QEMU_CAPS_MACHINE_OPT,
> QEMU_CAPS_MACHINE_SMM_OPT,
> QEMU_CAPS_VIRTIO_SCSI);
> + DO_TEST("bios-firmware", NONE);
> DO_TEST("clock-utc", QEMU_CAPS_NODEFCONFIG);
> DO_TEST("clock-localtime", NONE);
> DO_TEST("clock-localtime-basis-localtime", QEMU_CAPS_RTC);
> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-firmware.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-firmware.xml
> new file mode 100644
> index 0000000..624c60f
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-firmware.xml
> @@ -0,0 +1,48 @@
> +<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 firmware='uefi' readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
> + <nvram template='/usr/share/OVMF/OVMF_VARS.fd'>/tmp/nvram/test-bios_VARS.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</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'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
> + </controller>
> + <controller type='ide' index='0'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
> + </controller>
> + <controller type='pci' index='0' model='pci-root'/>
> + <serial type='pty'>
> + <target port='0'/>
> + </serial>
> + <console type='pty'>
> + <target type='serial' port='0'/>
> + </console>
> + <input type='tablet' bus='usb'/>
> + <input type='mouse' bus='ps2'/>
> + <input type='keyboard' bus='ps2'/>
> + <memballoon model='virtio'>
> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
> + </memballoon>
> + </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index fb05c85..5f94c26 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -808,6 +808,7 @@ mymain(void)
>
> DO_TEST("bios-nvram", NONE);
> DO_TEST("bios-nvram-os-interleave", NONE);
> + DO_TEST("bios-firmware", NONE);
>
> DO_TEST("tap-vhost", NONE);
> DO_TEST("tap-vhost-incorrect", NONE);
> diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
> index e66903a..3492f28 100644
> --- a/tests/testutilsqemu.c
> +++ b/tests/testutilsqemu.c
> @@ -552,21 +552,24 @@ int qemuTestCapsCacheInsert(virQEMUCapsCachePtr cache, const char *binary,
> int qemuTestDriverInit(virQEMUDriver *driver)
> {
> virSecurityManagerPtr mgr = NULL;
> + virQEMUDriverConfigPtr cfg;
>
> memset(driver, 0, sizeof(*driver));
>
> if (virMutexInit(&driver->lock) < 0)
> return -1;
>
> - driver->config = virQEMUDriverConfigNew(false);
> + cfg = driver->config = virQEMUDriverConfigNew(false);
> if (!driver->config)
> goto error;
>
> /* Overwrite some default paths so it's consistent for tests. */
> VIR_FREE(driver->config->libDir);
> VIR_FREE(driver->config->channelTargetDir);
> + VIR_FREE(driver->config->nvramDir);
> if (VIR_STRDUP(driver->config->libDir, "/tmp/lib") < 0 ||
> - VIR_STRDUP(driver->config->channelTargetDir, "/tmp/channel") < 0)
> + VIR_STRDUP(driver->config->channelTargetDir, "/tmp/channel") < 0 ||
> + VIR_STRDUP(driver->config->nvramDir, "/tmp/nvram") < 0)
> goto error;
>
> driver->caps = testQemuCapsInit();
> @@ -592,6 +595,29 @@ int qemuTestDriverInit(virQEMUDriver *driver)
> if (!(driver->securityManager = virSecurityManagerNewStack(mgr)))
> goto error;
>
> + /* The default firmware list may be changed by configure arg,
> + * so we must clear it and setup a fixed firmware list for testing */
> + virFirmwareFreeList(cfg->firmwares, cfg->nfirmwares);
> + if (VIR_ALLOC_N(cfg->firmwares, 3) < 0)
> + goto error;
> + cfg->nfirmwares = 3;
> + if (VIR_ALLOC(cfg->firmwares[0]) < 0 || VIR_ALLOC(cfg->firmwares[1]) < 0 ||
> + VIR_ALLOC(cfg->firmwares[2]) < 0)
> + goto error;
> +
> + if (VIR_STRDUP(cfg->firmwares[0]->name, VIR_QEMU_AAVMF_LOADER_PATH) < 0 ||
> + VIR_STRDUP(cfg->firmwares[0]->nvram, VIR_QEMU_AAVMF_NVRAM_PATH) < 0 ||
> + VIR_STRDUP(cfg->firmwares[1]->name, VIR_QEMU_OVMF_LOADER_PATH) < 0 ||
> + VIR_STRDUP(cfg->firmwares[1]->nvram, VIR_QEMU_OVMF_NVRAM_PATH) < 0 ||
> + VIR_STRDUP(cfg->firmwares[2]->name, VIR_QEMU_OVMF_SEC_LOADER_PATH) < 0 ||
> + VIR_STRDUP(cfg->firmwares[2]->nvram, VIR_QEMU_OVMF_SEC_NVRAM_PATH) < 0)
> + goto error;
> +
> + cfg->firmwares[0]->arch = VIR_ARCH_AARCH64;
> + cfg->firmwares[1]->arch = VIR_ARCH_X86_64;
> + cfg->firmwares[2]->arch = VIR_ARCH_X86_64;
> + cfg->firmwares[2]->secboot = true;
> +
> return 0;
>
> error:
>
More information about the libvir-list
mailing list