Spinup QEMU instance and complete QMP query-cpu-model-baseline exchanges to determine CPUModel Baseline. query-cpu-model-baseline only compares two CPUModels so multiple exchanges are needed to evaluate more than two CPUModels. --- src/qemu/qemu_capabilities.c | 132 +++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 9 +++ 2 files changed, 141 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 097985cbe7..9ffbf91a90 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -5122,3 +5122,135 @@ virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps, { qemuCaps->microcodeVersion = microcodeVersion; } + + +/* in: + * <host> + * <cpu> + * <arch>s390x</arch> + * <model>z13-base</model> + * <feature name='xxx'/> + * ... + * <feature name='yyy'/> + * </cpu> + * <cpu> + * <arch>s390x</arch> + * <model>z114-base</model> + * <feature name='xxx'/> + * ... + * <feature name='yyy'/> + * </cpu> + * </host> + * + * out: + * <cpu match='exact'> + * <model>z13-base</model> + * <feature policy='require' name='xxx'/> + * <feature policy='require' name='yyy'/> + * </cpu> + * + * (ret==0) && (baseline.len == 0) if baseline not supported by QEMU + */ +int +virQEMUCapsQMPBaselineCPUModel(char *exec, + const char *libDir, + uid_t runUid, + gid_t runGid, + const char **xmlCPUs, + unsigned int ncpus, + bool migratable, + virBufferPtr baseline) +{ + qemuMonitorCPUModelInfoPtr model_baseline = NULL; + qemuMonitorCPUModelInfoPtr new_model_baseline = NULL; + qemuMonitorCPUModelInfoPtr model_b = NULL; + virQEMUCapsInitQMPCommandPtr cmd = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + bool forceTCG = false; + int ret = -1; + size_t i; + + VIR_DEBUG("ncpus=%i, migratable=%i", ncpus, migratable); + + if (!(cmd = virQEMUCapsSpinUpQemu(exec, libDir, runUid, runGid, forceTCG))) + goto cleanup; + + if (!(cmd->mon)) { + /* Not connected to QEMU (monitor) */ + VIR_DEBUG("QEMU failed to initialize error=%s", virGetLastErrorMessage()); + goto cleanup; + } + + /* QEMU requires qmp_capabilities exchange first */ + if (qemuMonitorSetCapabilities(cmd->mon) < 0) { + VIR_DEBUG("Failed to set monitor capabilities %s", + virGetLastErrorMessage()); + goto cleanup; + } + + if (!xmlCPUs && ncpus != 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("nonzero ncpus doesn't match with NULL xmlCPUs")); + goto cleanup; + } + + if (ncpus < 2) { + virReportError(VIR_ERR_INVALID_ARG, "%s", _("baseline < 2 CPUs ")); + goto cleanup; + } + + if (virQEMUCapsLoadCPUModelInfoFromXMLString(xmlCPUs[0], "//cpu", + &model_baseline) < 0) + goto cleanup; + + VIR_DEBUG("xmlCPUs[0] = %s", xmlCPUs[0]); + + for (i = 1; i < ncpus; i++) { + + VIR_DEBUG("xmlCPUs[%lu] = %s", i, xmlCPUs[i]); + + if (virQEMUCapsLoadCPUModelInfoFromXMLString(xmlCPUs[i], "//cpu", &model_b) < 0) + goto cleanup; + + if (!model_baseline || !model_b) { + virReportError(VIR_ERR_INVALID_ARG, "%s", _("xmlCPU without content")); + goto cleanup; + } + + if (qemuMonitorGetCPUModelBaseline(cmd->mon, model_baseline, + model_b, &new_model_baseline) < 0) + goto cleanup; + + if (!new_model_baseline) { + VIR_DEBUG("QEMU didn't support baseline"); + ret = 0; + goto cleanup; + } + + qemuMonitorCPUModelInfoFree(model_baseline); + qemuMonitorCPUModelInfoFree(model_b); + + model_b = NULL; + + model_baseline = new_model_baseline; + } + + VIR_DEBUG("model_baseline->name = %s", NULLSTR(model_baseline->name)); + + virQEMUCapsCPUModelInfoToXML(model_baseline, &buf); + + if (virBufferUse(&buf)) + virBufferAddBuffer(baseline, &buf); + + ret = 0; + + cleanup: + virQEMUCapsInitQMPCommandFree(cmd); + + qemuMonitorCPUModelInfoFree(model_baseline); + qemuMonitorCPUModelInfoFree(model_b); + + VIR_DEBUG("baseline = %s", virBufferCurrentContent(baseline)); + + return ret; +} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 8da18a8063..2d3e8ce2ad 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -536,6 +536,15 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, const char *machineType); +int virQEMUCapsQMPBaselineCPUModel(char *exec, + const char *libDir, + uid_t runUid, + gid_t runGid, + const char **xmlCPUs, + unsigned int ncpus, + bool migratable, + virBufferPtr baseline); + virFileCachePtr virQEMUCapsCacheNew(const char *libDir, const char *cacheDir, uid_t uid, -- 2.14.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list