Providing an erroneous CPU definition in the XML file provided to the hypervisor-cpu-compare/baseline command will result in a verbose internal error. Let's add some sanity checking before executing the QMP commands to provide a cleaner message if something is wrong with the CPU model or features. Signed-off-by: Collin Walling <walling@xxxxxxxxxxxxx> --- src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 153b2f2..6298c48 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13703,6 +13703,55 @@ qemuConnectCompareCPU(virConnectPtr conn, } +static int +qemuConnectCheckCPUModel(qemuMonitorPtr mon, + virCPUDefPtr cpu, + bool reportError) +{ + qemuMonitorCPUModelInfoPtr modelInfo = NULL; + qemuMonitorCPUModelExpansionType type; + size_t i, j; + int ret = -1; + + /* Collect CPU model name and features known by QEMU */ + type = QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL; + if (qemuMonitorGetCPUModelExpansion(mon, type, cpu, + true, false, &modelInfo) < 0) + goto cleanup; + + /* Sanity check CPU model */ + if (!modelInfo) { + if (reportError) + virReportError(VIR_ERR_CPU_INCOMPATIBLE, + _("Unknown CPU model: %s"), cpu->model); + goto cleanup; + } + + /* Sanity check CPU features */ + for (i = 0; i < cpu->nfeatures; i++) { + const char *feat = cpu->features[i].name; + + for (j = 0; j < modelInfo->nprops; j++) { + const char *prop = modelInfo->props[j].name; + if (STREQ(feat, prop)) + break; + } + + if (j == modelInfo->nprops) { + if (reportError) + virReportError(VIR_ERR_CPU_INCOMPATIBLE, + _("Unknown CPU feature: %s"), feat); + goto cleanup; + } + } + ret = 0; + + cleanup: + qemuMonitorCPUModelInfoFree(modelInfo); + return ret; +} + + static virCPUCompareResult qemuConnectCPUModelComparison(virQEMUCapsPtr qemuCaps, const char *libDir, @@ -13723,6 +13772,13 @@ qemuConnectCPUModelComparison(virQEMUCapsPtr qemuCaps, if (qemuProcessQMPStart(proc) < 0) goto cleanup; + if (qemuConnectCheckCPUModel(proc->mon, cpu_a, failIncompatible) || + qemuConnectCheckCPUModel(proc->mon, cpu_b, failIncompatible)) { + if (!failIncompatible) + ret = VIR_CPU_COMPARE_INCOMPATIBLE; + goto cleanup; + } + if (qemuMonitorGetCPUModelComparison(proc->mon, cpu_a, cpu_b, &result) < 0) goto cleanup; @@ -13913,6 +13969,9 @@ qemuConnectCPUModelBaseline(virQEMUCapsPtr qemuCaps, if (qemuProcessQMPStart(proc) < 0) goto cleanup; + if (qemuConnectCheckCPUModel(proc->mon, cpus[0], true)) + goto cleanup; + if (VIR_ALLOC(baseline) < 0) goto error; @@ -13921,6 +13980,9 @@ qemuConnectCPUModelBaseline(virQEMUCapsPtr qemuCaps, for (i = 1; i < ncpus; i++) { + if (qemuConnectCheckCPUModel(proc->mon, cpus[i], true)) + goto error; + if (qemuMonitorGetCPUModelBaseline(proc->mon, baseline, cpus[i], &result) < 0) goto error; -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list