The qemu-cpu-model-comparison QMP command can return a
"responsible-properties" array identifying which CPU properties
caused an incompatibility result.  Expose this through the JSON
monitor layer by adding an optional `responsibleProps` output
parameter (char ***) to qemuMonitorJSONGetCPUModelComparison() and
its public wrapper qemuMonitorGetCPUModelComparison().

When the caller passes a non-NULL pointer the array is populated
from the QMP response; passing NULL preserves the existing
behaviour.  The existing caller in qemuConnectCPUModelComparison()
is updated to pass NULL so the build continues to work.

Signed-off-by: Rorie Reyes <[email protected]>
---
 src/qemu/qemu_driver.c       |  2 +-
 src/qemu/qemu_monitor.c      |  8 +++++---
 src/qemu/qemu_monitor.h      |  3 ++-
 src/qemu/qemu_monitor_json.c | 15 ++++++++++++++-
 src/qemu/qemu_monitor_json.h |  3 ++-
 tests/qemumonitorjsontest.c  |  8 ++++----
 6 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2500b6fb50..199eedca36 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12137,7 +12137,7 @@ qemuConnectCPUModelComparison(virQEMUCaps *qemuCaps,
     if (qemuProcessQMPStart(proc) < 0)
         return VIR_CPU_COMPARE_ERROR;
 
-    result = qemuMonitorGetCPUModelComparison(proc->mon, cpu_a, cpu_b);
+    result = qemuMonitorGetCPUModelComparison(proc->mon, cpu_a, cpu_b, NULL);
 
     if (result == VIR_CPU_COMPARE_ERROR)
         return VIR_CPU_COMPARE_ERROR;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 265890922f..915ab7c10f 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3329,13 +3329,15 @@ qemuMonitorGetCPUModelBaseline(qemuMonitor *mon,
 virCPUCompareResult
 qemuMonitorGetCPUModelComparison(qemuMonitor *mon,
                                  virCPUDef *cpu_a,
-                                 virCPUDef *cpu_b)
+                                 virCPUDef *cpu_b,
+                                 char ***responsibleProps)
 {
-    VIR_DEBUG("cpu_a=%p cpu_b=%p", cpu_a, cpu_b);
+    VIR_DEBUG("cpu_a=%p cpu_b=%p responsibleProps=%p", cpu_a, cpu_b, 
responsibleProps);
 
     QEMU_CHECK_MONITOR_FULL(mon, return VIR_CPU_COMPARE_ERROR);
 
-    return qemuMonitorJSONGetCPUModelComparison(mon, cpu_a, cpu_b);
+    return qemuMonitorJSONGetCPUModelComparison(mon, cpu_a, cpu_b,
+                                                responsibleProps);
 }
 
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c94cfc2b35..f14bd9e04b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1486,7 +1486,8 @@ qemuMonitorGetCPUModelBaseline(qemuMonitor *mon,
 virCPUCompareResult
 qemuMonitorGetCPUModelComparison(qemuMonitor *mon,
                                  virCPUDef *cpu_a,
-                                 virCPUDef *cpu_b);
+                                 virCPUDef *cpu_b,
+                                 char ***responsibleProps);
 
 qemuMonitorCPUModelInfo *
 qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index a8932af43c..5dec049479 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5689,7 +5689,8 @@ qemuMonitorJSONGetCPUModelBaseline(qemuMonitor *mon,
 virCPUCompareResult
 qemuMonitorJSONGetCPUModelComparison(qemuMonitor *mon,
                                      virCPUDef *cpu_a,
-                                     virCPUDef *cpu_b)
+                                     virCPUDef *cpu_b,
+                                     char ***responsibleProps)
 {
     g_autoptr(virJSONValue) model_a = NULL;
     g_autoptr(virJSONValue) model_b = NULL;
@@ -5697,6 +5698,10 @@ qemuMonitorJSONGetCPUModelComparison(qemuMonitor *mon,
     g_autoptr(virJSONValue) reply = NULL;
     const char *result;
     virJSONValue *data;
+    virJSONValue *propsArray;
+
+    if (responsibleProps)
+        *responsibleProps = NULL;
 
     if (!(model_a = qemuMonitorJSONMakeCPUModel(cpu_a, true, false)) ||
         !(model_b = qemuMonitorJSONMakeCPUModel(cpu_b, true, false)))
@@ -5722,6 +5727,14 @@ qemuMonitorJSONGetCPUModelComparison(qemuMonitor *mon,
         return VIR_CPU_COMPARE_ERROR;
     }
 
+    propsArray = virJSONValueObjectGetArray(data, "responsible-properties");
+
+    if (responsibleProps && propsArray &&
+        virJSONValueArraySize(propsArray) > 0 &&
+        !(*responsibleProps = virJSONValueArrayToStringList(propsArray))) {
+        return VIR_CPU_COMPARE_ERROR;
+    }
+
     if (STREQ(result, "identical"))
         return VIR_CPU_COMPARE_IDENTICAL;
 
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index e5d3d5d99e..ebee30036a 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -442,7 +442,8 @@ qemuMonitorJSONGetCPUModelBaseline(qemuMonitor *mon,
 virCPUCompareResult
 qemuMonitorJSONGetCPUModelComparison(qemuMonitor *mon,
                                      virCPUDef *cpu_a,
-                                     virCPUDef *cpu_b)
+                                     virCPUDef *cpu_b,
+                                     char ***responsibleProps)
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
 GHashTable *
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index b00d4512d1..db44a725ee 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -2661,7 +2661,7 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelComparison(const void *opaque)
             return -1;
 
         if 
(qemuMonitorJSONGetCPUModelComparison(qemuMonitorTestGetMonitor(test),
-                                                 cpu_a, cpu_b) != 
VIR_CPU_COMPARE_IDENTICAL) {
+                                                 cpu_a, cpu_b, NULL) != 
VIR_CPU_COMPARE_IDENTICAL) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            "unexpected result for 'identical'");
             return -1;
@@ -2675,7 +2675,7 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelComparison(const void *opaque)
             return -1;
 
         if 
(qemuMonitorJSONGetCPUModelComparison(qemuMonitorTestGetMonitor(test),
-                                                 cpu_a, cpu_b) != 
VIR_CPU_COMPARE_SUPERSET) {
+                                                 cpu_a, cpu_b, NULL) != 
VIR_CPU_COMPARE_SUPERSET) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            "unexpected result for 'superset'");
             return -1;
@@ -2689,7 +2689,7 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelComparison(const void *opaque)
             return -1;
 
         if 
(qemuMonitorJSONGetCPUModelComparison(qemuMonitorTestGetMonitor(test),
-                                                 cpu_a, cpu_b) != 
VIR_CPU_COMPARE_INCOMPATIBLE) {
+                                                 cpu_a, cpu_b, NULL) != 
VIR_CPU_COMPARE_INCOMPATIBLE) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            "unexpected result for 'subset'");
             return -1;
@@ -2703,7 +2703,7 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelComparison(const void *opaque)
             return -1;
 
         if 
(qemuMonitorJSONGetCPUModelComparison(qemuMonitorTestGetMonitor(test),
-                                                 cpu_a, cpu_b) != 
VIR_CPU_COMPARE_INCOMPATIBLE) {
+                                                 cpu_a, cpu_b, NULL) != 
VIR_CPU_COMPARE_INCOMPATIBLE) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            "unexpected result for 'incompatible'");
             return -1;
-- 
2.48.1

Reply via email to