[libvirt] [PATCH v3] qemu: Allow UEFI paths to be specified at compile time

Michal Privoznik mprivozn at redhat.com
Wed Jan 14 15:28:33 UTC 2015


Up until now there are just two ways how to specify UEFI paths to
libvirt. The first one is editing qemu.conf, the other is editing
qemu_conf.c and recompile which is not that fancy. So, new
configure option is introduced: --with-loader-nvram which takes a
list of pairs of UEFI firmware and NVRAM store. This way, the
compiled in defaults can be passed during compile time without
need to change the code itself.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 configure.ac                                       | 32 +++++++++++++++++
 src/qemu/qemu.conf                                 | 12 +++++--
 src/qemu/qemu_conf.c                               | 41 ++++++++++++++++++----
 src/qemu/test_libvirtd_qemu.aug.in                 |  1 +
 .../domaincaps-qemu_1.6.50-1.xml                   |  1 +
 tests/domaincapstest.c                             | 15 ++++----
 6 files changed, 85 insertions(+), 17 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9d12079..164cfad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2786,6 +2786,38 @@ AC_ARG_WITH([default-editor],
   [DEFAULT_EDITOR=vi])
 AC_DEFINE_UNQUOTED([DEFAULT_EDITOR], ["$DEFAULT_EDITOR"], [Default editor to use])
 
