]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu_driver: hook up query-cpu-model-baseline
authorCollin Walling <walling@linux.ibm.com>
Thu, 19 Sep 2019 20:25:00 +0000 (16:25 -0400)
committerJiri Denemark <jdenemar@redhat.com>
Mon, 7 Oct 2019 08:10:11 +0000 (10:10 +0200)
This command is hooked into the virsh hypervisor-cpu-baseline command.
The CPU models provided in the XML sent to the command will be baselined
via the query-cpu-model-baseline QMP command. The resulting CPU model
will be reported.

Signed-off-by: Collin Walling <walling@linux.ibm.com>
Reviewed-by: Daniel Henrique Barboza <danielh413@gmail.com>
Message-Id: <1568924706-2311-10-git-send-email-walling@linux.ibm.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
src/qemu/qemu_driver.c

index 95fe844c34590f4db0666115dc77adfcc33bd681..5daa4b3f829a632a07fc79b16805a2e6a0e7dfca 100644 (file)
@@ -13739,6 +13739,90 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
 }
 
 
+/**
+ * qemuConnectStealCPUModelFromInfo:
+ *
+ * Consumes @src and replaces the content of @dst with CPU model name and
+ * features from @src. When this function returns (both with success or
+ * failure), @src is freed.
+ */
+static int
+qemuConnectStealCPUModelFromInfo(virCPUDefPtr dst,
+                                 qemuMonitorCPUModelInfoPtr *src)
+{
+    qemuMonitorCPUModelInfoPtr info;
+    size_t i;
+    int ret = -1;
+
+    virCPUDefFreeModel(dst);
+
+    VIR_STEAL_PTR(info, *src);
+    VIR_STEAL_PTR(dst->model, info->name);
+
+    for (i = 0; i < info->nprops; i++) {
+        char *name = info->props[i].name;
+
+        if (info->props[i].type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN ||
+            !info->props[i].value.boolean)
+            continue;
+
+        if (virCPUDefAddFeature(dst, name, VIR_CPU_FEATURE_REQUIRE) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    qemuMonitorCPUModelInfoFree(info);
+    return ret;
+}
+
+
+static virCPUDefPtr
+qemuConnectCPUModelBaseline(virQEMUCapsPtr qemuCaps,
+                            const char *libDir,
+                            uid_t runUid,
+                            gid_t runGid,
+                            virCPUDefPtr *cpus,
+                            int ncpus)
+{
+    qemuProcessQMPPtr proc;
+    virCPUDefPtr ret = NULL;
+    virCPUDefPtr baseline = NULL;
+    qemuMonitorCPUModelInfoPtr result = NULL;
+    size_t i;
+
+    if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps),
+                                   libDir, runUid, runGid, false)))
+        goto cleanup;
+
+    if (qemuProcessQMPStart(proc) < 0)
+        goto cleanup;
+
+    if (VIR_ALLOC(baseline) < 0)
+        goto cleanup;
+
+    if (virCPUDefCopyModel(baseline, cpus[0], false))
+        goto cleanup;
+
+    for (i = 1; i < ncpus; i++) {
+        if (qemuMonitorGetCPUModelBaseline(proc->mon, baseline,
+                                           cpus[i], &result) < 0)
+            goto cleanup;
+
+        if (qemuConnectStealCPUModelFromInfo(baseline, &result) < 0)
+            goto cleanup;
+    }
+
+    VIR_STEAL_PTR(ret, baseline);
+
+ cleanup:
+    qemuProcessQMPFree(proc);
+    virCPUDefFree(baseline);
+    return ret;
+}
+
+
 static char *
 qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
                                  const char *emulator,
@@ -13750,6 +13834,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
                                  unsigned int flags)
 {
     virQEMUDriverPtr driver = conn->privateData;
+    VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver);
     virCPUDefPtr *cpus = NULL;
     virQEMUCapsPtr qemuCaps = NULL;
     virArch arch;
@@ -13804,6 +13889,12 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
         if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
                                    (const char **)features, migratable)))
             goto cleanup;
+    } else if (ARCH_IS_S390(arch) &&
+               virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_BASELINE)) {
+        if (!(cpu = qemuConnectCPUModelBaseline(qemuCaps, cfg->libDir,
+                                                cfg->user, cfg->group,
+                                                cpus, ncpus)))
+            goto cleanup;
     } else {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("computing baseline hypervisor CPU is not supported "