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@xxxxxxxxxx> --- 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