In commit v6.9.0-rc1~450 I've adapted libvirt to QEMU's deprecation of
-mem-path and -mem-prealloc and switched to memory-backend-* even for
system memory. My claim was that that's what QEMU does under the hood
anyway. And indeed it was: see QEMU commit v5.0.0-rc0~75^2~1^2~76 and
look at function create_default_memdev().
However, then commit v5.0.0-rc1~11^2~3 was merged into QEMU. While it
was fixing a bug, it also changed the create_default_memdev() function
in which it started turning off use of canonical path (by setting
"x-use-canonical-path-for-ramblock-id" attribute to false). This wasn't
documented until QEMU commit XXX. The path affects migration - the same
path has to be used on the source and on the destination. Therefore, if
there is old guest started with '-m X' it has "pc.ram" block which
doesn't use canonical path and thus when migrating to newer QEMU which
uses memory-backend-* we have to turn off the canonical path explicitly.
Otherwise, "/objects/pc.ram" path would be expected by QEMU which
doesn't match the source.
Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1912201
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
I'll replace both occurrences of 'QEMU commit XXX' once QEMU patch is
merged.
src/qemu/qemu_command.c | 30 ++++++++++++++++---
src/qemu/qemu_command.h | 3 +-
src/qemu/qemu_hotplug.c | 2 +-
.../hugepages-memaccess3.x86_64-latest.args | 4 +--
4 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6f970a3128..b99d4e5faf 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2950,7 +2950,8 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
qemuDomainObjPrivatePtr priv,
const virDomainDef *def,
const virDomainMemoryDef *mem,
- bool force)
+ bool force,
+ bool systemMemory)
{
const char *backendType = "memory-backend-file";
virDomainNumatuneMemMode mode;
@@ -2967,6 +2968,7 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
bool needHugepage = !!pagesize;
bool useHugepage = !!pagesize;
int discard = mem->discard;
+ bool useCanonicalPath = true;
/* The difference between @needHugepage and @useHugepage is that the latter
* is true whenever huge page is defined for the current memory cell.
@@ -3081,6 +3083,9 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
if (qemuBuildMemoryBackendPropsShare(props, memAccess) < 0)
return -1;
+ if (systemMemory)
+ useCanonicalPath = false;
+
} else if (useHugepage || mem->nvdimmPath || memAccess ||
def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
@@ -3122,10 +3127,27 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
if (qemuBuildMemoryBackendPropsShare(props, memAccess) < 0)
return -1;
+
+ if (systemMemory)
+ useCanonicalPath = false;
+
} else {
backendType = "memory-backend-ram";
}
+ /* This is a terrible hack, but unfortunately there is no better way.
+ * The replacement for '-m X' argument is not simple '-machine
+ * memory-backend' and '-object memory-backend-*,size=X' (which was the
+ * idea). This is because of create_default_memdev() in QEMU sets
+ * 'x-use-canonical-path-for-ramblock-id' attribute to false and is
+ * documented in QEMU in qemu-options.hx under 'memory-backend'.
+ * See QEMU commit XXX.
+ */
+ if (!useCanonicalPath &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID)
&&
+ virJSONValueObjectAdd(props, "b:x-use-canonical-path-for-ramblock-id",
false, NULL) < 0)
+ return -1;
+
if (!priv->memPrealloc &&
virJSONValueObjectAdd(props, "B:prealloc", prealloc, NULL) < 0)
return -1;
@@ -3237,7 +3259,7 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def,
mem.info.alias = alias;
if ((rc = qemuBuildMemoryBackendProps(&props, alias, cfg,
- priv, def, &mem, false)) < 0)
+ priv, def, &mem, false, false)) < 0)
return -1;
if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0)
@@ -3266,7 +3288,7 @@ qemuBuildMemoryDimmBackendStr(virBufferPtr buf,
alias = g_strdup_printf("mem%s", mem->info.alias);
if (qemuBuildMemoryBackendProps(&props, alias, cfg,
- priv, def, mem, true) < 0)
+ priv, def, mem, true, false) < 0)
return -1;
if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0)
@@ -7065,7 +7087,7 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommandPtr cmd,
mem.info.alias = (char *) defaultRAMid;
if (qemuBuildMemoryBackendProps(&props, defaultRAMid, cfg,
- priv, def, &mem, false) < 0)
+ priv, def, &mem, false, true) < 0)
return -1;
if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0)
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 3cfe6ff3e9..32cb013172 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -153,7 +153,8 @@ int qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps,
qemuDomainObjPrivatePtr priv,
const virDomainDef *def,
const virDomainMemoryDef *mem,
- bool force);
+ bool force,
+ bool systemMemory);
char *
qemuBuildMemoryDeviceStr(const virDomainDef *def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f336a90c8e..18d8cc06f5 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2426,7 +2426,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
goto cleanup;
if (qemuBuildMemoryBackendProps(&props, objalias, cfg,
- priv, vm->def, mem, true) < 0)
+ priv, vm->def, mem, true, false) < 0)
goto cleanup;
if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0)
diff --git a/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args
b/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args
index 6033950eab..9396441b92 100644
--- a/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args
@@ -19,8 +19,8 @@
arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,\
rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \
-m 4096 \
-object memory-backend-file,id=pc.ram,\
-mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,share=yes,prealloc=yes,\
-size=4294967296 \
+mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,share=yes,\
+x-use-canonical-path-for-ramblock-id=no,prealloc=yes,size=4294967296 \
-overcommit mem-lock=off \
-smp 4,sockets=4,cores=1,threads=1 \
-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
--
2.26.2