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@xxxxxxxxxx> --- 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 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); + } 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; + + 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")); + 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: -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list