提交 b14954fc 编写于 作者: J Jiri Denemark

cpuCompare*: Add support for reporting failure on incompatible CPUs

When CPU comparison APIs return VIR_CPU_COMPARE_INCOMPATIBLE, the caller
has no clue why the CPU is considered incompatible with host CPU. And in
some cases, it would be nice to be able to get such info in a client
rather than having to look in logs.

To achieve this, the APIs can be told to return VIR_ERR_CPU_INCOMPATIBLE
error for incompatible CPUs and the reason will be described in the
associated error message.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 871e64c6
...@@ -300,6 +300,8 @@ typedef enum { ...@@ -300,6 +300,8 @@ typedef enum {
was denied */ was denied */
VIR_ERR_DBUS_SERVICE = 89, /* error from a dbus service */ VIR_ERR_DBUS_SERVICE = 89, /* error from a dbus service */
VIR_ERR_STORAGE_VOL_EXIST = 90, /* the storage vol already exists */ VIR_ERR_STORAGE_VOL_EXIST = 90, /* the storage vol already exists */
VIR_ERR_CPU_INCOMPATIBLE = 91, /* given CPU is incompatible with host
CPU*/
} virErrorNumber; } virErrorNumber;
/** /**
......
...@@ -1332,7 +1332,7 @@ bhyveConnectCompareCPU(virConnectPtr conn, ...@@ -1332,7 +1332,7 @@ bhyveConnectCompareCPU(virConnectPtr conn,
VIR_WARN("cannot get host CPU capabilities"); VIR_WARN("cannot get host CPU capabilities");
ret = VIR_CPU_COMPARE_INCOMPATIBLE; ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else { } else {
ret = cpuCompareXML(caps->host.cpu, xmlDesc); ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
} }
cleanup: cleanup:
......
...@@ -92,7 +92,8 @@ cpuGetSubDriver(virArch arch) ...@@ -92,7 +92,8 @@ cpuGetSubDriver(virArch arch)
*/ */
virCPUCompareResult virCPUCompareResult
cpuCompareXML(virCPUDefPtr host, cpuCompareXML(virCPUDefPtr host,
const char *xml) const char *xml,
bool failIncompatible)
{ {
xmlDocPtr doc = NULL; xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL; xmlXPathContextPtr ctxt = NULL;
...@@ -108,7 +109,7 @@ cpuCompareXML(virCPUDefPtr host, ...@@ -108,7 +109,7 @@ cpuCompareXML(virCPUDefPtr host,
if (cpu == NULL) if (cpu == NULL)
goto cleanup; goto cleanup;
ret = cpuCompare(host, cpu); ret = cpuCompare(host, cpu, failIncompatible);
cleanup: cleanup:
virCPUDefFree(cpu); virCPUDefFree(cpu);
...@@ -134,7 +135,8 @@ cpuCompareXML(virCPUDefPtr host, ...@@ -134,7 +135,8 @@ cpuCompareXML(virCPUDefPtr host,
*/ */
virCPUCompareResult virCPUCompareResult
cpuCompare(virCPUDefPtr host, cpuCompare(virCPUDefPtr host,
virCPUDefPtr cpu) virCPUDefPtr cpu,
bool failIncompatible)
{ {
struct cpuArchDriver *driver; struct cpuArchDriver *driver;
...@@ -156,7 +158,7 @@ cpuCompare(virCPUDefPtr host, ...@@ -156,7 +158,7 @@ cpuCompare(virCPUDefPtr host,
return VIR_CPU_COMPARE_ERROR; return VIR_CPU_COMPARE_ERROR;
} }
return driver->compare(host, cpu); return driver->compare(host, cpu, failIncompatible);
} }
......
...@@ -46,7 +46,8 @@ struct _virCPUData { ...@@ -46,7 +46,8 @@ struct _virCPUData {
typedef virCPUCompareResult typedef virCPUCompareResult
(*cpuArchCompare) (virCPUDefPtr host, (*cpuArchCompare) (virCPUDefPtr host,
virCPUDefPtr cpu); virCPUDefPtr cpu,
bool failIncompatible);
typedef int typedef int
(*cpuArchDecode) (virCPUDefPtr cpu, (*cpuArchDecode) (virCPUDefPtr cpu,
...@@ -119,12 +120,14 @@ struct cpuArchDriver { ...@@ -119,12 +120,14 @@ struct cpuArchDriver {
extern virCPUCompareResult extern virCPUCompareResult
cpuCompareXML(virCPUDefPtr host, cpuCompareXML(virCPUDefPtr host,
const char *xml) const char *xml,
bool failIncompatible)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern virCPUCompareResult extern virCPUCompareResult
cpuCompare (virCPUDefPtr host, cpuCompare (virCPUDefPtr host,
virCPUDefPtr cpu) virCPUDefPtr cpu,
bool failIncompatible)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
extern int extern int
......
...@@ -110,7 +110,8 @@ AArch64Baseline(virCPUDefPtr *cpus, ...@@ -110,7 +110,8 @@ AArch64Baseline(virCPUDefPtr *cpus,
static virCPUCompareResult static virCPUCompareResult
AArch64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED, AArch64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED,
virCPUDefPtr cpu ATTRIBUTE_UNUSED) virCPUDefPtr cpu ATTRIBUTE_UNUSED,
bool failIncompatible ATTRIBUTE_UNUSED)
{ {
return VIR_CPU_COMPARE_IDENTICAL; return VIR_CPU_COMPARE_IDENTICAL;
} }
......
...@@ -113,7 +113,8 @@ ArmBaseline(virCPUDefPtr *cpus, ...@@ -113,7 +113,8 @@ ArmBaseline(virCPUDefPtr *cpus,
static virCPUCompareResult static virCPUCompareResult
ArmCompare(virCPUDefPtr host ATTRIBUTE_UNUSED, ArmCompare(virCPUDefPtr host ATTRIBUTE_UNUSED,
virCPUDefPtr cpu ATTRIBUTE_UNUSED) virCPUDefPtr cpu ATTRIBUTE_UNUSED,
bool failMessages ATTRIBUTE_UNUSED)
{ {
return VIR_CPU_COMPARE_IDENTICAL; return VIR_CPU_COMPARE_IDENTICAL;
} }
......
...@@ -57,17 +57,20 @@ genericHashFeatures(virCPUDefPtr cpu) ...@@ -57,17 +57,20 @@ genericHashFeatures(virCPUDefPtr cpu)
static virCPUCompareResult static virCPUCompareResult
genericCompare(virCPUDefPtr host, genericCompare(virCPUDefPtr host,
virCPUDefPtr cpu) virCPUDefPtr cpu,
bool failIncompatible)
{ {
virHashTablePtr hash; virHashTablePtr hash = NULL;
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
size_t i; size_t i;
unsigned int reqfeatures; unsigned int reqfeatures;
if ((cpu->arch != VIR_ARCH_NONE && if ((cpu->arch != VIR_ARCH_NONE &&
host->arch != cpu->arch) || host->arch != cpu->arch) ||
STRNEQ(host->model, cpu->model)) STRNEQ(host->model, cpu->model)) {
return VIR_CPU_COMPARE_INCOMPATIBLE; ret = VIR_CPU_COMPARE_INCOMPATIBLE;
goto cleanup;
}
if ((hash = genericHashFeatures(host)) == NULL) if ((hash = genericHashFeatures(host)) == NULL)
goto cleanup; goto cleanup;
...@@ -102,6 +105,10 @@ genericCompare(virCPUDefPtr host, ...@@ -102,6 +105,10 @@ genericCompare(virCPUDefPtr host,
cleanup: cleanup:
virHashFree(hash); virHashFree(hash);
if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
ret = VIR_CPU_COMPARE_ERROR;
virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
}
return ret; return ret;
} }
......
...@@ -440,13 +440,19 @@ ppcCompute(virCPUDefPtr host, ...@@ -440,13 +440,19 @@ ppcCompute(virCPUDefPtr host,
static virCPUCompareResult static virCPUCompareResult
ppcCompare(virCPUDefPtr host, ppcCompare(virCPUDefPtr host,
virCPUDefPtr cpu) virCPUDefPtr cpu,
bool failIncompatible)
{ {
if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) && if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) &&
STREQ(host->model, cpu->model)) STREQ(host->model, cpu->model))
return VIR_CPU_COMPARE_IDENTICAL; 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 int
......
...@@ -1463,9 +1463,25 @@ x86Compute(virCPUDefPtr host, ...@@ -1463,9 +1463,25 @@ x86Compute(virCPUDefPtr host,
static virCPUCompareResult static virCPUCompareResult
x86Compare(virCPUDefPtr host, 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;
} }
......
...@@ -11528,7 +11528,7 @@ qemuConnectCompareCPU(virConnectPtr conn, ...@@ -11528,7 +11528,7 @@ qemuConnectCompareCPU(virConnectPtr conn,
VIR_WARN("cannot get host CPU capabilities"); VIR_WARN("cannot get host CPU capabilities");
ret = VIR_CPU_COMPARE_INCOMPATIBLE; ret = VIR_CPU_COMPARE_INCOMPATIBLE;
} else { } else {
ret = cpuCompareXML(caps->host.cpu, xmlDesc); ret = cpuCompareXML(caps->host.cpu, xmlDesc, false);
} }
cleanup: cleanup:
......
...@@ -1277,6 +1277,12 @@ virErrorMsg(virErrorNumber error, const char *info) ...@@ -1277,6 +1277,12 @@ virErrorMsg(virErrorNumber error, const char *info)
else else
errmsg = _("error from service: %s"); errmsg = _("error from service: %s");
break; 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; return errmsg;
} }
......
...@@ -228,7 +228,7 @@ cpuTestCompare(const void *arg) ...@@ -228,7 +228,7 @@ cpuTestCompare(const void *arg)
!(cpu = cpuTestLoadXML(data->arch, data->name))) !(cpu = cpuTestLoadXML(data->arch, data->name)))
goto cleanup; goto cleanup;
result = cpuCompare(host, cpu); result = cpuCompare(host, cpu, false);
if (data->result == VIR_CPU_COMPARE_ERROR) if (data->result == VIR_CPU_COMPARE_ERROR)
virResetLastError(); virResetLastError();
...@@ -357,7 +357,7 @@ cpuTestBaseline(const void *arg) ...@@ -357,7 +357,7 @@ cpuTestBaseline(const void *arg)
for (i = 0; i < ncpus; i++) { for (i = 0; i < ncpus; i++) {
virCPUCompareResult cmp; virCPUCompareResult cmp;
cmp = cpuCompare(cpus[i], baseline); cmp = cpuCompare(cpus[i], baseline, false);
if (cmp != VIR_CPU_COMPARE_SUPERSET && if (cmp != VIR_CPU_COMPARE_SUPERSET &&
cmp != VIR_CPU_COMPARE_IDENTICAL) { cmp != VIR_CPU_COMPARE_IDENTICAL) {
if (virTestGetVerbose()) { if (virTestGetVerbose()) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册