提交 641b8c72 编写于 作者: J Jiri Denemark

Introduce /domain/cpu/@check XML attribute

The attribute can be used to request a specific way of checking whether
the virtual CPU matches created by the hypervisor matches the
specification in domain XML.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 38567e94
...@@ -1247,6 +1247,36 @@ ...@@ -1247,6 +1247,36 @@
<span class="since">Since 0.8.5</span> the <code>match</code> <span class="since">Since 0.8.5</span> the <code>match</code>
attribute can be omitted and will default to <code>exact</code>. attribute can be omitted and will default to <code>exact</code>.
Sometimes the hypervisor is not able to create a virtual CPU exactly
matching the specification passed by libvirt.
<span class="since">Since 3.2.0</span>, an optional <code>check</code>
attribute can be used to request a specific way of checking whether
the virtual CPU matches the specification. It is usually safe to omit
this attribute when starting a domain and stick with the default
value. Once the domain starts, libvirt will automatically change the
<code>check</code> attribute to the best supported value to ensure the
virtual CPU does not change when the domain is migrated to another
host. The following values can be used:
<dl>
<dt><code>none</code></dt>
<dd>Libvirt does no checking and it is up to the hypervisor to
refuse to start the domain if it cannot provide the requested CPU.
With QEMU this means no checking is done at all since the default
behavior of QEMU is to emit warnings, but start the domain anyway.
</dd>
<dt><code>partial</code></dt>
<dd>Libvirt will check the guest CPU specification before starting
a domain, but the rest is left on the hypervisor. It can still
provide a different virtual CPU.</dd>
<dt><code>full</code></dt>
<dd>The virtual CPU created by the hypervisor will be checked
against the CPU specification and the domain will not be started
unless the two CPUs match.</dd>
</dl>
<span class="since">Since 0.9.10</span>, an optional <code>mode</code> <span class="since">Since 0.9.10</span>, an optional <code>mode</code>
attribute may be used to make it easier to configure a guest CPU to be attribute may be used to make it easier to configure a guest CPU to be
as close to host CPU as possible. Possible values for the as close to host CPU as possible. Possible values for the
......
...@@ -23,6 +23,16 @@ ...@@ -23,6 +23,16 @@
</attribute> </attribute>
</define> </define>
<define name="cpuCheck">
<attribute name="check">
<choice>
<value>none</value>
<value>partial</value>
<value>full</value>
</choice>
</attribute>
</define>
<define name="cpuModel"> <define name="cpuModel">
<element name="model"> <element name="model">
<optional> <optional>
......
...@@ -4504,6 +4504,9 @@ ...@@ -4504,6 +4504,9 @@
<optional> <optional>
<ref name="cpuMatch"/> <ref name="cpuMatch"/>
</optional> </optional>
<optional>
<ref name="cpuCheck"/>
</optional>
<interleave> <interleave>
<optional> <optional>
<ref name="cpuModel"/> <ref name="cpuModel"/>
......
...@@ -45,6 +45,12 @@ VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST, ...@@ -45,6 +45,12 @@ VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"exact", "exact",
"strict") "strict")
VIR_ENUM_IMPL(virCPUCheck, VIR_CPU_CHECK_LAST,
"default",
"none",
"partial",
"full")
VIR_ENUM_IMPL(virCPUFallback, VIR_CPU_FALLBACK_LAST, VIR_ENUM_IMPL(virCPUFallback, VIR_CPU_FALLBACK_LAST,
"allow", "allow",
"forbid") "forbid")
...@@ -182,6 +188,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu) ...@@ -182,6 +188,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
copy->type = cpu->type; copy->type = cpu->type;
copy->mode = cpu->mode; copy->mode = cpu->mode;
copy->match = cpu->match; copy->match = cpu->match;
copy->check = cpu->check;
copy->fallback = cpu->fallback; copy->fallback = cpu->fallback;
copy->sockets = cpu->sockets; copy->sockets = cpu->sockets;
copy->cores = cpu->cores; copy->cores = cpu->cores;
...@@ -277,6 +284,7 @@ virCPUDefParseXML(xmlNodePtr node, ...@@ -277,6 +284,7 @@ virCPUDefParseXML(xmlNodePtr node,
if (def->type == VIR_CPU_TYPE_GUEST) { if (def->type == VIR_CPU_TYPE_GUEST) {
char *match = virXMLPropString(node, "match"); char *match = virXMLPropString(node, "match");
char *check;
if (!match) { if (!match) {
if (virXPathBoolean("boolean(./model)", ctxt)) if (virXPathBoolean("boolean(./model)", ctxt))
...@@ -294,6 +302,19 @@ virCPUDefParseXML(xmlNodePtr node, ...@@ -294,6 +302,19 @@ virCPUDefParseXML(xmlNodePtr node,
goto error; goto error;
} }
} }
if ((check = virXMLPropString(node, "check"))) {
int value = virCPUCheckTypeFromString(check);
VIR_FREE(check);
if (value < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Invalid check attribute for CPU "
"specification"));
goto error;
}
def->check = value;
}
} }
if (def->type == VIR_CPU_TYPE_HOST) { if (def->type == VIR_CPU_TYPE_HOST) {
...@@ -532,6 +553,11 @@ virCPUDefFormatBufFull(virBufferPtr buf, ...@@ -532,6 +553,11 @@ virCPUDefFormatBufFull(virBufferPtr buf,
} }
virBufferAsprintf(&attributeBuf, " match='%s'", tmp); virBufferAsprintf(&attributeBuf, " match='%s'", tmp);
} }
if (def->check) {
virBufferAsprintf(&attributeBuf, " check='%s'",
virCPUCheckTypeToString(def->check));
}
} }
/* Format children */ /* Format children */
......
...@@ -63,6 +63,17 @@ typedef enum { ...@@ -63,6 +63,17 @@ typedef enum {
VIR_ENUM_DECL(virCPUMatch) VIR_ENUM_DECL(virCPUMatch)
typedef enum {
VIR_CPU_CHECK_DEFAULT,
VIR_CPU_CHECK_NONE,
VIR_CPU_CHECK_PARTIAL,
VIR_CPU_CHECK_FULL,
VIR_CPU_CHECK_LAST
} virCPUCheck;
VIR_ENUM_DECL(virCPUCheck)
typedef enum { typedef enum {
VIR_CPU_FALLBACK_ALLOW, VIR_CPU_FALLBACK_ALLOW,
VIR_CPU_FALLBACK_FORBID, VIR_CPU_FALLBACK_FORBID,
...@@ -98,6 +109,7 @@ struct _virCPUDef { ...@@ -98,6 +109,7 @@ struct _virCPUDef {
int type; /* enum virCPUType */ int type; /* enum virCPUType */
int mode; /* enum virCPUMode */ int mode; /* enum virCPUMode */
int match; /* enum virCPUMatch */ int match; /* enum virCPUMatch */
virCPUCheck check;
virArch arch; virArch arch;
char *model; char *model;
char *vendor_id; /* vendor id returned by CPUID in the guest */ char *vendor_id; /* vendor id returned by CPUID in the guest */
......
...@@ -4592,6 +4592,24 @@ virDomainVcpuDefPostParse(virDomainDefPtr def) ...@@ -4592,6 +4592,24 @@ virDomainVcpuDefPostParse(virDomainDefPtr def)
} }
static int
virDomainDefPostParseCPU(virDomainDefPtr def)
{
if (!def->cpu)
return 0;
if (def->cpu->mode == VIR_CPU_MODE_CUSTOM &&
!def->cpu->model &&
def->cpu->check != VIR_CPU_CHECK_DEFAULT) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("check attribute specified for CPU with no model"));
return -1;
}
return 0;
}
static int static int
virDomainDefPostParseInternal(virDomainDefPtr def, virDomainDefPostParseInternal(virDomainDefPtr def,
struct virDomainDefPostParseDeviceIteratorData *data) struct virDomainDefPostParseDeviceIteratorData *data)
...@@ -4642,6 +4660,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def, ...@@ -4642,6 +4660,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
virDomainDefPostParseGraphics(def); virDomainDefPostParseGraphics(def);
if (virDomainDefPostParseCPU(def) < 0)
return -1;
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册