mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
qemu: Add support for controling qemu capabilities via the qemu XML namespace
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>
This commit is contained in:
parent
ca62170e8c
commit
c6da5913d9
@ -519,6 +519,36 @@ mount -t cgroup none /dev/cgroup -o devices
|
||||
<qemu:env name='QEMU_ENV' value='VAL'/>
|
||||
</qemu:commandline>
|
||||
</domain>
|
||||
</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><qemu:capabilities></code> element to add
|
||||
(<code><qemu:add capability="capname"/></code>) or remove
|
||||
(<code><qemu:del capability="capname"/></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>
|
||||
<domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
|
||||
<name>testvm</name>
|
||||
|
||||
[...]
|
||||
|
||||
<qemu:capabilities>
|
||||
<qemu:add capability='blockdev'/>
|
||||
<qemu:del capability='drive'/>
|
||||
</qemu:capabilities>
|
||||
</domain>
|
||||
</pre>
|
||||
|
||||
<h2><a id="xmlconfig">Example domain XML config</a></h2>
|
||||
|
@ -72,6 +72,9 @@
|
||||
<optional>
|
||||
<ref name='qemucmdline'/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name='qemucapabilities'/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name='lxcsharens'/>
|
||||
</optional>
|
||||
@ -6197,6 +6200,22 @@
|
||||
</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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user