提交 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 @@
<span class="since">Since 0.8.5</span> the <code>match</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>
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
......
......@@ -23,6 +23,16 @@
</attribute>
</define>
<define name="cpuCheck">
<attribute name="check">
<choice>
<value>none</value>
<value>partial</value>
<value>full</value>
</choice>
</attribute>
</define>
<define name="cpuModel">
<element name="model">
<optional>
......
......@@ -4504,6 +4504,9 @@
<optional>
<ref name="cpuMatch"/>
</optional>
<optional>
<ref name="cpuCheck"/>
</optional>
<interleave>
<optional>
<ref name="cpuModel"/>
......
......@@ -45,6 +45,12 @@ VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
"exact",
"strict")
VIR_ENUM_IMPL(virCPUCheck, VIR_CPU_CHECK_LAST,
"default",
"none",
"partial",
"full")
VIR_ENUM_IMPL(virCPUFallback, VIR_CPU_FALLBACK_LAST,
"allow",
"forbid")
......@@ -182,6 +188,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
copy->type = cpu->type;
copy->mode = cpu->mode;
copy->match = cpu->match;
copy->check = cpu->check;
copy->fallback = cpu->fallback;
copy->sockets = cpu->sockets;
copy->cores = cpu->cores;
......@@ -277,6 +284,7 @@ virCPUDefParseXML(xmlNodePtr node,
if (def->type == VIR_CPU_TYPE_GUEST) {
char *match = virXMLPropString(node, "match");
char *check;
if (!match) {
if (virXPathBoolean("boolean(./model)", ctxt))
......@@ -294,6 +302,19 @@ virCPUDefParseXML(xmlNodePtr node,
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) {
......@@ -532,6 +553,11 @@ virCPUDefFormatBufFull(virBufferPtr buf,
}
virBufferAsprintf(&attributeBuf, " match='%s'", tmp);
}
if (def->check) {
virBufferAsprintf(&attributeBuf, " check='%s'",
virCPUCheckTypeToString(def->check));
}
}
/* Format children */
......
......@@ -63,6 +63,17 @@ typedef enum {
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 {
VIR_CPU_FALLBACK_ALLOW,
VIR_CPU_FALLBACK_FORBID,
......@@ -98,6 +109,7 @@ struct _virCPUDef {
int type; /* enum virCPUType */
int mode; /* enum virCPUMode */
int match; /* enum virCPUMatch */
virCPUCheck check;
virArch arch;
char *model;
char *vendor_id; /* vendor id returned by CPUID in the guest */
......
......@@ -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
virDomainDefPostParseInternal(virDomainDefPtr def,
struct virDomainDefPostParseDeviceIteratorData *data)
......@@ -4642,6 +4660,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
virDomainDefPostParseGraphics(def);
if (virDomainDefPostParseCPU(def) < 0)
return -1;
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册