]> xenbits.xensource.com Git - libvirt.git/commitdiff
domaincaps: Expose UEFI capability
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 16 Sep 2014 12:47:47 +0000 (14:47 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 17 Sep 2014 07:42:33 +0000 (09:42 +0200)
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@redhat.com>
docs/formatdomaincaps.html.in
docs/schemas/domaincaps.rng
src/conf/domain_capabilities.c
src/conf/domain_capabilities.h
src/qemu/qemu_capabilities.c
tests/domaincapsschemadata/domaincaps-basic.xml
tests/domaincapsschemadata/domaincaps-full.xml
tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
tests/domaincapstest.c

index 66b6017742759d870942680815e2c2e47d49a410..34d746dee82f4801253516ecf8a6cbfb6cd69bfc 100644 (file)
       <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>
+&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>
 
     <p>
index 627b69998d47e077054ea167bbb0f34cecfdb0f2..ad8d9664f83a79855885a4277a6ee8c54d3f93c7 100644 (file)
@@ -25,6 +25,9 @@
         <optional>
           <ref name='vcpu'/>
         </optional>
+        <optional>
+          <ref name='os'/>
+        </optional>
         <optional>
           <ref name='devices'/>
         </optional>
     </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>
index df190eb108adb196e7dfaa23bd3438837de0dbb7..5a3c8e71163b49479a0a6fdc85c5dc0e2c11a198 100644 (file)
@@ -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);
 
index 731e66f8a48d35b780f43caddda0d80fde0bbd73..768646b2a8e9bbdaa58b16fcd1a0388ba089c7bd 100644 (file)
@@ -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 */
index 81ada486f10416b3d4a46a66d34d417906758935..9f8868dd7eafdad6ed1e48f31630d5e7e66ece5e 100644 (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
 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);
 }
index 99635199b4f1ca585e0efbe7a5dda1da667df16b..6171393968d9bdbe59fd1c723bb40052d5e28985 100644 (file)
@@ -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'/>
index 58dd4cbdb0f8ed034f8d192aac14e2d10f118fdd..97227726e273f4d3e4ef892470cfa7ffadb1fb90 100644 (file)
@@ -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'>
index 8b63993e511ea085e91b7ca360a27db4c51b18c9..568cecbe9edbc76fdd279486a317bba500aaacdf 100644 (file)
@@ -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'>
index 78197e2350ec249cbb54f311048f66077fca8cca..f240643f2cc9f5f5e1beb05686bd99dab5a49379 100644 (file)
@@ -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);