domaincaps: Expose UEFI capability

As of 542899168c 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@redhat.com>
This commit is contained in:
Michal Privoznik 2014-09-16 14:47:47 +02:00
parent 865421c94a
commit 4f76621c0e
9 changed files with 177 additions and 0 deletions

View File

@ -93,6 +93,46 @@
<dd>The maximum number of supported virtual CPUs</dd> <dd>The maximum number of supported virtual CPUs</dd>
</dl> </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>
&lt;domainCapabilities&gt;
...
&lt;os supported='yes'&gt;
&lt;loader supported='yes'&gt;
&lt;enum name='type'&gt;
&lt;value&gt;rom&lt;/value&gt;
&lt;value&gt;pflash&lt;/value&gt;
&lt;/enum&gt;
&lt;enum name='readonly'&gt;
&lt;value&gt;yes&lt;/value&gt;
&lt;value&gt;no&lt;/value&gt;
&lt;/enum&gt;
&lt;/loader&gt;
&lt;/os&gt;
...
&lt;domainCapabilities&gt;
</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 &lt;loader/&gt;
element.</dd>
<dt>readonly</dt>
<dd>Options for the <code>readonly</code> attribute of the
&lt;loader/&gt; element.</dd>
</dl>
<h3><a name="elementsDevices">Devices</a></h3> <h3><a name="elementsDevices">Devices</a></h3>
<p> <p>

View File

@ -25,6 +25,9 @@
<optional> <optional>
<ref name='vcpu'/> <ref name='vcpu'/>
</optional> </optional>
<optional>
<ref name='os'/>
</optional>
<optional> <optional>
<ref name='devices'/> <ref name='devices'/>
</optional> </optional>
@ -41,6 +44,24 @@
</element> </element>
</define> </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'> <define name='devices'>
<element name='devices'> <element name='devices'>
<interleave> <interleave>

View File

@ -178,6 +178,32 @@ virDomainCapsEnumFormat(virBufferPtr buf,
#capsEnum, valToStr); \ #capsEnum, valToStr); \
} while (0) } 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 static void
virDomainCapsDeviceDiskFormat(virBufferPtr buf, virDomainCapsDeviceDiskFormat(virBufferPtr buf,
virDomainCapsDeviceDiskPtr const disk) virDomainCapsDeviceDiskPtr const disk)
@ -225,6 +251,8 @@ virDomainCapsFormatInternal(virBufferPtr buf,
if (caps->maxvcpus) if (caps->maxvcpus)
virBufferAsprintf(buf, "<vcpu max='%d'/>\n", caps->maxvcpus); virBufferAsprintf(buf, "<vcpu max='%d'/>\n", caps->maxvcpus);
virDomainCapsOSFormat(buf, &caps->os);
virBufferAddLit(buf, "<devices>\n"); virBufferAddLit(buf, "<devices>\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);

View File

@ -43,6 +43,21 @@ struct _virDomainCapsDevice {
bool supported; /* true if <devtype> is supported by hypervisor */ 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 struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk;
typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr; typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr;
struct _virDomainCapsDeviceDisk { struct _virDomainCapsDeviceDisk {
@ -75,6 +90,7 @@ struct _virDomainCaps {
/* Some machine specific info */ /* Some machine specific info */
int maxvcpus; int maxvcpus;
virDomainCapsOS os;
virDomainCapsDeviceDisk disk; virDomainCapsDeviceDisk disk;
virDomainCapsDeviceHostdev hostdev; virDomainCapsDeviceHostdev hostdev;
/* add new domain devices here */ /* add new domain devices here */

View File

@ -3608,6 +3608,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 static void
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps, virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
virDomainCapsDeviceDiskPtr disk) virDomainCapsDeviceDiskPtr disk)
@ -3686,12 +3722,14 @@ void
virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps, virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps) virQEMUCapsPtr qemuCaps)
{ {
virDomainCapsOSPtr os = &domCaps->os;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk; virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev; virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine); int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine);
domCaps->maxvcpus = maxvcpus; domCaps->maxvcpus = maxvcpus;
virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk); virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk);
virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev); virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev);
} }

View File

@ -3,6 +3,7 @@
<domain>uml</domain> <domain>uml</domain>
<machine>my-machine-type</machine> <machine>my-machine-type</machine>
<arch>x86_64</arch> <arch>x86_64</arch>
<os supported='no'/>
<devices> <devices>
<disk supported='no'/> <disk supported='no'/>
<hostdev supported='no'/> <hostdev supported='no'/>

View File

@ -4,6 +4,19 @@
<machine>my-machine-type</machine> <machine>my-machine-type</machine>
<arch>x86_64</arch> <arch>x86_64</arch>
<vcpu max='255'/> <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> <devices>
<disk supported='yes'> <disk supported='yes'>
<enum name='diskDevice'> <enum name='diskDevice'>

View File

@ -3,6 +3,18 @@
<domain>kvm</domain> <domain>kvm</domain>
<machine>pc-1.2</machine> <machine>pc-1.2</machine>
<arch>x86_64</arch> <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> <devices>
<disk supported='yes'> <disk supported='yes'>
<enum name='diskDevice'> <enum name='diskDevice'>

View File

@ -38,10 +38,18 @@ static void
fillAll(virDomainCapsPtr domCaps, fillAll(virDomainCapsPtr domCaps,
void *opaque ATTRIBUTE_UNUSED) void *opaque ATTRIBUTE_UNUSED)
{ {
virDomainCapsOSPtr os = &domCaps->os;
virDomainCapsLoaderPtr loader = &os->loader;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk; virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev; virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
domCaps->maxvcpus = 255; 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; disk->device.supported = true;
SET_ALL_BITS(disk->diskDevice); SET_ALL_BITS(disk->diskDevice);
SET_ALL_BITS(disk->bus); SET_ALL_BITS(disk->bus);