|
|
6ae9ed |
From c9fb2f1ef7a756909c705df0c6a323af826be139 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <c9fb2f1ef7a756909c705df0c6a323af826be139@dist-git>
|
|
|
6ae9ed |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
6ae9ed |
Date: Wed, 24 Aug 2016 16:11:33 -0400
|
|
|
6ae9ed |
Subject: [PATCH] conf: Add XML for individual vCPU hotplug
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
|
|
|
6ae9ed |
|
|
|
6ae9ed |
Individual vCPU hotplug requires us to track the state of any vCPU. To
|
|
|
6ae9ed |
allow this add the following XML:
|
|
|
6ae9ed |
|
|
|
6ae9ed |
<domain>
|
|
|
6ae9ed |
...
|
|
|
6ae9ed |
<vcpu current='2'>3</vcpu>
|
|
|
6ae9ed |
<vcpus>
|
|
|
6ae9ed |
<vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>
|
|
|
6ae9ed |
<vcpu id='1' enabled='yes' hotpluggable='yes' order='2'/>
|
|
|
6ae9ed |
<vcpu id='1' enabled='no' hotpluggable='yes'/>
|
|
|
6ae9ed |
</vcpus>
|
|
|
6ae9ed |
...
|
|
|
6ae9ed |
|
|
|
6ae9ed |
The 'enabled' attribute allows to control the state of the vcpu.
|
|
|
6ae9ed |
'hotpluggable' controls whether given vcpu can be hotplugged and 'order'
|
|
|
6ae9ed |
allows to specify the order to add the vcpus.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit 5847bc5c64f205a2f00315a2434e8a7bd48c5508)
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
docs/formatdomain.html.in | 40 ++++++
|
|
|
6ae9ed |
docs/schemas/domaincommon.rng | 25 ++++
|
|
|
6ae9ed |
src/conf/domain_conf.c | 154 ++++++++++++++++++++-
|
|
|
6ae9ed |
src/conf/domain_conf.h | 6 +
|
|
|
6ae9ed |
src/qemu/qemu_domain.c | 11 +-
|
|
|
6ae9ed |
.../generic-vcpus-individual.xml | 23 +++
|
|
|
6ae9ed |
tests/genericxml2xmltest.c | 2 +
|
|
|
6ae9ed |
tests/testutils.c | 4 +-
|
|
|
6ae9ed |
8 files changed, 261 insertions(+), 4 deletions(-)
|
|
|
6ae9ed |
create mode 100644 tests/genericxml2xmlindata/generic-vcpus-individual.xml
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
|
|
|
6ae9ed |
index b74057f..252f91c 100644
|
|
|
6ae9ed |
--- a/docs/formatdomain.html.in
|
|
|
6ae9ed |
+++ b/docs/formatdomain.html.in
|
|
|
6ae9ed |
@@ -489,6 +489,10 @@
|
|
|
6ae9ed |
<domain>
|
|
|
6ae9ed |
...
|
|
|
6ae9ed |
<vcpu placement='static' cpuset="1-4,^3,6" current="1">2</vcpu>
|
|
|
6ae9ed |
+ <vcpus>
|
|
|
6ae9ed |
+ <vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>
|
|
|
6ae9ed |
+ <vcpu id='1' enabled='no' hotpluggable='yes'/>
|
|
|
6ae9ed |
+ </vcpus>
|
|
|
6ae9ed |
...
|
|
|
6ae9ed |
</domain>
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -542,6 +546,42 @@
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ vcpus
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ The vcpus element allows to control state of individual vcpus.
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ The id attribute specifies the vCPU id as used by libvirt
|
|
|
6ae9ed |
+ in other places such as vcpu pinning, scheduler information and NUMA
|
|
|
6ae9ed |
+ assignment. Note that the vcpu ID as seen in the guest may differ from
|
|
|
6ae9ed |
+ libvirt ID in certain cases. Valid IDs are from 0 to the maximum vcpu
|
|
|
6ae9ed |
+ count as set by the vcpu element minus 1.
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ The enabled attribute allows to control the state of the
|
|
|
6ae9ed |
+ vcpu. Valid values are yes and no .
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ hotpluggable controls whether given vcpu can be hotplugged
|
|
|
6ae9ed |
+ and hotunplugged in cases when the cpu is enabled at boot. Note that
|
|
|
6ae9ed |
+ all disabled vcpus must be hotpluggable. Valid values are
|
|
|
6ae9ed |
+ yes and no .
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ order allows to specify the order to add the vcpus. For
|
|
|
6ae9ed |
+ hypervisors/platforms that require to insert multiple vcpus at once
|
|
|
6ae9ed |
+ the order may be be duplicated accross all vcpus that need to be
|
|
|
6ae9ed |
+ enabled at once. Specifying order is not necessary, vcpus are then
|
|
|
6ae9ed |
+ added in an arbitrary order.
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ Note that hypervisors may create hotpluggable vcpus differently from
|
|
|
6ae9ed |
+ boot vcpus thus special initialization may be necessary.
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ Hypervisors may require that vcpus enabled on boot which are not
|
|
|
6ae9ed |
+ hotpluggable are clustered at the beginning starting with ID 0. It may
|
|
|
6ae9ed |
+ be also required that vcpu 0 is always present and non-hotpluggable.
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ Note that providing state for individual cpus may be necessary to enable
|
|
|
6ae9ed |
+ support of addressable vCPU hotplug and this feature may not be
|
|
|
6ae9ed |
+ supported by all hypervisors.
|
|
|
6ae9ed |
+ Since 2.2.0 (QEMU only)
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
|
|
6ae9ed |
index 497597c..bf4d795 100644
|
|
|
6ae9ed |
--- a/docs/schemas/domaincommon.rng
|
|
|
6ae9ed |
+++ b/docs/schemas/domaincommon.rng
|
|
|
6ae9ed |
@@ -583,6 +583,31 @@
|
|
|
6ae9ed |
</optional>
|
|
|
6ae9ed |
|
|
|
6ae9ed |
<optional>
|
|
|
6ae9ed |
+ <element name="vcpus">
|
|
|
6ae9ed |
+ <zeroOrMore>
|
|
|
6ae9ed |
+ <element name="vcpu">
|
|
|
6ae9ed |
+ <attribute name="id">
|
|
|
6ae9ed |
+ <ref name="unsignedInt"/>
|
|
|
6ae9ed |
+ </attribute>
|
|
|
6ae9ed |
+ <attribute name="enabled">
|
|
|
6ae9ed |
+ <ref name="virYesNo"/>
|
|
|
6ae9ed |
+ </attribute>
|
|
|
6ae9ed |
+ <optional>
|
|
|
6ae9ed |
+ <attribute name="hotpluggable">
|
|
|
6ae9ed |
+ <ref name="virYesNo"/>
|
|
|
6ae9ed |
+ </attribute>
|
|
|
6ae9ed |
+ </optional>
|
|
|
6ae9ed |
+ <optional>
|
|
|
6ae9ed |
+ <attribute name="order">
|
|
|
6ae9ed |
+ <ref name="unsignedInt"/>
|
|
|
6ae9ed |
+ </attribute>
|
|
|
6ae9ed |
+ </optional>
|
|
|
6ae9ed |
+ </element>
|
|
|
6ae9ed |
+ </zeroOrMore>
|
|
|
6ae9ed |
+ </element>
|
|
|
6ae9ed |
+ </optional>
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ <optional>
|
|
|
6ae9ed |
<element name="iothreads">
|
|
|
6ae9ed |
<ref name="unsignedInt"/>
|
|
|
6ae9ed |
</element>
|
|
|
6ae9ed |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
6ae9ed |
index 4e703d9..d3a0400 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_conf.c
|
|
|
6ae9ed |
+++ b/src/conf/domain_conf.c
|
|
|
6ae9ed |
@@ -4425,6 +4425,13 @@ virDomainDefPostParseCheckFeatures(virDomainDefPtr def,
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (UNSUPPORTED(VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS) &&
|
|
|
6ae9ed |
+ def->individualvcpus) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
6ae9ed |
+ _("individual CPU state configuration is not supported"));
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
return 0;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -4499,6 +4506,43 @@ virDomainDefPostParseDeviceIterator(virDomainDefPtr def,
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
static int
|
|
|
6ae9ed |
+virDomainVcpuDefPostParse(virDomainDefPtr def)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ virDomainVcpuDefPtr vcpu;
|
|
|
6ae9ed |
+ size_t maxvcpus = virDomainDefGetVcpusMax(def);
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < maxvcpus; i++) {
|
|
|
6ae9ed |
+ vcpu = virDomainDefGetVcpu(def, i);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ switch (vcpu->hotpluggable) {
|
|
|
6ae9ed |
+ case VIR_TRISTATE_BOOL_ABSENT:
|
|
|
6ae9ed |
+ if (vcpu->online)
|
|
|
6ae9ed |
+ vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
|
|
|
6ae9ed |
+ else
|
|
|
6ae9ed |
+ vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ case VIR_TRISTATE_BOOL_NO:
|
|
|
6ae9ed |
+ if (!vcpu->online) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
6ae9ed |
+ _("vcpu '%zu' is both offline and not "
|
|
|
6ae9ed |
+ "hotpluggable"), i);
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ case VIR_TRISTATE_BOOL_YES:
|
|
|
6ae9ed |
+ case VIR_TRISTATE_BOOL_LAST:
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ return 0;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
virDomainDefPostParseInternal(virDomainDefPtr def,
|
|
|
6ae9ed |
struct virDomainDefPostParseDeviceIteratorData *data)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
@@ -4509,6 +4553,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (virDomainVcpuDefPostParse(def) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
if (virDomainDefPostParseMemory(def, data->parseFlags) < 0)
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -15590,6 +15637,8 @@ virDomainVcpuParse(virDomainDefPtr def,
|
|
|
6ae9ed |
virDomainXMLOptionPtr xmlopt)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
int n;
|
|
|
6ae9ed |
+ xmlNodePtr *nodes = NULL;
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
char *tmp = NULL;
|
|
|
6ae9ed |
unsigned int maxvcpus;
|
|
|
6ae9ed |
unsigned int vcpus;
|
|
|
6ae9ed |
@@ -15618,8 +15667,6 @@ virDomainVcpuParse(virDomainDefPtr def,
|
|
|
6ae9ed |
vcpus = maxvcpus;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- if (virDomainDefSetVcpus(def, vcpus) < 0)
|
|
|
6ae9ed |
- goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
tmp = virXPathString("string(./vcpu[1]/@placement)", ctxt);
|
|
|
6ae9ed |
if (tmp) {
|
|
|
6ae9ed |
@@ -15651,9 +15698,82 @@ virDomainVcpuParse(virDomainDefPtr def,
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if ((n = virXPathNodeSet("./vcpus/vcpu", ctxt, &nodes)) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (n) {
|
|
|
6ae9ed |
+ /* if individual vcpu states are provided take them as master */
|
|
|
6ae9ed |
+ def->individualvcpus = true;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < n; i++) {
|
|
|
6ae9ed |
+ virDomainVcpuDefPtr vcpu;
|
|
|
6ae9ed |
+ int state;
|
|
|
6ae9ed |
+ unsigned int id;
|
|
|
6ae9ed |
+ unsigned int order;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(tmp = virXMLPropString(nodes[i], "id")) ||
|
|
|
6ae9ed |
+ virStrToLong_uip(tmp, NULL, 10, &id) < 0) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
6ae9ed |
+ _("missing or invalid vcpu id"));
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_FREE(tmp);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (id >= def->maxvcpus) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
6ae9ed |
+ _("vcpu id '%u' is out of range of maximum "
|
|
|
6ae9ed |
+ "vcpu count"), id);
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ vcpu = virDomainDefGetVcpu(def, id);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(tmp = virXMLPropString(nodes[i], "enabled"))) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
6ae9ed |
+ _("missing vcpu enabled state"));
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if ((state = virTristateBoolTypeFromString(tmp)) < 0) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
6ae9ed |
+ _("invalid vcpu 'enabled' value '%s'"), tmp);
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ VIR_FREE(tmp);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ vcpu->online = state == VIR_TRISTATE_BOOL_YES;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if ((tmp = virXMLPropString(nodes[i], "hotpluggable"))) {
|
|
|
6ae9ed |
+ int hotpluggable;
|
|
|
6ae9ed |
+ if ((hotpluggable = virTristateBoolTypeFromString(tmp)) < 0) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
6ae9ed |
+ _("invalid vcpu 'hotpluggable' value '%s'"), tmp);
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ vcpu->hotpluggable = hotpluggable;
|
|
|
6ae9ed |
+ VIR_FREE(tmp);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if ((tmp = virXMLPropString(nodes[i], "order"))) {
|
|
|
6ae9ed |
+ if (virStrToLong_uip(tmp, NULL, 10, &order) < 0) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
6ae9ed |
+ _("invalid vcpu order"));
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ vcpu->order = order;
|
|
|
6ae9ed |
+ VIR_FREE(tmp);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ } else {
|
|
|
6ae9ed |
+ if (virDomainDefSetVcpus(def, vcpus) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
cleanup:
|
|
|
6ae9ed |
+ VIR_FREE(nodes);
|
|
|
6ae9ed |
VIR_FREE(tmp);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return ret;
|
|
|
6ae9ed |
@@ -18679,6 +18799,13 @@ virDomainDefVcpuCheckAbiStability(virDomainDefPtr src,
|
|
|
6ae9ed |
"destination definitions"), i);
|
|
|
6ae9ed |
return false;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (svcpu->order != dvcpu->order) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
6ae9ed |
+ _("vcpu enable order of vCPU '%zu' differs between "
|
|
|
6ae9ed |
+ "source and destination definitions"), i);
|
|
|
6ae9ed |
+ return false;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return true;
|
|
|
6ae9ed |
@@ -22921,6 +23048,8 @@ static int
|
|
|
6ae9ed |
virDomainCpuDefFormat(virBufferPtr buf,
|
|
|
6ae9ed |
const virDomainDef *def)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
+ virDomainVcpuDefPtr vcpu;
|
|
|
6ae9ed |
+ size_t i;
|
|
|
6ae9ed |
char *cpumask = NULL;
|
|
|
6ae9ed |
int ret = -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -22937,6 +23066,27 @@ virDomainCpuDefFormat(virBufferPtr buf,
|
|
|
6ae9ed |
virBufferAsprintf(buf, " current='%u'", virDomainDefGetVcpus(def));
|
|
|
6ae9ed |
virBufferAsprintf(buf, ">%u</vcpu>\n", virDomainDefGetVcpusMax(def));
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (def->individualvcpus) {
|
|
|
6ae9ed |
+ virBufferAddLit(buf, "<vcpus>\n");
|
|
|
6ae9ed |
+ virBufferAdjustIndent(buf, 2);
|
|
|
6ae9ed |
+ for (i = 0; i < def->maxvcpus; i++) {
|
|
|
6ae9ed |
+ vcpu = def->vcpus[i];
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ virBufferAsprintf(buf, "
|
|
|
6ae9ed |
+ i, vcpu->online ? "yes" : "no");
|
|
|
6ae9ed |
+ if (vcpu->hotpluggable)
|
|
|
6ae9ed |
+ virBufferAsprintf(buf, " hotpluggable='%s'",
|
|
|
6ae9ed |
+ virTristateBoolTypeToString(vcpu->hotpluggable));
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (vcpu->order != 0)
|
|
|
6ae9ed |
+ virBufferAsprintf(buf, " order='%d'", vcpu->order);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ virBufferAddLit(buf, "/>\n");
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ virBufferAdjustIndent(buf, -2);
|
|
|
6ae9ed |
+ virBufferAddLit(buf, "</vcpus>\n");
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
cleanup:
|
|
|
6ae9ed |
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|
|
6ae9ed |
index e7ff401..34da54c 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_conf.h
|
|
|
6ae9ed |
+++ b/src/conf/domain_conf.h
|
|
|
6ae9ed |
@@ -2040,6 +2040,9 @@ typedef virDomainVcpuDef *virDomainVcpuDefPtr;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
struct _virDomainVcpuDef {
|
|
|
6ae9ed |
bool online;
|
|
|
6ae9ed |
+ virTristateBool hotpluggable;
|
|
|
6ae9ed |
+ unsigned int order;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
virBitmapPtr cpumask;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
virDomainThreadSchedParam sched;
|
|
|
6ae9ed |
@@ -2136,6 +2139,8 @@ struct _virDomainDef {
|
|
|
6ae9ed |
|
|
|
6ae9ed |
virDomainVcpuDefPtr *vcpus;
|
|
|
6ae9ed |
size_t maxvcpus;
|
|
|
6ae9ed |
+ /* set if the vcpu definition was specified individually */
|
|
|
6ae9ed |
+ bool individualvcpus;
|
|
|
6ae9ed |
int placement_mode;
|
|
|
6ae9ed |
virBitmapPtr cpumask;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -2338,6 +2343,7 @@ typedef enum {
|
|
|
6ae9ed |
VIR_DOMAIN_DEF_FEATURE_MEMORY_HOTPLUG = (1 << 1),
|
|
|
6ae9ed |
VIR_DOMAIN_DEF_FEATURE_OFFLINE_VCPUPIN = (1 << 2),
|
|
|
6ae9ed |
VIR_DOMAIN_DEF_FEATURE_NAME_SLASH = (1 << 3),
|
|
|
6ae9ed |
+ VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS = (1 << 4),
|
|
|
6ae9ed |
} virDomainDefFeatures;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
index add8379..7a71bfb 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain.c
|
|
|
6ae9ed |
@@ -5796,8 +5796,17 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
VIR_STEAL_PTR(vcpupriv->alias, info[i].alias);
|
|
|
6ae9ed |
vcpupriv->enable_id = info[i].id;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
- if (hotplug && state)
|
|
|
6ae9ed |
+ if (hotplug && state) {
|
|
|
6ae9ed |
vcpu->online = !!info[i].qom_path;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* mark cpus that don't have an alias as non-hotpluggable */
|
|
|
6ae9ed |
+ if (vcpu->online) {
|
|
|
6ae9ed |
+ if (vcpupriv->alias)
|
|
|
6ae9ed |
+ vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
|
|
|
6ae9ed |
+ else
|
|
|
6ae9ed |
+ vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
ret = 0;
|
|
|
6ae9ed |
diff --git a/tests/genericxml2xmlindata/generic-vcpus-individual.xml b/tests/genericxml2xmlindata/generic-vcpus-individual.xml
|
|
|
6ae9ed |
new file mode 100644
|
|
|
6ae9ed |
index 0000000..cbcf8fd
|
|
|
6ae9ed |
--- /dev/null
|
|
|
6ae9ed |
+++ b/tests/genericxml2xmlindata/generic-vcpus-individual.xml
|
|
|
6ae9ed |
@@ -0,0 +1,23 @@
|
|
|
6ae9ed |
+<domain type='qemu'>
|
|
|
6ae9ed |
+ <name>foobar</name>
|
|
|
6ae9ed |
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
|
6ae9ed |
+ <memory unit='KiB'>219136</memory>
|
|
|
6ae9ed |
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
|
6ae9ed |
+ <vcpu placement='static' current='2'>4</vcpu>
|
|
|
6ae9ed |
+ <vcpus>
|
|
|
6ae9ed |
+ <vcpu id='0' enabled='no' hotpluggable='yes' order='1'/>
|
|
|
6ae9ed |
+ <vcpu id='1' enabled='yes' hotpluggable='no'/>
|
|
|
6ae9ed |
+ <vcpu id='2' enabled='no' hotpluggable='yes' order='2'/>
|
|
|
6ae9ed |
+ <vcpu id='3' enabled='yes' hotpluggable='no'/>
|
|
|
6ae9ed |
+ </vcpus>
|
|
|
6ae9ed |
+ <os>
|
|
|
6ae9ed |
+ <type arch='i686' machine='pc'>hvm</type>
|
|
|
6ae9ed |
+ <boot dev='hd'/>
|
|
|
6ae9ed |
+ </os>
|
|
|
6ae9ed |
+ <clock offset='utc'/>
|
|
|
6ae9ed |
+ <on_poweroff>destroy</on_poweroff>
|
|
|
6ae9ed |
+ <on_reboot>restart</on_reboot>
|
|
|
6ae9ed |
+ <on_crash>destroy</on_crash>
|
|
|
6ae9ed |
+ <devices>
|
|
|
6ae9ed |
+ </devices>
|
|
|
6ae9ed |
+</domain>
|
|
|
6ae9ed |
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
|
|
|
6ae9ed |
index a487727..2ea2396 100644
|
|
|
6ae9ed |
--- a/tests/genericxml2xmltest.c
|
|
|
6ae9ed |
+++ b/tests/genericxml2xmltest.c
|
|
|
6ae9ed |
@@ -97,6 +97,8 @@ mymain(void)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
DO_TEST("perf");
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ DO_TEST("vcpus-individual");
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
virObjectUnref(caps);
|
|
|
6ae9ed |
virObjectUnref(xmlopt);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/tests/testutils.c b/tests/testutils.c
|
|
|
6ae9ed |
index be61e4d..2daad43 100644
|
|
|
6ae9ed |
--- a/tests/testutils.c
|
|
|
6ae9ed |
+++ b/tests/testutils.c
|
|
|
6ae9ed |
@@ -1075,7 +1075,9 @@ virCapsPtr virTestGenericCapsInit(void)
|
|
|
6ae9ed |
return NULL;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
-static virDomainDefParserConfig virTestGenericDomainDefParserConfig;
|
|
|
6ae9ed |
+static virDomainDefParserConfig virTestGenericDomainDefParserConfig = {
|
|
|
6ae9ed |
+ .features = VIR_DOMAIN_DEF_FEATURE_INDIVIDUAL_VCPUS,
|
|
|
6ae9ed |
+};
|
|
|
6ae9ed |
static virDomainXMLPrivateDataCallbacks virTestGenericPrivateDataCallbacks;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
virDomainXMLOptionPtr virTestGenericDomainXMLConfInit(void)
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.10.0
|
|
|
6ae9ed |
|