As of 542899168c38 we learned libvirt to use UEFI for domains.
However, management applications may firstly query if libvirt
supports it. And this is where virConnectGetDomainCapabilities()
API comes handy.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
docs/formatdomaincaps.html.in | 40 ++++++++++++++++++++++
docs/schemas/domaincaps.rng | 21 ++++++++++++
src/conf/domain_capabilities.c | 28 +++++++++++++++
src/conf/domain_capabilities.h | 16 +++++++++
src/qemu/qemu_capabilities.c | 38 ++++++++++++++++++++
tests/domaincapsschemadata/domaincaps-basic.xml | 1 +
tests/domaincapsschemadata/domaincaps-full.xml | 13 +++++++
.../domaincaps-qemu_1.6.50-1.xml | 12 +++++++
tests/domaincapstest.c | 8 +++++
9 files changed, 177 insertions(+)
diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 66b6017..34d746d 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -93,6 +93,46 @@
<dd>The maximum number of supported virtual CPUs</dd>
</dl>
+ <h3><a name="elementsOSBIOS">BIOS
bootloader</a></h3>
+
+ <p>Sometimes users might want to tweak some BIOS knobs or use
+ UEFI. For cases like that, <a
+
href="formatdomain.html#elementsOSBIOS"><code>os</code></a>
+ element exposes what values can be passed to its children.</p>
+
+<pre>
+<domainCapabilities>
+ ...
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
+ ...
+<domainCapabilities>
+</pre>
+
+ <p>For the <code>loader</code> element, the following can
occur:</p>
+
+ <dl>
+ <dt>type</dt>
+ <dd>Whether loader is a typical BIOS (<code>rom</code>) or
+ an UEFI binary (<code>pflash</code>). This refers to
+ <code>type</code> attribute of the <loader/>
+ element.</dd>
+
+ <dt>readonly</dt>
+ <dd>Options for the <code>readonly</code> attribute of the
+ <loader/> element.</dd>
+ </dl>
+
<h3><a name="elementsDevices">Devices</a></h3>
<p>
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 627b699..ad8d966 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -26,6 +26,9 @@
<ref name='vcpu'/>
</optional>
<optional>
+ <ref name='os'/>
+ </optional>
+ <optional>
<ref name='devices'/>
</optional>
</interleave>
@@ -41,6 +44,24 @@
</element>
</define>
+ <define name='loader'>
+ <element name='loader'>
+ <ref name='supported'/>
+ <ref name='enum'/>
+ </element>
+ </define>
+
+ <define name='os'>
+ <element name='os'>
+ <interleave>
+ <ref name='supported'/>
+ <optional>
+ <ref name='loader'/>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<define name='devices'>
<element name='devices'>
<interleave>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index df190eb..5a3c8e7 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -178,6 +178,32 @@ virDomainCapsEnumFormat(virBufferPtr buf,
#capsEnum, valToStr); \
} while (0)
+
+static void
+virDomainCapsLoaderFormat(virBufferPtr buf,
+ virDomainCapsLoaderPtr loader)
+{
+ FORMAT_PROLOGUE(loader);
+
+ ENUM_PROCESS(loader, type, virDomainLoaderTypeToString);
+ ENUM_PROCESS(loader, readonly, virTristateBoolTypeToString);
+
+ FORMAT_EPILOGUE(loader);
+}
+
+static void
+virDomainCapsOSFormat(virBufferPtr buf,
+ virDomainCapsOSPtr os)
+{
+ virDomainCapsLoaderPtr loader = &os->loader;
+
+ FORMAT_PROLOGUE(os);
+
+ virDomainCapsLoaderFormat(buf, loader);
+
+ FORMAT_EPILOGUE(os);
+}
+
static void
virDomainCapsDeviceDiskFormat(virBufferPtr buf,
virDomainCapsDeviceDiskPtr const disk)
@@ -225,6 +251,8 @@ virDomainCapsFormatInternal(virBufferPtr buf,
if (caps->maxvcpus)
virBufferAsprintf(buf, "<vcpu max='%d'/>\n",
caps->maxvcpus);
+ virDomainCapsOSFormat(buf, &caps->os);
+
virBufferAddLit(buf, "<devices>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 731e66f..768646b 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -43,6 +43,21 @@ struct _virDomainCapsDevice {
bool supported; /* true if <devtype> is supported by hypervisor */
};
+typedef struct _virDomainCapsLoader virDomainCapsLoader;
+typedef virDomainCapsLoader *virDomainCapsLoaderPtr;
+struct _virDomainCapsLoader {
+ virDomainCapsDevice device;
+ virDomainCapsEnum type; /* Info about virDomainLoader */
+ virDomainCapsEnum readonly; /* Info about readonly:virTristateBool */
+};
+
+typedef struct _virDomainCapsOS virDomainCapsOS;
+typedef virDomainCapsOS *virDomainCapsOSPtr;
+struct _virDomainCapsOS {
+ virDomainCapsDevice device;
+ virDomainCapsLoader loader; /* Info about virDomainLoaderDef */
+};
+
typedef struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk;
typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr;
struct _virDomainCapsDeviceDisk {
@@ -75,6 +90,7 @@ struct _virDomainCaps {
/* Some machine specific info */
int maxvcpus;
+ virDomainCapsOS os;
virDomainCapsDeviceDisk disk;
virDomainCapsDeviceHostdev hostdev;
/* add new domain devices here */
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 81ada48..9f8868d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3609,6 +3609,42 @@ virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
static void
+virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsLoaderPtr loader,
+ virArch arch)
+{
+ loader->device.supported = true;
+
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->type,
+ VIR_DOMAIN_LOADER_TYPE_ROM);
+
+ if (arch == VIR_ARCH_X86_64 &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->type,
+ VIR_DOMAIN_LOADER_TYPE_PFLASH);
+
+
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY))
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->readonly,
+ VIR_TRISTATE_BOOL_YES,
+ VIR_TRISTATE_BOOL_NO);
+}
+
+
+static void
+virQEMUCapsFillDomainOSCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsOSPtr os,
+ virArch arch)
+{
+ virDomainCapsLoaderPtr loader = &os->loader;
+
+ os->device.supported = true;
+ virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch);
+}
+
+
+static void
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
virDomainCapsDeviceDiskPtr disk)
{
@@ -3686,12 +3722,14 @@ void
virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps)
{
+ virDomainCapsOSPtr os = &domCaps->os;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine);
domCaps->maxvcpus = maxvcpus;
+ virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk);
virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev);
}
diff --git a/tests/domaincapsschemadata/domaincaps-basic.xml
b/tests/domaincapsschemadata/domaincaps-basic.xml
index 9963519..6171393 100644
--- a/tests/domaincapsschemadata/domaincaps-basic.xml
+++ b/tests/domaincapsschemadata/domaincaps-basic.xml
@@ -3,6 +3,7 @@
<domain>uml</domain>
<machine>my-machine-type</machine>
<arch>x86_64</arch>
+ <os supported='no'/>
<devices>
<disk supported='no'/>
<hostdev supported='no'/>
diff --git a/tests/domaincapsschemadata/domaincaps-full.xml
b/tests/domaincapsschemadata/domaincaps-full.xml
index 58dd4cb..9722772 100644
--- a/tests/domaincapsschemadata/domaincaps-full.xml
+++ b/tests/domaincapsschemadata/domaincaps-full.xml
@@ -4,6 +4,19 @@
<machine>my-machine-type</machine>
<arch>x86_64</arch>
<vcpu max='255'/>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>default</value>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
index 8b63993..568cecb 100644
--- a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
+++ b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
@@ -3,6 +3,18 @@
<domain>kvm</domain>
<machine>pc-1.2</machine>
<arch>x86_64</arch>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 78197e2..f240643 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -38,10 +38,18 @@ static void
fillAll(virDomainCapsPtr domCaps,
void *opaque ATTRIBUTE_UNUSED)
{
+ virDomainCapsOSPtr os = &domCaps->os;
+ virDomainCapsLoaderPtr loader = &os->loader;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
domCaps->maxvcpus = 255;
+ os->device.supported = true;
+
+ loader->device.supported = true;
+ SET_ALL_BITS(loader->type);
+ SET_ALL_BITS(loader->readonly);
+
disk->device.supported = true;
SET_ALL_BITS(disk->diskDevice);
SET_ALL_BITS(disk->bus);
--
1.8.5.5