]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Add support for controling qemu capabilities via the qemu XML namespace
authorPeter Krempa <pkrempa@redhat.com>
Mon, 17 Jun 2019 15:17:56 +0000 (17:17 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 21 Jun 2019 13:24:06 +0000 (15:24 +0200)
Similarly how we allow adding arbitrary command line arguments and
environment variables this patch introduces the ability to control
libvirt's perception of the qemu process by tweaking the capability bits
for testing purposes.

The idea is to allow developers and users either test a new feature by
enabling it early or disabling it to see whether it introduced
regressions.

This feature is not meant for production use though, so users should
handle it with care.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
docs/drvqemu.html.in
docs/schemas/domaincommon.rng
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
tests/qemuxml2argvdata/qemu-ns.xml

index cf36f6cc7b23ce424fe7280cb8e3c1d41444a8b4..aa61ee5cedea90d44deb6807e8627b5b0e0c5234 100644 (file)
@@ -519,6 +519,36 @@ mount -t cgroup none /dev/cgroup -o devices
     &lt;qemu:env name='QEMU_ENV' value='VAL'/&gt;
   &lt;/qemu:commandline&gt;
 &lt;/domain&gt;
+</pre>
+
+    <h2><a id="xmlnsfeatures">QEMU feature configuration for testing</a></h2>
+
+      <p>
+        In some cases e.g. when developing a new feature or for testing it may
+        be required to control a given qemu feature (or qemu capability) to test
+        it before it's complete or disable it for debugging purposes.
+        <span class="since">Since 5.5.0</span> it's possible to use the same
+        special qemu namespace as above
+        (<code>http://libvirt.org/schemas/domain/qemu/1.0</code>) and use
+        <code>&lt;qemu:capabilities&gt;</code> element to add
+        (<code>&lt;qemu:add capability="capname"/&gt;</code>) or remove
+        (<code>&lt;qemu:del capability="capname"/&gt;</code>) capability bits.
+        The naming of the feature bits is the same libvirt uses in the status
+        XML. Note that this feature is meant for experiments only and should
+        _not_ be used in production.
+      </p>
+
+      <p>Example:</p><pre>
+&lt;domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'&gt;
+  &lt;name&gt;testvm&lt;/name&gt;
+
+   [...]
+
+  &lt;qemu:capabilities&gt;
+    &lt;qemu:add capability='blockdev'/&gt;
+    &lt;qemu:del capability='drive'/&gt;
+  &lt;/qemu:capabilities&gt;
+&lt;/domain&gt;
 </pre>
 
     <h2><a id="xmlconfig">Example domain XML config</a></h2>
index 0f490deecd8f9810e5a26f942571a2bcb806a195..31db599ab9b4dcc8d5c9b8b54401e7ab379c964b 100644 (file)
@@ -72,6 +72,9 @@
         <optional>
           <ref name='qemucmdline'/>
         </optional>
+        <optional>
+          <ref name='qemucapabilities'/>
+        </optional>
         <optional>
           <ref name='lxcsharens'/>
         </optional>
     </element>
   </define>
 
+  <define name="qemucapabilities">
+    <element name="capabilities" ns="http://libvirt.org/schemas/domain/qemu/1.0">
+      <zeroOrMore>
+        <element name="add">
+          <attribute name="capability"/>
+        </element>
+      </zeroOrMore>
+      <zeroOrMore>
+        <element name="del">
+          <attribute name="capability"/>
+        </element>
+      </zeroOrMore>
+    </element>
+  </define>
+
+
   <!--
        Optional hypervisor extensions in their own namespace:
        LXC
index 0144ec61fd3747d390006bef08166633c5e01405..ac19d254ee624c63e41e8a63ab526324befc6761 100644 (file)
@@ -3096,6 +3096,8 @@ qemuDomainXmlNsDefFree(qemuDomainXmlNsDefPtr def)
     virStringListFreeCount(def->args, def->num_args);
     virStringListFreeCount(def->env_name, def->num_env);
     virStringListFreeCount(def->env_value, def->num_env);
+    virStringListFreeCount(def->capsadd, def->ncapsadd);
+    virStringListFreeCount(def->capsdel, def->ncapsdel);
 
     VIR_FREE(def);
 }
@@ -3195,6 +3197,50 @@ qemuDomainDefNamespaceParseCommandlineEnv(qemuDomainXmlNsDefPtr nsdef,
 }
 
 
+static int
+qemuDomainDefNamespaceParseCaps(qemuDomainXmlNsDefPtr nsdef,
+                                xmlXPathContextPtr ctxt)
+{
+    VIR_AUTOFREE(xmlNodePtr *) nodesadd = NULL;
+    ssize_t nnodesadd;
+    VIR_AUTOFREE(xmlNodePtr *) nodesdel = NULL;
+    ssize_t nnodesdel;
+    size_t i;
+
+    if ((nnodesadd = virXPathNodeSet("./qemu:capabilities/qemu:add", ctxt, &nodesadd)) < 0 ||
+        (nnodesdel = virXPathNodeSet("./qemu:capabilities/qemu:del", ctxt, &nodesdel)) < 0)
+        return -1;
+
+    if (nnodesadd > 0) {
+        if (VIR_ALLOC_N(nsdef->capsadd, nnodesadd) < 0)
+            return -1;
+
+        for (i = 0; i < nnodesadd; i++) {
+            if (!(nsdef->capsadd[nsdef->ncapsadd++] = virXMLPropString(nodesadd[i], "capability"))) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("missing capability name"));
+                return -1;
+            }
+        }
+    }
+
+    if (nnodesdel > 0) {
+        if (VIR_ALLOC_N(nsdef->capsdel, nnodesdel) < 0)
+            return -1;
+
+        for (i = 0; i < nnodesdel; i++) {
+            if (!(nsdef->capsdel[nsdef->ncapsdel++] = virXMLPropString(nodesdel[i], "capability"))) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("missing capability name"));
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED,
                             xmlNodePtr root ATTRIBUTE_UNUSED,
@@ -3215,10 +3261,12 @@ qemuDomainDefNamespaceParse(xmlDocPtr xml ATTRIBUTE_UNUSED,
         return -1;
 
     if (qemuDomainDefNamespaceParseCommandlineArgs(nsdata, ctxt) < 0 ||
-        qemuDomainDefNamespaceParseCommandlineEnv(nsdata, ctxt) < 0)
+        qemuDomainDefNamespaceParseCommandlineEnv(nsdata, ctxt) < 0 ||
+        qemuDomainDefNamespaceParseCaps(nsdata, ctxt) < 0)
         goto cleanup;
 
-    if (nsdata->num_args > 0 || nsdata->num_env > 0)
+    if (nsdata->num_args > 0 || nsdata->num_env > 0 ||
+        nsdata->ncapsadd > 0 || nsdata->ncapsdel > 0)
         VIR_STEAL_PTR(*data, nsdata);
 
     ret = 0;
@@ -3256,6 +3304,29 @@ qemuDomainDefNamespaceFormatXMLCommandline(virBufferPtr buf,
 }
 
 
+static void
+qemuDomainDefNamespaceFormatXMLCaps(virBufferPtr buf,
+                                    qemuDomainXmlNsDefPtr xmlns)
+{
+    size_t i;
+
+    if (!xmlns->ncapsadd && !xmlns->ncapsdel)
+        return;
+
+    virBufferAddLit(buf, "<qemu:capabilities>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < xmlns->ncapsadd; i++)
+        virBufferEscapeString(buf, "<qemu:add capability='%s'/>\n", xmlns->capsadd[i]);
+
+    for (i = 0; i < xmlns->ncapsdel; i++)
+        virBufferEscapeString(buf, "<qemu:del capability='%s'/>\n", xmlns->capsdel[i]);
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</qemu:capabilities>\n");
+}
+
+
 static int
 qemuDomainDefNamespaceFormatXML(virBufferPtr buf,
                                 void *nsdata)
@@ -3263,6 +3334,7 @@ qemuDomainDefNamespaceFormatXML(virBufferPtr buf,
     qemuDomainXmlNsDefPtr cmd = nsdata;
 
     qemuDomainDefNamespaceFormatXMLCommandline(buf, cmd);
+    qemuDomainDefNamespaceFormatXMLCaps(buf, cmd);
 
     return 0;
 }
index 3b94f5a97c7462e69766181aabc9bade5805e8fb..5cb4a32c0e2d05e293b861196121a5e3045174af 100644 (file)
@@ -539,6 +539,12 @@ struct _qemuDomainXmlNsDef {
     unsigned int num_env;
     char **env_name;
     char **env_value;
+
+    size_t ncapsadd;
+    char **capsadd;
+
+    size_t ncapsdel;
+    char **capsdel;
 };
 
 
index 62860a683c8b2b5ba391c1b5e6f90a6cab4ae6ce..c1095b3e81fb5713f8cce6bf05c97ee960439c3d 100644 (file)
@@ -27,4 +27,9 @@
     <qemu:env name='NS' value='ns'/>
     <qemu:env name='BAR'/>
   </qemu:commandline>
+  <qemu:capabilities>
+    <qemu:add capability="vnc-colon"/>
+    <qemu:add capability="drive"/>
+    <qemu:del capability="name"/>
+  </qemu:capabilities>
 </domain>