[libvirt] [PATCH 3/3] qemu: add support for simpler UEFI config

Daniel P. Berrange berrange at redhat.com
Mon Oct 3 15:49:49 UTC 2016


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

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




More information about the libvir-list mailing list