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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list