mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
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: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
871e64c66d
commit
b14954fc12
@ -300,6 +300,8 @@ typedef enum {
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -1332,7 +1332,7 @@ bhyveConnectCompareCPU(virConnectPtr conn,
|
||||
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:
|
||||
|
@ -92,7 +92,8 @@ cpuGetSubDriver(virArch arch)
|
||||
*/
|
||||
virCPUCompareResult
|
||||
cpuCompareXML(virCPUDefPtr host,
|
||||
const char *xml)
|
||||
const char *xml,
|
||||
bool failIncompatible)
|
||||
{
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
@ -108,7 +109,7 @@ cpuCompareXML(virCPUDefPtr host,
|
||||
if (cpu == NULL)
|
||||
goto cleanup;
|
||||
|
||||
ret = cpuCompare(host, cpu);
|
||||
ret = cpuCompare(host, cpu, failIncompatible);
|
||||
|
||||
cleanup:
|
||||
virCPUDefFree(cpu);
|
||||
@ -134,7 +135,8 @@ cpuCompareXML(virCPUDefPtr host,
|
||||
*/
|
||||
virCPUCompareResult
|
||||
cpuCompare(virCPUDefPtr host,
|
||||
virCPUDefPtr cpu)
|
||||
virCPUDefPtr cpu,
|
||||
bool failIncompatible)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
@ -156,7 +158,7 @@ cpuCompare(virCPUDefPtr host,
|
||||
return VIR_CPU_COMPARE_ERROR;
|
||||
}
|
||||
|
||||
return driver->compare(host, cpu);
|
||||
return driver->compare(host, cpu, failIncompatible);
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,8 @@ struct _virCPUData {
|
||||
|
||||
typedef virCPUCompareResult
|
||||
(*cpuArchCompare) (virCPUDefPtr host,
|
||||
virCPUDefPtr cpu);
|
||||
virCPUDefPtr cpu,
|
||||
bool failIncompatible);
|
||||
|
||||
typedef int
|
||||
(*cpuArchDecode) (virCPUDefPtr cpu,
|
||||
@ -119,12 +120,14 @@ struct cpuArchDriver {
|
||||
|
||||
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
|
||||
|
@ -110,7 +110,8 @@ AArch64Baseline(virCPUDefPtr *cpus,
|
||||
|
||||
static virCPUCompareResult
|
||||
AArch64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED,
|
||||
virCPUDefPtr cpu ATTRIBUTE_UNUSED)
|
||||
virCPUDefPtr cpu ATTRIBUTE_UNUSED,
|
||||
bool failIncompatible ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return VIR_CPU_COMPARE_IDENTICAL;
|
||||
}
|
||||
|
@ -113,7 +113,8 @@ ArmBaseline(virCPUDefPtr *cpus,
|
||||
|
||||
static virCPUCompareResult
|
||||
ArmCompare(virCPUDefPtr host ATTRIBUTE_UNUSED,
|
||||
virCPUDefPtr cpu ATTRIBUTE_UNUSED)
|
||||
virCPUDefPtr cpu ATTRIBUTE_UNUSED,
|
||||
bool failMessages ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return VIR_CPU_COMPARE_IDENTICAL;
|
||||
}
|
||||
|
@ -57,17 +57,20 @@ genericHashFeatures(virCPUDefPtr cpu)
|
||||
|
||||
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;
|
||||
@ -102,6 +105,10 @@ genericCompare(virCPUDefPtr host,
|
||||
|
||||
cleanup:
|
||||
virHashFree(hash);
|
||||
if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
|
||||
ret = VIR_CPU_COMPARE_ERROR;
|
||||
virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -440,13 +440,19 @@ ppcCompute(virCPUDefPtr host,
|
||||
|
||||
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
|
||||
|
@ -1463,9 +1463,25 @@ x86Compute(virCPUDefPtr host,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -11528,7 +11528,7 @@ qemuConnectCompareCPU(virConnectPtr conn,
|
||||
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:
|
||||
|
@ -1277,6 +1277,12 @@ virErrorMsg(virErrorNumber error, const char *info)
|
||||
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;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ cpuTestCompare(const void *arg)
|
||||
!(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();
|
||||
|
||||
@ -357,7 +357,7 @@ cpuTestBaseline(const void *arg)
|
||||
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()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user