On Thu, Oct 01, 2026 at 22:36:25 -0400, Rorie Reyes wrote:
Add a new internal qemuCPUModelCompatResult enum to qemu_process.h with values for IDENTICAL, SUBSET, SUPERSET, INCOMPATIBLE, and ERROR, and a new shared helper qemuProcessCPUModelComparison() in qemu_process.c that wraps the QMP probe and maps the result string to the enum.
Refactor qemuConnectCPUModelComparison() in qemu_driver.c to delegate to the new helper, eliminating the duplicated QMP probe boilerplate.
Instead of reusing internals from qemuConnectCPUModelComparison in other places, I think we should incorporate the function inside qemuDomainCheckCPU. Or rather rename qemuDomainCheckCPU to emphasise it is x86 specific, create similar function for s390 and call them both from qemuDomainCheckCPU and adapt qemuConnectCompareHypervisorCPU to use only this new function. See my reply to the last patch for details.
qemuConnectCPUModelComparison() maps the internal enum back to virCPUCompareResult, treating SUBSET as VIR_CPU_COMPARE_INCOMPATIBLE to preserve existing public API behaviour.
Signed-off-by: Rorie Reyes <rreyes@linux.ibm.com> --- src/qemu/qemu_driver.c | 20 +++++++---------- src/qemu/qemu_process.c | 50 +++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.h | 21 +++++++++++++++++ 3 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7332ec0256..56a254f0ec 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12127,25 +12127,21 @@ qemuConnectCPUModelComparison(virQEMUCaps *qemuCaps, virCPUDef *cpu_b, bool failIncompatible) { - g_autoptr(qemuProcessQMP) proc = NULL; - g_autofree char *result = NULL; - - if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps), - libDir, runUid, runGid, false))) - return VIR_CPU_COMPARE_ERROR; - - if (qemuProcessQMPStart(proc) < 0) - return VIR_CPU_COMPARE_ERROR; + qemuCPUModelCompatResult cmp = + qemuProcessCPUModelComparison(qemuCaps, libDir, runUid, runGid, + cpu_a, cpu_b, NULL);
- if (qemuMonitorGetCPUModelComparison(proc->mon, cpu_a, cpu_b, &result, NULL) < 0) + if (cmp == QEMU_CPU_COMPAT_ERROR) return VIR_CPU_COMPARE_ERROR;
- if (STREQ(result, "identical")) + if (cmp == QEMU_CPU_COMPAT_IDENTICAL) return VIR_CPU_COMPARE_IDENTICAL;
- if (STREQ(result, "superset")) + if (cmp == QEMU_CPU_COMPAT_SUPERSET) return VIR_CPU_COMPARE_SUPERSET;
Hmm, this is the kind of refactoring I suggested in my reply to the first patch. I'd just push it a few layers down directly to the monitor code.
+ /* cpu_a is the host. SUBSET means the host lacks features the guest + * needs — treat as incompatible, same as INCOMPATIBLE. */ if (failIncompatible) { virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); return VIR_CPU_COMPARE_ERROR; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 57a3ed3720..90b8acc6c2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c ... @@ -10583,6 +10591,48 @@ qemuProcessQMPStart(qemuProcessQMP *proc) }
+qemuCPUModelCompatResult +qemuProcessCPUModelComparison(virQEMUCaps *qemuCaps, + const char *libDir, + uid_t runUid, + gid_t runGid, + virCPUDef *cpu_a, + virCPUDef *cpu_b, + char ***responsibleProps) +{
...
+ switch (compatResult) { + case QEMU_CPU_COMPAT_INCOMPATIBLE: + case QEMU_CPU_COMPAT_IDENTICAL: + case QEMU_CPU_COMPAT_SUPERSET: + case QEMU_CPU_COMPAT_SUBSET: + return compatResult; + case QEMU_CPU_COMPAT_ERROR: + case QEMU_CPU_COMPAT_LAST: + default: + VIR_WARN("unknown query-cpu-model-comparison result '%s', treating as incompatible", + result); + return QEMU_CPU_COMPAT_INCOMPATIBLE; + }
No matter how you finally end up decoding the strings to the enum, unknown results from query-cpu-model-comparison should be properly reported as errors. Jirka