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(a)redhat.com>
---
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