mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-30 13:37:17 +00:00
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>
|
<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 @@
|
|||||||
</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 @@
|
|||||||
<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,
|
|||||||
"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)
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
|||||||
|
|
||||||
virDomainDefPostParseGraphics(def);
|
virDomainDefPostParseGraphics(def);
|
||||||
|
|
||||||
|
if (virDomainDefPostParseCPU(def) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user