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 <mprivozn(a)redhat.com>
---
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 +++++++++++
tests/testutilsqemu.c | 15 +++++++++++++--
7 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 801200c4e7..b2dbc6b28e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -598,6 +598,7 @@ struct _virQEMUCapsMachineType {
bool qemuDefault;
char *defaultCPU;
bool numaMemSupported;
+ char *defaultRAMid;
};
typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
@@ -1875,6 +1876,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);
}
}
@@ -1951,6 +1953,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);
@@ -2537,6 +2540,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
@@ -2773,7 +2795,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps,
int maxCpus,
bool hotplugCpus,
bool isDefault,
- bool numaMemSupported)
+ bool numaMemSupported,
+ const char *defaultRAMid)
{
virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType);
virQEMUCapsMachineTypePtr mach;
@@ -2794,6 +2817,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps,
mach->qemuDefault = isDefault;
mach->numaMemSupported = numaMemSupported;
+
+ mach->defaultRAMid = g_strdup(defaultRAMid);
}
/**
@@ -2840,7 +2865,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) ||
@@ -4065,6 +4091,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;
@@ -4526,6 +4553,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");
}
}
@@ -6264,7 +6293,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 bc2c432609..e2742030d8 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -677,6 +677,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 5d2f448e41..1028de517e 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -121,4 +121,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 2911307f0e..400bb2424a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3512,6 +3512,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 c61c05cb9f..8d88a02958 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1096,6 +1096,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 3070c1e6b3..45f1576ad7 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5638,6 +5638,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/testutilsqemu.c b/tests/testutilsqemu.c
index 4dcc3089dd..13b48d99b3 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)
@@ -345,7 +354,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache,
0,
false,
false,
- true);
+ true,
+ qemu_default_ram_id[i]);
virQEMUCapsSet(tmpCaps, QEMU_CAPS_TCG);
}
for (j = 0; kvm_machines[i][j] != NULL; j++) {
@@ -357,7 +367,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache,
0,
false,
false,
- true);
+ true,
+ qemu_default_ram_id[i]);
virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM);
}
}
--
2.26.2