On Tue, 12 Jan 2021 09:29:50 +0100 Michal Privoznik <mprivozn@xxxxxxxxxx> wrote: > 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; is it possible to do it only for old machine types <= 4.0, to limit hack exposure? > 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 \