+AC_ARG_WITH([loader-nvram],
+  [AS_HELP_STRING([--with-loader-nvram],
+    [Pass list of pairs of <loader>:<nvram> paths. Both
+     pairs and list items are separated by a colon.
+     @<:default=paths to OVMF and its clones@:>@])],
+  [with_loader_nvram=${withval}],
+  [with_loader_nvram=no])
+
+if test "$with_loader_nvram" != "no"; then
+    IFS=':' read -a loader_arr <<< "${with_loader_nvram}"
+
+    loader_str_c="{"
+    nvram_str_c="{"
+    for ((indx=0; indx<${#loader_arr[@]}; indx+=2)); do
+        loader=${loader_arr[[indx]]}
+        nvram=${loader_arr[[indx+1]]}
+
+        if test -z "$loader" || test -z "$nvram"; then
+            AC_MSG_ERROR([Malformed loader-nvram list])
+        fi
+
+        loader_str_c="$loader_str_c \"$loader\","
+        nvram_str_c="$nvram_str_c \"$nvram\","
+    done
+
+    loader_str_c="$loader_str_c }"
+    nvram_str_c="$nvram_str_c }"
+
+    AC_DEFINE_UNQUOTED([DEFAULT_LOADER], [$loader_str_c], [Array of loader paths])
+    AC_DEFINE_UNQUOTED([DEFAULT_NVRAM], [$nvram_str_c], [Array of nvram paths])
+fi
+
 # Some GNULIB base64 symbols clash with a kerberos library
 AC_DEFINE_UNQUOTED([isbase64],[libvirt_gl_isbase64],[Hack to avoid symbol clash])
 AC_DEFINE_UNQUOTED([base64_encode],[libvirt_gl_base64_encode],[Hack to avoid symbol clash])
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index c6db568..1c589a2 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -506,6 +506,12 @@
 # however, have different variables store. Therefore the nvram is
 # a list of strings when a single item is in form of:
 #   ${PATH_TO_UEFI_FW}:${PATH_TO_UEFI_VARS}.
-# Later, when libvirt creates per domain variable store, this
-# list is searched for the master image.
-#nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" ]
+# Later, when libvirt creates per domain variable store, this list is
+# searched for the master image. The UEFI firmware can be called
+# differently for different guest architectures. For instance, it's OVMF
+# for x86_64 and i686, but it's AAVMF for aarch64. The libvirt default
+# follows this scheme.
+#nvram = [
+#   "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd",
+#   "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd"
+#]
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 9539231..728d01e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -107,13 +107,21 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def)
     VIR_FREE(def);
 }
 
-#define VIR_QEMU_LOADER_FILE_PATH "/usr/share/OVMF/OVMF_CODE.fd"
-#define VIR_QEMU_NVRAM_FILE_PATH "/usr/share/OVMF/OVMF_VARS.fd"
+#define VIR_QEMU_OVMF_LOADER_PATH "/usr/share/AAVMF/AAVMF_CODE.fd"
+#define VIR_QEMU_OVMF_NVRAM_PATH "/usr/share/AAVMF/AAVMF_VARS.fd"
+#define VIR_QEMU_AAVMF_LOADER_PATH "/usr/share/OVMF/OVMF_CODE.fd"
+#define VIR_QEMU_AAVMF_NVRAM_PATH "/usr/share/OVMF/OVMF_VARS.fd"
 
 virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
 {
     virQEMUDriverConfigPtr cfg;
 
+#if defined(DEFAULT_LOADER) && defined(DEFAULT_NVRAM)
+    const char *loader[] = DEFAULT_LOADER;
+    const char *nvram[] = DEFAULT_NVRAM;
+    size_t i;
+#endif
+
     if (virQEMUConfigInitialize() < 0)
         return NULL;
 
@@ -258,14 +266,33 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
 
     cfg->logTimestamp = true;
 
-    if (VIR_ALLOC_N(cfg->loader, 1) < 0 ||
-        VIR_ALLOC_N(cfg->nvram, 1) < 0)
+#if defined(DEFAULT_LOADER) && defined(DEFAULT_NVRAM)
+    verify(ARRAY_CARDINALITY(loader) == ARRAY_CARDINALITY(nvram));
+
+    if (VIR_ALLOC_N(cfg->loader, ARRAY_CARDINALITY(loader)) < 0 ||
+        VIR_ALLOC_N(cfg->nvram, ARRAY_CARDINALITY(loader)) < 0)
+        goto error;
+    cfg->nloader = ARRAY_CARDINALITY(loader);
+
+    for (i = 0; i < ARRAY_CARDINALITY(loader); i++) {
+        if (VIR_STRDUP(cfg->loader[i], loader[i]) < 0 ||
+            VIR_STRDUP(cfg->nvram[i], nvram[i]) < 0)
+            goto error;
+    }
+
+#else /* !defined(DEFAULT_LOADER) || !defined(DEFAULT_NVRAM) */
+
+    if (VIR_ALLOC_N(cfg->loader, 2) < 0 ||
+        VIR_ALLOC_N(cfg->nvram, 2) < 0)
         goto error;
-    cfg->nloader = 1;
+    cfg->nloader = 2;
 
-    if (VIR_STRDUP(cfg->loader[0], VIR_QEMU_LOADER_FILE_PATH) < 0 ||
-        VIR_STRDUP(cfg->nvram[0], VIR_QEMU_NVRAM_FILE_PATH) < 0)
+    if (VIR_STRDUP(cfg->loader[0], VIR_QEMU_OVMF_LOADER_PATH) < 0 ||
+        VIR_STRDUP(cfg->nvram[0], VIR_QEMU_OVMF_NVRAM_PATH) < 0  ||
+        VIR_STRDUP(cfg->loader[1], VIR_QEMU_AAVMF_LOADER_PATH) < 0 ||
+        VIR_STRDUP(cfg->nvram[1], VIR_QEMU_AAVMF_NVRAM_PATH) < 0)
         goto error;
+#endif /* !defined(DEFAULT_LOADER) || !defined(DEFAULT_NVRAM) */
 
     return cfg;
 
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index 30fd27e..fc4935b 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -76,4 +76,5 @@ module Test_libvirtd_qemu =
 { "log_timestamp" = "0" }
 { "nvram"
     { "1" = "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" }
+    { "2" = "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd" }
 }
diff --git a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
index 346ef65..37d2102 100644
--- a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
+++ b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
@@ -5,6 +5,7 @@
   <arch>x86_64</arch>
   <os supported='yes'>
     <loader supported='yes'>
+      <value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
       <value>/usr/share/OVMF/OVMF_CODE.fd</value>
       <enum name='type'>
         <value>rom</value>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 70d2ef3..5ca8928 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -105,6 +105,7 @@ fillQemuCaps(virDomainCapsPtr domCaps,
     struct fillQemuCapsData *data = (struct fillQemuCapsData *) opaque;
     virQEMUCapsPtr qemuCaps = data->qemuCaps;
     virQEMUDriverConfigPtr cfg = data->cfg;
+    virDomainCapsLoaderPtr loader = &domCaps->os.loader;
 
     if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps,
                                   cfg->loader, cfg->nloader) < 0)
@@ -122,14 +123,14 @@ fillQemuCaps(virDomainCapsPtr domCaps,
 
     /* Moreover, as of f05b6a918e28 we are expecting to see
      * OVMF_CODE.fd file which may not exists everywhere. */
-    if (!domCaps->os.loader.values.nvalues) {
-        virDomainCapsLoaderPtr loader = &domCaps->os.loader;
+    while (loader->values.nvalues)
+        VIR_FREE(loader->values.values[--loader->values.nvalues]);
 
-        if (fillStringValues(&loader->values,
-                             "/usr/share/OVMF/OVMF_CODE.fd",
-                             NULL) < 0)
-            return -1;
-    }
+    if (fillStringValues(&loader->values,
+                         "/usr/share/AAVMF/AAVMF_CODE.fd",
+                         "/usr/share/OVMF/OVMF_CODE.fd",
+                         NULL) < 0)
+        return -1;
     return 0;
 }
 #endif /* WITH_QEMU */
-- 
2.0.5




More information about the libvir-list mailing list