[libvirt] [PATCH v5 14/15] qemu_driver: hook up query-cpu-model-comparison

Collin Walling posted 15 patches 6 years, 4 months ago
[libvirt] [PATCH v5 14/15] qemu_driver: hook up query-cpu-model-comparison
Posted by Collin Walling 6 years, 4 months ago
This command is hooked into the virsh hypervisor-cpu-compare command.
As such, the CPU model XML provided to the command will be compared
to the hypervisor CPU contained in the QEMU capabilities file for the
appropriate QEMU binary (for s390x, this CPU definition can be observed
via virsh domcapabilities).

QMP will report that the XML CPU is either identical to, a subset of,
or incompatible with the hypervisor CPU. s390 can also report that
the XML CPU is a "superset" of the hypervisor CPU. This response is
presented as incompatible, as this CPU model would not be able to run
on the hypervisor.

Signed-off-by: Collin Walling <walling@linux.ibm.com>
Reviewed-by: Daniel Henrique Barboza <danielh413@gmail.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
---
 src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 93f1767..153b2f2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13703,6 +13703,45 @@ qemuConnectCompareCPU(virConnectPtr conn,
 }
 
 
+static virCPUCompareResult
+qemuConnectCPUModelComparison(virQEMUCapsPtr qemuCaps,
+                              const char *libDir,
+                              uid_t runUid,
+                              gid_t runGid,
+                              virCPUDefPtr cpu_a,
+                              virCPUDefPtr cpu_b,
+                              bool failIncompatible)
+{
+    qemuProcessQMPPtr proc = NULL;
+    char *result = NULL;
+    int ret = VIR_CPU_COMPARE_ERROR;
+
+    if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps),
+                                   libDir, runUid, runGid, false)))
+        goto cleanup;
+
+    if (qemuProcessQMPStart(proc) < 0)
+        goto cleanup;
+
+    if (qemuMonitorGetCPUModelComparison(proc->mon, cpu_a, cpu_b, &result) < 0)
+        goto cleanup;
+
+    if (STREQ(result, "identical"))
+        ret = VIR_CPU_COMPARE_IDENTICAL;
+    else if (STREQ(result, "superset"))
+        ret = VIR_CPU_COMPARE_SUPERSET;
+    else if (failIncompatible)
+        virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+    else
+        ret = VIR_CPU_COMPARE_INCOMPATIBLE;
+
+ cleanup:
+    VIR_FREE(result);
+    qemuProcessQMPFree(proc);
+    return ret;
+}
+
+
 static int
 qemuConnectCompareHypervisorCPU(virConnectPtr conn,
                                 const char *emulator,
@@ -13714,9 +13753,11 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
 {
     int ret = VIR_CPU_COMPARE_ERROR;
     virQEMUDriverPtr driver = conn->privateData;
+    VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver);
     virQEMUCapsPtr qemuCaps = NULL;
     bool failIncompatible;
     virCPUDefPtr hvCPU;
+    virCPUDefPtr cpu;
     virArch arch;
     virDomainVirtType virttype;
 
@@ -13751,6 +13792,16 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
 
     if (ARCH_IS_X86(arch)) {
         ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible);
+
+    } else if (ARCH_IS_S390(arch) &&
+               virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) {
+
+        if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu) < 0)
+            goto cleanup;
+
+        ret = qemuConnectCPUModelComparison(qemuCaps, cfg->libDir,
+                                            cfg->user, cfg->group,
+                                            hvCPU, cpu, failIncompatible);
     } else {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("comparing with the hypervisor CPU is not supported "
@@ -13758,6 +13809,7 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
     }
 
  cleanup:
+    virCPUDefFree(cpu);
     virObjectUnref(qemuCaps);
     return ret;
 }
-- 
2.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v5 14/15] qemu_driver: hook up query-cpu-model-comparison
Posted by Jiri Denemark 6 years, 4 months ago
On Thu, Sep 19, 2019 at 16:25:05 -0400, Collin Walling wrote:
> This command is hooked into the virsh hypervisor-cpu-compare command.
> As such, the CPU model XML provided to the command will be compared
> to the hypervisor CPU contained in the QEMU capabilities file for the
> appropriate QEMU binary (for s390x, this CPU definition can be observed
> via virsh domcapabilities).
> 
> QMP will report that the XML CPU is either identical to, a subset of,
> or incompatible with the hypervisor CPU. s390 can also report that
> the XML CPU is a "superset" of the hypervisor CPU. This response is
> presented as incompatible, as this CPU model would not be able to run
> on the hypervisor.
> 
> Signed-off-by: Collin Walling <walling@linux.ibm.com>
> Reviewed-by: Daniel Henrique Barboza <danielh413@gmail.com>
> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
> ---
>  src/qemu/qemu_driver.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 93f1767..153b2f2 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
...
> @@ -13714,9 +13753,11 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
>  {
>      int ret = VIR_CPU_COMPARE_ERROR;
>      virQEMUDriverPtr driver = conn->privateData;
> +    VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver);
>      virQEMUCapsPtr qemuCaps = NULL;
>      bool failIncompatible;
>      virCPUDefPtr hvCPU;
> +    virCPUDefPtr cpu;

This needs to be initialized to NULL.

>      virArch arch;
>      virDomainVirtType virttype;
>  
> @@ -13751,6 +13792,16 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
>  
>      if (ARCH_IS_X86(arch)) {
>          ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible);
> +
> +    } else if (ARCH_IS_S390(arch) &&
> +               virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) {
> +

Some extra empty lines.

> +        if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu) < 0)
> +            goto cleanup;
> +
> +        ret = qemuConnectCPUModelComparison(qemuCaps, cfg->libDir,
> +                                            cfg->user, cfg->group,
> +                                            hvCPU, cpu, failIncompatible);
>      } else {
>          virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
>                         _("comparing with the hypervisor CPU is not supported "
> @@ -13758,6 +13809,7 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
>      }
>  
>   cleanup:
> +    virCPUDefFree(cpu);
>      virObjectUnref(qemuCaps);
>      return ret;
>  }

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list