[PATCH v2 2/2] qemu: Do not Use canonical path for system memory

Michal Privoznik mprivozn at redhat.com
Thu Jan 14 12:37:24 UTC 2021


In commit 88957116c9d3cb4705380c3702c9d4315fb500bb 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 900c0ba373aada4c13d47d95330aa72ec4067ba5 and
look at function create_default_memdev().

However, then commit d96c4d5f193e0e45beec80a6277728b32875bddb 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 at redhat.com>
---
 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




More information about the libvir-list mailing list