<domainCapabilities>
...
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/OVMF/OVMF_CODE.fd</value>
<enum name='type'>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
</loader>
</os>
...
<domainCapabilities>
</pre>
+ <p>The <code>firmware</code> enum corresponds to
+ <code>firmware</code> attribute of the <code>os</code> element.
+ Plain presence of this enum means that libvirt is capable of so
+ called firmware auto selection. The listed values then represent
+ accepted values for the domain attribute. Only values for which
+ there exists a firmware descriptor that matches machine type and
+ architecture are listed, i.e. those which won't cause a failure
+ on domain startup.
+ </p>
+
<p>For the <code>loader</code> element, the following can occur:</p>
<dl>
<dt><code>readonly</code></dt>
<dd>Options for the <code>readonly</code> attribute of the
<loader/> element.</dd>
+
+ <dt><code>secure</code></dt>
+ <dd>Options for the <code>secure</code> attribute of the
+ <loader/> element. Note, that <code>yes</code> is listed
+ only if there is a firmware that supports it.</dd>
</dl>
<h3><a id="elementsCPU">CPU configuration</a></h3>
<element name='os'>
<interleave>
<ref name='supported'/>
+ <ref name='enum'/>
<optional>
<ref name='loader'/>
</optional>
virDomainCapsStringValuesFormat(buf, &loader->values);
ENUM_PROCESS(loader, type, virDomainLoaderTypeToString);
ENUM_PROCESS(loader, readonly, virTristateBoolTypeToString);
+ ENUM_PROCESS(loader, secure, virTristateBoolTypeToString);
FORMAT_EPILOGUE(loader);
}
FORMAT_PROLOGUE(os);
+ ENUM_PROCESS(os, firmware, virDomainOsDefFirmwareTypeToString);
+
virDomainCapsLoaderFormat(buf, loader);
FORMAT_EPILOGUE(os);
virDomainCapsStringValues values; /* Info about values for the element */
virDomainCapsEnum type; /* Info about virDomainLoader */
virDomainCapsEnum readonly; /* Info about readonly:virTristateBool */
+ virDomainCapsEnum secure; /* Info about secure:virTristateBool */
};
typedef struct _virDomainCapsOS virDomainCapsOS;
typedef virDomainCapsOS *virDomainCapsOSPtr;
struct _virDomainCapsOS {
virTristateBool supported;
+ virDomainCapsEnum firmware; /* Info about virDomainOsDefFirmware */
virDomainCapsLoader loader; /* Info about virDomainLoaderDef */
};
#include "qemu_capspriv.h"
#include "qemu_qapi.h"
#include "qemu_process.h"
+#include "qemu_firmware.h"
#include <fcntl.h>
#include <sys/stat.h>
static int
virQEMUCapsFillDomainLoaderCaps(virDomainCapsLoaderPtr capsLoader,
+ bool secure,
virFirmwarePtr *firmwares,
size_t nfirmwares)
{
capsLoader->supported = VIR_TRISTATE_BOOL_YES;
capsLoader->type.report = true;
capsLoader->readonly.report = true;
+ capsLoader->secure.report = true;
if (VIR_ALLOC_N(capsLoader->values.values, nfirmwares) < 0)
return -1;
VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->readonly,
VIR_TRISTATE_BOOL_YES,
VIR_TRISTATE_BOOL_NO);
+
+ VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->secure,
+ VIR_TRISTATE_BOOL_NO);
+
+ if (secure)
+ VIR_DOMAIN_CAPS_ENUM_SET(capsLoader->secure,
+ VIR_TRISTATE_BOOL_YES);
+
return 0;
}
static int
virQEMUCapsFillDomainOSCaps(virDomainCapsOSPtr os,
+ const char *machine,
+ virArch arch,
+ bool privileged,
virFirmwarePtr *firmwares,
size_t nfirmwares)
{
virDomainCapsLoaderPtr capsLoader = &os->loader;
+ uint64_t autoFirmwares = 0;
+ bool secure = false;
os->supported = VIR_TRISTATE_BOOL_YES;
- if (virQEMUCapsFillDomainLoaderCaps(capsLoader, firmwares, nfirmwares) < 0)
+ os->firmware.report = true;
+
+ if (qemuFirmwareGetSupported(machine, arch, privileged, &autoFirmwares, &secure) < 0)
+ return -1;
+
+ if (autoFirmwares & (1ULL << VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS))
+ VIR_DOMAIN_CAPS_ENUM_SET(os->firmware, VIR_DOMAIN_OS_DEF_FIRMWARE_BIOS);
+ if (autoFirmwares & (1ULL << VIR_DOMAIN_OS_DEF_FIRMWARE_EFI))
+ VIR_DOMAIN_CAPS_ENUM_SET(os->firmware, VIR_DOMAIN_OS_DEF_FIRMWARE_EFI);
+
+ if (virQEMUCapsFillDomainLoaderCaps(capsLoader, secure, firmwares, nfirmwares) < 0)
return -1;
return 0;
}
virQEMUCapsFillDomainCaps(virCapsPtr caps,
virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps,
+ bool privileged,
virFirmwarePtr *firmwares,
size_t nfirmwares)
{
domCaps->genid = virTristateBoolFromBool(
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMGENID));
- if (virQEMUCapsFillDomainOSCaps(os, firmwares, nfirmwares) < 0 ||
+ if (virQEMUCapsFillDomainOSCaps(os,
+ domCaps->machine,
+ domCaps->arch,
+ privileged,
+ firmwares, nfirmwares) < 0 ||
virQEMUCapsFillDomainCPUCaps(caps, qemuCaps, domCaps) < 0 ||
virQEMUCapsFillDomainIOThreadCaps(qemuCaps, domCaps) < 0 ||
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps,
int virQEMUCapsFillDomainCaps(virCapsPtr caps,
virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps,
+ bool privileged,
virFirmwarePtr *firmwares,
size_t nfirmwares);
goto cleanup;
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
+ driver->privileged,
cfg->firmwares, cfg->nfirmwares) < 0)
goto cleanup;
domaincapsmock_la_LIBADD = $(MOCKLIBS_LIBS)
domaincapstest_SOURCES = \
- domaincapstest.c testutils.h testutils.c
+ domaincapstest.c testutils.h testutils.c \
+ virfilewrapper.c virfilewrapper.h \
+ $(NULL)
domaincapstest_LDADD = $(LDADDS)
if WITH_QEMU
<vcpu max='255'/>
<iothreads supported='no'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='1024'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='248'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='1'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='248'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='248'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='288'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='248'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'/>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
<vcpu max='255'/>
<iothreads supported='yes'/>
<os supported='yes'>
+ <enum name='firmware'>
+ <value>bios</value>
+ <value>efi</value>
+ </enum>
<loader supported='yes'>
<value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
<value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
<value>yes</value>
<value>no</value>
</enum>
+ <enum name='secure'>
+ <value>no</value>
+ </enum>
</loader>
</os>
<cpu>
#include "testutils.h"
#include "domain_capabilities.h"
+#include "virfilewrapper.h"
+#include "configmake.h"
#define VIR_FROM_THIS VIR_FROM_NONE
goto cleanup;
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
+ false,
cfg->firmwares,
cfg->nfirmwares) < 0)
goto cleanup;
#if WITH_QEMU
+ virFileWrapperAddPrefix(SYSCONFDIR "/qemu/firmware",
+ abs_srcdir "/qemufirmwaredata/etc/qemu/firmware");
+ virFileWrapperAddPrefix(PREFIX "/share/qemu/firmware",
+ abs_srcdir "/qemufirmwaredata/usr/share/qemu/firmware");
+ virFileWrapperAddPrefix("/home/user/.config/qemu/firmware",
+ abs_srcdir "/qemufirmwaredata/home/user/.config/qemu/firmware");
+
DO_TEST_QEMU("1.7.0", "caps_1.7.0",
"/usr/bin/qemu-system-x86_64", NULL,
"x86_64", VIR_DOMAIN_VIRT_KVM);
"x86_64", VIR_DOMAIN_VIRT_KVM);
virObjectUnref(cfg);
+ virFileWrapperRemovePrefix(SYSCONFDIR "/qemu/firmware");
+ virFileWrapperRemovePrefix(PREFIX "/share/qemu/firmware");
+ virFileWrapperRemovePrefix("/home/user/.config/qemu/firmware");
+
#endif /* WITH_QEMU */
#if WITH_LIBXL
DO_TEST_BHYVE("fbuf", "/usr/sbin/bhyve", &bhyve_caps, VIR_DOMAIN_VIRT_BHYVE);
#endif /* WITH_BHYVE */
+ virFileWrapperClearPrefixes();
+
return ret;
}