mirror of https://gitee.com/openkylin/libvirt.git
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: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
38567e94de
commit
641b8c721e
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue