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@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Sat, May 05, 2018 at 12:48:46 -0500, Chris Venteicher wrote: > 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)) { This test will never be true. > + /* 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; > + } This should be moved inside virQEMUCapsSpinUpQemu. And the rest of the function needs to be changed to work on CPUDefs already parsed by the caller. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.