From b647654cbbe59589a8b014a63f43c38c91c03353 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 25 May 2020 19:13:43 +0200 Subject: [PATCH] qemu: Track default-ram-id machine attribute MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The machine structure has another (optional) attribute: default-ram-id, which specifies the alias of the default RAM object. While the alias is private, it can never change in order to not break migration. QEMU uses the alias when allocating regular, not NUMA memory. In order to switch to new command line and maintain migration, save this ID. Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko Reviewed-by: Daniel Henrique Barboza --- src/qemu/qemu_capabilities.c | 35 +++- src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_capspriv.h | 3 +- src/qemu/qemu_monitor.c | 1 + src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 11 + .../caps_5.2.0.x86_64.xml | 196 +++++++++--------- tests/testutilsqemu.c | 24 ++- 8 files changed, 170 insertions(+), 104 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ad25a30f2d..5dcfcd574d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -613,6 +613,7 @@ struct _virQEMUCapsMachineType { bool qemuDefault; char *defaultCPU; bool numaMemSupported; + char *defaultRAMid; }; typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData; @@ -1898,6 +1899,7 @@ virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccelPtr dst, dst->machineTypes[i].hotplugCpus = src->machineTypes[i].hotplugCpus; dst->machineTypes[i].qemuDefault = src->machineTypes[i].qemuDefault; dst->machineTypes[i].numaMemSupported = src->machineTypes[i].numaMemSupported; + dst->machineTypes[i].defaultRAMid = g_strdup(src->machineTypes[i].defaultRAMid); } } @@ -1975,6 +1977,7 @@ virQEMUCapsAccelClear(virQEMUCapsAccelPtr caps) VIR_FREE(caps->machineTypes[i].name); VIR_FREE(caps->machineTypes[i].alias); VIR_FREE(caps->machineTypes[i].defaultCPU); + VIR_FREE(caps->machineTypes[i].defaultRAMid); } VIR_FREE(caps->machineTypes); @@ -2561,6 +2564,25 @@ virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, } +const char * +virQEMUCapsGetMachineDefaultRAMid(virQEMUCapsPtr qemuCaps, + virDomainVirtType virtType, + const char *name) +{ + virQEMUCapsAccelPtr accel; + size_t i; + + accel = virQEMUCapsGetAccel(qemuCaps, virtType); + + for (i = 0; i < accel->nmachineTypes; i++) { + if (STREQ(accel->machineTypes[i].name, name)) + return accel->machineTypes[i].defaultRAMid; + } + + return NULL; +} + + /** * virQEMUCapsSetGICCapabilities: * @qemuCaps: QEMU capabilities @@ -2797,7 +2819,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, int maxCpus, bool hotplugCpus, bool isDefault, - bool numaMemSupported) + bool numaMemSupported, + const char *defaultRAMid) { virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType); virQEMUCapsMachineTypePtr mach; @@ -2818,6 +2841,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, mach->qemuDefault = isDefault; mach->numaMemSupported = numaMemSupported; + + mach->defaultRAMid = g_strdup(defaultRAMid); } /** @@ -2864,7 +2889,8 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps, machines[i]->maxCpus, machines[i]->hotplugCpus, machines[i]->isDefault, - machines[i]->numaMemSupported); + machines[i]->numaMemSupported, + machines[i]->defaultRAMid); if (preferredMachine && (STREQ_NULLABLE(machines[i]->alias, preferredMachine) || @@ -4091,6 +4117,7 @@ virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps, VIR_FREE(str); caps->machineTypes[i].defaultCPU = virXMLPropString(nodes[i], "defaultCPU"); + caps->machineTypes[i].defaultRAMid = virXMLPropString(nodes[i], "defaultRAMid"); } return 0; @@ -4579,6 +4606,8 @@ virQEMUCapsFormatMachines(virQEMUCapsAccelPtr caps, caps->machineTypes[i].defaultCPU); if (caps->machineTypes[i].numaMemSupported) virBufferAddLit(buf, " numaMemSupported='yes'"); + virBufferEscapeString(buf, " defaultRAMid='%s'", + caps->machineTypes[i].defaultRAMid); virBufferAddLit(buf, "/>\n"); } } @@ -6388,7 +6417,7 @@ virQEMUCapsStripMachineAliasesForVirtType(virQEMUCapsPtr qemuCaps, if (name) { virQEMUCapsAddMachine(qemuCaps, virtType, name, NULL, mach->defaultCPU, mach->maxCpus, mach->hotplugCpus, mach->qemuDefault, - mach->numaMemSupported); + mach->numaMemSupported, mach->defaultRAMid); } } } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 1a3fafd1a6..98d70cfa0e 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -691,6 +691,9 @@ const char *virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, const char *name); +const char *virQEMUCapsGetMachineDefaultRAMid(virQEMUCapsPtr qemuCaps, + virDomainVirtType virtType, + const char *name); void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h index f6c06ea008..15fc79e88b 100644 --- a/src/qemu/qemu_capspriv.h +++ b/src/qemu/qemu_capspriv.h @@ -119,4 +119,5 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, int maxCpus, bool hotplugCpus, bool isDefault, - bool numaMemSupported); + bool numaMemSupported, + const char *defaultRAMid); diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index ab3bcc761e..eb4b04dc1a 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3540,6 +3540,7 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine) VIR_FREE(machine->name); VIR_FREE(machine->alias); VIR_FREE(machine->defaultCPU); + VIR_FREE(machine->defaultRAMid); VIR_FREE(machine); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index d3f7797085..a744c8975b 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1106,6 +1106,7 @@ struct _qemuMonitorMachineInfo { bool hotplugCpus; char *defaultCPU; bool numaMemSupported; + char *defaultRAMid; }; int qemuMonitorGetMachines(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e6d2e7d4db..bc242c798b 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5641,6 +5641,17 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon, } else { info->numaMemSupported = true; } + + if (virJSONValueObjectHasKey(child, "default-ram-id")) { + if (!(tmp = virJSONValueObjectGetString(child, "default-ram-id"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-machines reply has malformed " + "'default-ram-id' data")); + goto cleanup; + } + + info->defaultRAMid = g_strdup(tmp); + } } ret = n; diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index 8d4726a492..3ee678ef8f 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -1405,55 +1405,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3142,53 +3142,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index b248207f0f..5b23888a98 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -99,6 +99,15 @@ static const char *const *kvm_machines[VIR_ARCH_LAST] = { [VIR_ARCH_S390X] = s390x_machines, }; +static const char *qemu_default_ram_id[VIR_ARCH_LAST] = { + [VIR_ARCH_I686] = "pc.ram", + [VIR_ARCH_X86_64] = "pc.ram", + [VIR_ARCH_AARCH64] = "mach-virt.ram", + [VIR_ARCH_ARMV7L] = "vexpress.highmem", + [VIR_ARCH_PPC64] = "ppc_spapr.ram", + [VIR_ARCH_PPC] = "ppc_spapr.ram", + [VIR_ARCH_S390X] = "s390.ram" +}; char * virFindFileInPath(const char *file) @@ -331,7 +340,16 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, } if (!virQEMUCapsHasMachines(tmpCaps)) { + const char *defaultRAMid = NULL; + + /* default-ram-id appeared in QEMU 5.2.0. Reflect + * this in our capabilities, i.e. set it for new + * enough versions only. */ + if (virQEMUCapsGetVersion(tmpCaps) >= 5002000) + defaultRAMid = qemu_default_ram_id[i]; + virQEMUCapsSetArch(tmpCaps, i); + for (j = 0; qemu_machines[i][j] != NULL; j++) { virQEMUCapsAddMachine(tmpCaps, VIR_DOMAIN_VIRT_QEMU, @@ -341,7 +359,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, 0, false, false, - true); + true, + defaultRAMid); virQEMUCapsSet(tmpCaps, QEMU_CAPS_TCG); } for (j = 0; kvm_machines[i][j] != NULL; j++) { @@ -353,7 +372,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, 0, false, false, - true); + true, + defaultRAMid); virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM); } } -- 2.47.2