was denied */
VIR_ERR_DBUS_SERVICE = 89, /* error from a dbus service */
VIR_ERR_STORAGE_VOL_EXIST = 90, /* the storage vol already exists */
+ VIR_ERR_CPU_INCOMPATIBLE = 91, /* given CPU is incompatible with host
+ CPU*/
} virErrorNumber;
/**
VIR_WARN("cannot get host CPU capabilities");
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else {
- ret = cpuCompareXML(caps->host.cpu, xmlDesc);
+ ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
}
cleanup:
*/
virCPUCompareResult
cpuCompareXML(virCPUDefPtr host,
- const char *xml)
+ const char *xml,
+ bool failIncompatible)
{
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL;
if (cpu == NULL)
goto cleanup;
- ret = cpuCompare(host, cpu);
+ ret = cpuCompare(host, cpu, failIncompatible);
cleanup:
virCPUDefFree(cpu);
*/
virCPUCompareResult
cpuCompare(virCPUDefPtr host,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool failIncompatible)
{
struct cpuArchDriver *driver;
return VIR_CPU_COMPARE_ERROR;
}
- return driver->compare(host, cpu);
+ return driver->compare(host, cpu, failIncompatible);
}
typedef virCPUCompareResult
(*cpuArchCompare) (virCPUDefPtr host,
- virCPUDefPtr cpu);
+ virCPUDefPtr cpu,
+ bool failIncompatible);
typedef int
(*cpuArchDecode) (virCPUDefPtr cpu,
extern virCPUCompareResult
cpuCompareXML(virCPUDefPtr host,
- const char *xml)
+ const char *xml,
+ bool failIncompatible)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern virCPUCompareResult
cpuCompare (virCPUDefPtr host,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool failIncompatible)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern int
static virCPUCompareResult
AArch64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED,
- virCPUDefPtr cpu ATTRIBUTE_UNUSED)
+ virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+ bool failIncompatible ATTRIBUTE_UNUSED)
{
return VIR_CPU_COMPARE_IDENTICAL;
}
static virCPUCompareResult
ArmCompare(virCPUDefPtr host ATTRIBUTE_UNUSED,
- virCPUDefPtr cpu ATTRIBUTE_UNUSED)
+ virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+ bool failMessages ATTRIBUTE_UNUSED)
{
return VIR_CPU_COMPARE_IDENTICAL;
}
static virCPUCompareResult
genericCompare(virCPUDefPtr host,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool failIncompatible)
{
- virHashTablePtr hash;
+ virHashTablePtr hash = NULL;
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
size_t i;
unsigned int reqfeatures;
if ((cpu->arch != VIR_ARCH_NONE &&
host->arch != cpu->arch) ||
- STRNEQ(host->model, cpu->model))
- return VIR_CPU_COMPARE_INCOMPATIBLE;
+ STRNEQ(host->model, cpu->model)) {
+ ret = VIR_CPU_COMPARE_INCOMPATIBLE;
+ goto cleanup;
+ }
if ((hash = genericHashFeatures(host)) == NULL)
goto cleanup;
cleanup:
virHashFree(hash);
+ if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
+ ret = VIR_CPU_COMPARE_ERROR;
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+ }
return ret;
}
static virCPUCompareResult
ppcCompare(virCPUDefPtr host,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool failIncompatible)
{
if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) &&
STREQ(host->model, cpu->model))
return VIR_CPU_COMPARE_IDENTICAL;
- return VIR_CPU_COMPARE_INCOMPATIBLE;
+ if (failIncompatible) {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+ return VIR_CPU_COMPARE_ERROR;
+ } else {
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
}
static int
static virCPUCompareResult
x86Compare(virCPUDefPtr host,
- virCPUDefPtr cpu)
+ virCPUDefPtr cpu,
+ bool failIncomaptible)
{
- return x86Compute(host, cpu, NULL, NULL);
+ virCPUCompareResult ret;
+ char *message = NULL;
+
+ ret = x86Compute(host, cpu, NULL, &message);
+
+ if (failIncomaptible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
+ ret = VIR_CPU_COMPARE_ERROR;
+ if (message) {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message);
+ } else {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+ }
+ }
+ VIR_FREE(message);
+
+ return ret;
}
VIR_WARN("cannot get host CPU capabilities");
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else {
- ret = cpuCompareXML(caps->host.cpu, xmlDesc);
+ ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
}
cleanup:
else
errmsg = _("error from service: %s");
break;
+ case VIR_ERR_CPU_INCOMPATIBLE:
+ if (info == NULL)
+ errmsg = _("the CPU is incompatible with host CPU");
+ else
+ errmsg = _("the CPU is incompatible with host CPU: %s");
+ break;
}
return errmsg;
}
!(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup;
- result = cpuCompare(host, cpu);
+ result = cpuCompare(host, cpu, false);
if (data->result == VIR_CPU_COMPARE_ERROR)
virResetLastError();
for (i = 0; i < ncpus; i++) {
virCPUCompareResult cmp;
- cmp = cpuCompare(cpus[i], baseline);
+ cmp = cpuCompare(cpus[i], baseline, false);
if (cmp != VIR_CPU_COMPARE_SUPERSET &&
cmp != VIR_CPU_COMPARE_IDENTICAL) {
if (virTestGetVerbose()) {