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

Martin Kletzander mkletzan at redhat.com
Tue Jan 20 17:20:22 UTC 2015


On Wed, Jan 14, 2015 at 04:28:33PM +0100, Michal Privoznik wrote:
>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}"
>+

This will fail miserably on freebsd and basically everything out there
that's not bash, I guess.  At least for csh and dash this is an
invalid line.

>+    loader_str_c="{"
>+    nvram_str_c="{"
>+    for ((indx=0; indx<${#loader_arr[@]}; indx+=2)); do

Same here.  It's basically not a very good idea to use shell scripts
here, mainly for such operations.

>+        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>

Unrelated to this patch, but under what conditions *should* these
values be formatted?

>       <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]);
>

And my head just went blank in this hunk.  So I'll start from
scratch...

You are filling in the qemu caps for the test so they are consistent
when we are running tests.  What you are changing is that before this
patch the value got filled in only if there was none, but now you are
clearing the whole array.  Since the second approach seems to be the
right one, does that mean that we had an error there before?

Not counting the shell script part it looks fine.

>-        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
>
>--
>libvir-list mailing list
>libvir-list at redhat.com
>https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150120/d4c34487/attachment-0001.sig>


More information about the libvir-list mailing list