On Wed, Jul 17, 2019 at 10:03:29 -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). > > s390x can report that the first model (A) is a subset of the second > (B). If A is the hypervisor CPU and a subset of B (the CPU contained > in the XML), then B would not be able to run on this machine and thus > we will report that CPU model B is incompatible. > > Signed-off-by: Collin Walling <walling@xxxxxxxxxxxxx> > Reviewed-by: Daniel Henrique Barboza <danielh413@xxxxxxxxx> > --- > src/qemu/qemu_capabilities.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_capabilities.h | 9 +++++++++ > src/qemu/qemu_driver.c | 11 ++++++++++ > 3 files changed, 68 insertions(+) > > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c > index a99ebcb..20cb82b 100644 > --- a/src/qemu/qemu_capabilities.c > +++ b/src/qemu/qemu_capabilities.c > @@ -5660,3 +5660,51 @@ virQEMUCapsCPUModelBaseline(virQEMUCapsPtr qemuCaps, > virCPUDefFree(cpu); > return baseline; > } > + > +virCPUCompareResult > +virQEMUCapsCPUModelComparison(virQEMUCapsPtr qemuCaps, > + const char *libDir, > + uid_t runUid, > + gid_t runGid, > + virCPUDefPtr cpu_a, > + virCPUDefPtr cpu_b, > + bool failIncompatible) This function should go into qemu_driver.c and its name should change accordingly. > +{ > + qemuProcessQMPPtr proc = NULL; > + qemuMonitorCPUModelInfoPtr result = NULL; > + int ret = -1; > + > + if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir, > + runUid, runGid, false))) > + goto cleanup; > + > + if (qemuProcessQMPStart(proc) < 0) > + goto cleanup; > + > + if (qemuMonitorGetCPUModelComparison(proc->mon, cpu_a->model, > + cpu_a->nfeatures, cpu_a->features, > + cpu_b->model, cpu_b->nfeatures, > + cpu_b->features, &result) < 0) > + goto cleanup; > + > + if (STREQ(result->name, "incompatible") || > + STREQ(result->name, "subset")) > + ret = VIR_CPU_COMPARE_INCOMPATIBLE; > + else if (STREQ(result->name, "identical")) > + ret = VIR_CPU_COMPARE_IDENTICAL; > + else if (STREQ(result->name, "superset")) > + ret = VIR_CPU_COMPARE_SUPERSET; > + > + if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) { > + ret = VIR_CPU_COMPARE_ERROR; > + virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); > + } > + > + cleanup: > + if (ret < 0) > + virQEMUCapsLogProbeFailure(qemuCaps->binary); Again, no logging here, please. The reported error is already going to be logged anyway. And mainly since this is called from inside an API invoked by a client, the client will get the error. Probing is different as there's no API involved, QEMU binaries are probed when libvirtd starts. > + > + qemuMonitorCPUModelInfoFree(result); > + qemuProcessQMPFree(proc); > + return ret; > +} > diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h > index 8afa05c..a62499f 100644 > --- a/src/qemu/qemu_capabilities.h > +++ b/src/qemu/qemu_capabilities.h > @@ -673,3 +673,12 @@ virCPUDefPtr virQEMUCapsCPUModelBaseline(virQEMUCapsPtr qemuCaps, > gid_t runGid, > int ncpus, > virCPUDefPtr *cpus); > + > +virCPUCompareResult > +virQEMUCapsCPUModelComparison(virQEMUCapsPtr qemuCaps, > + const char *libDir, > + uid_t runUid, > + gid_t runGid, > + virCPUDefPtr cpu_a, > + virCPUDefPtr cpu_b, > + bool failIncompatible); > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 37b9c75..3e49c04 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -13446,9 +13446,11 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, > { > int ret = VIR_CPU_COMPARE_ERROR; > virQEMUDriverPtr driver = conn->privateData; > + virQEMUDriverConfigPtr config = driver->config; VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); > virQEMUCapsPtr qemuCaps = NULL; > bool failIncompatible; > virCPUDefPtr hvCPU; > + virCPUDefPtr cpu; > virArch arch; > virDomainVirtType virttype; > > @@ -13483,6 +13485,14 @@ 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 (virCPUDefParseXMLHelper(xmlCPU, NULL, VIR_CPU_TYPE_AUTO, &cpu) < 0) > + goto cleanup; > + > + ret = virQEMUCapsCPUModelComparison(qemuCaps, config->libDir, > + config->user, config->group, > + hvCPU, cpu, failIncompatible); > } else { > virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > _("comparing with the hypervisor CPU is not supported " > @@ -13490,6 +13500,7 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, > } > > cleanup: > + virCPUDefFree(cpu); > virObjectUnref(qemuCaps); > return ret; > } Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list