The new VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE flag for virConnectCompareCPU can be used to get an error (VIR_ERR_CPU_INCOMPATIBLE) describing the incompatibility instead of the usual VIR_CPU_COMPARE_INCOMPATIBLE return code. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- include/libvirt/libvirt.h.in | 5 +++++ src/bhyve/bhyve_driver.c | 17 +++++++++++++---- src/libvirt.c | 9 +++++++-- src/qemu/qemu_driver.c | 17 +++++++++++++---- tools/virsh-domain.c | 11 +++++++++-- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 3f7a201..594521e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4122,6 +4122,11 @@ typedef enum { #endif } virCPUCompareResult; +typedef enum { + VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE = (1 << 0), /* treat incompatible + CPUs as failure */ +} virConnectCompareCPUFlags; + int virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags); diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 9bece84..d784ed1 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1318,21 +1318,30 @@ bhyveConnectCompareCPU(virConnectPtr conn, bhyveConnPtr driver = conn->privateData; int ret = VIR_CPU_COMPARE_ERROR; virCapsPtr caps = NULL; + bool failIncompatible; - virCheckFlags(0, VIR_CPU_COMPARE_ERROR); + virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE, + VIR_CPU_COMPARE_ERROR); if (virConnectCompareCPUEnsureACL(conn) < 0) goto cleanup; + failIncomaptible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE); + if (!(caps = bhyveDriverGetCapabilities(driver))) goto cleanup; if (!caps->host.cpu || !caps->host.cpu->model) { - VIR_WARN("cannot get host CPU capabilities"); - ret = VIR_CPU_COMPARE_INCOMPATIBLE; + if (failIncomaptible) { + virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", + _("cannot get host CPU capabilities")); + } else { + VIR_WARN("cannot get host CPU capabilities"); + ret = VIR_CPU_COMPARE_INCOMPATIBLE; + } } else { - ret = cpuCompareXML(caps->host.cpu, xmlDesc, false); + ret = cpuCompareXML(caps->host.cpu, xmlDesc, failIncomaptible); } cleanup: diff --git a/src/libvirt.c b/src/libvirt.c index a0cdfa2..48ce225 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -17245,11 +17245,16 @@ virConnectIsSecure(virConnectPtr conn) * virConnectCompareCPU: * @conn: virConnect connection * @xmlDesc: XML describing the CPU to compare with host CPU - * @flags: extra flags; not used yet, so callers should always pass 0 + * @flags: bitwise-OR of virConnectCompareCPUFlags * * Compares the given CPU description with the host CPU * - * Returns comparison result according to enum virCPUCompareResult + * Returns comparison result according to enum virCPUCompareResult. If + * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is + * incompatible with host CPU, this function will return VIR_CPU_COMPARE_ERROR + * (instead of VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use + * VIR_ERR_CPU_INCOMPATIBLE code the error message will provide more details + * about the incompatibility. */ int virConnectCompareCPU(virConnectPtr conn, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3c23fc7..d8cecff 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -11514,21 +11514,30 @@ qemuConnectCompareCPU(virConnectPtr conn, virQEMUDriverPtr driver = conn->privateData; int ret = VIR_CPU_COMPARE_ERROR; virCapsPtr caps = NULL; + bool failIncomaptible; - virCheckFlags(0, VIR_CPU_COMPARE_ERROR); + virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE, + VIR_CPU_COMPARE_ERROR); if (virConnectCompareCPUEnsureACL(conn) < 0) goto cleanup; + failIncomaptible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE); + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; if (!caps->host.cpu || !caps->host.cpu->model) { - VIR_WARN("cannot get host CPU capabilities"); - ret = VIR_CPU_COMPARE_INCOMPATIBLE; + if (failIncomaptible) { + virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", + _("cannot get host CPU capabilities")); + } else { + VIR_WARN("cannot get host CPU capabilities"); + ret = VIR_CPU_COMPARE_INCOMPATIBLE; + } } else { - ret = cpuCompareXML(caps->host.cpu, xmlDesc, false); + ret = cpuCompareXML(caps->host.cpu, xmlDesc, failIncomaptible); } cleanup: diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 0ae1538..f55dae4 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6214,6 +6214,10 @@ static const vshCmdOptDef opts_cpu_compare[] = { .flags = VSH_OFLAG_REQ, .help = N_("file containing an XML CPU description") }, + {.name = "error", + .type = VSH_OT_BOOL, + .help = N_("report error if CPUs are incompatible") + }, {.name = NULL} }; @@ -6225,11 +6229,14 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) char *buffer; int result; char *snippet = NULL; - + unsigned int flags = 0; xmlDocPtr xml = NULL; xmlXPathContextPtr ctxt = NULL; xmlNodePtr node; + if (vshCommandOptBool(cmd, "error")) + flags |= VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE; + if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) return false; @@ -6253,7 +6260,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - result = virConnectCompareCPU(ctl->conn, snippet, 0); + result = virConnectCompareCPU(ctl->conn, snippet, flags); switch (result) { case VIR_CPU_COMPARE_INCOMPATIBLE: -- 2.0.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list