404507
From 12f6ee75efb15263f62fb12c693b74b116ac4a4f Mon Sep 17 00:00:00 2001
404507
Message-Id: <12f6ee75efb15263f62fb12c693b74b116ac4a4f@dist-git>
404507
From: Michal Privoznik <mprivozn@redhat.com>
404507
Date: Thu, 9 Nov 2017 16:06:47 +0100
404507
Subject: [PATCH] qemu: Use predictable file names for memory-backend-file
404507
404507
https://bugzilla.redhat.com/show_bug.cgi?id=1461214
404507
404507
In some cases management application needs to allocate memory for
404507
qemu upfront and then just let qemu use that. Since we don't want
404507
to expose path for memory-backend-file anywhere in the domain
404507
XML, we can generate predictable paths. In this case:
404507
404507
  $memoryBackingDir/libvirt/qemu/$shortName/$alias
404507
404507
where $shortName is result of virDomainDefGetShortName().
404507
404507
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
404507
Reviewed-by: John Ferlan <jferlan@redhat.com>
404507
(cherry picked from commit fec8f9c49afb479f6c3c8c388426945f2c1f099b)
404507
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
404507
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
404507
---
404507
 src/qemu/qemu_command.c                            |  2 +-
404507
 src/qemu/qemu_conf.c                               | 55 +++++++++++++++++-
404507
 src/qemu/qemu_conf.h                               |  9 ++-
404507
 src/qemu/qemu_driver.c                             | 17 ++++++
404507
 src/qemu/qemu_process.c                            | 65 ++++++++++++++++++----
404507
 .../qemuxml2argv-cpu-numa-memshared.args           |  6 +-
404507
 .../qemuxml2argv-fd-memory-numa-topology.args      |  3 +-
404507
 .../qemuxml2argv-fd-memory-numa-topology2.args     |  6 +-
404507
 .../qemuxml2argv-fd-memory-numa-topology3.args     |  9 ++-
404507
 .../qemuxml2argv-hugepages-memaccess2.args         |  9 ++-
404507
 10 files changed, 155 insertions(+), 26 deletions(-)
404507
404507
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
404507
index 57c855c047..f8eb59884c 100644
404507
--- a/src/qemu/qemu_command.c
404507
+++ b/src/qemu/qemu_command.c
404507
@@ -3439,7 +3439,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
404507
         } else {
404507
             /* We can have both pagesize and mem source. If that's the case,
404507
              * prefer hugepages as those are more specific. */
404507
-            if (qemuGetMemoryBackingPath(cfg, &memPath) < 0)
404507
+            if (qemuGetMemoryBackingPath(def, cfg, mem->info.alias, &memPath) < 0)
404507
                 goto cleanup;
404507
         }
404507
 
404507
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
404507
index 3b670a68c5..e04523223d 100644
404507
--- a/src/qemu/qemu_conf.c
404507
+++ b/src/qemu/qemu_conf.c
404507
@@ -1767,9 +1767,41 @@ qemuGetDomainHupageMemPath(const virDomainDef *def,
404507
 }
404507
 
404507
 
404507
+int
404507
+qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg,
404507
+                             char **path)
404507
+{
404507
+    return virAsprintf(path, "%s/libvirt/qemu", cfg->memoryBackingDir);
404507
+}
404507
+
404507
+
404507
+int
404507
+qemuGetMemoryBackingDomainPath(const virDomainDef *def,
404507
+                               virQEMUDriverConfigPtr cfg,
404507
+                               char **path)
404507
+{
404507
+    char *shortName = NULL;
404507
+    char *base = NULL;
404507
+    int ret = -1;
404507
+
404507
+    if (!(shortName = virDomainDefGetShortName(def)) ||
404507
+        qemuGetMemoryBackingBasePath(cfg, &base) < 0 ||
404507
+        virAsprintf(path, "%s/%s", base, shortName) < 0)
404507
+        goto cleanup;
404507
+
404507
+    ret = 0;
404507
+ cleanup:
404507
+    VIR_FREE(base);
404507
+    VIR_FREE(shortName);
404507
+    return ret;
404507
+}
404507
+
404507
+
404507
 /**
404507
  * qemuGetMemoryBackingPath:
404507
+ * @def: domain definition
404507
  * @cfg: the driver config
404507
+ * @alias: memory object alias
404507
  * @memPath: constructed path
404507
  *
404507
  * Constructs path to memory backing dir and stores it at @memPath.
404507
@@ -1778,8 +1810,27 @@ qemuGetDomainHupageMemPath(const virDomainDef *def,
404507
  *          -1 otherwise (with error reported).
404507
  */
404507
 int
404507
-qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg,
404507
+qemuGetMemoryBackingPath(const virDomainDef *def,
404507
+                         virQEMUDriverConfigPtr cfg,
404507
+                         const char *alias,
404507
                          char **memPath)
404507
 {
404507
-    return VIR_STRDUP(*memPath, cfg->memoryBackingDir);
404507
+    char *domainPath = NULL;
404507
+    int ret = -1;
404507
+
404507
+    if (!alias) {
404507
+        /* This should never happen (TM) */
404507
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
404507
+                       _("memory device alias is not assigned"));
404507
+        goto cleanup;
404507
+    }
404507
+
404507
+    if (qemuGetMemoryBackingDomainPath(def, cfg, &domainPath) < 0 ||
404507
+        virAsprintf(memPath, "%s/%s", domainPath, alias) < 0)
404507
+        goto cleanup;
404507
+
404507
+    ret = 0;
404507
+ cleanup:
404507
+    VIR_FREE(domainPath);
404507
+    return ret;
404507
 }
404507
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
404507
index 9d6866816f..a553e30e2e 100644
404507
--- a/src/qemu/qemu_conf.h
404507
+++ b/src/qemu/qemu_conf.h
404507
@@ -364,6 +364,13 @@ int qemuGetDomainHupageMemPath(const virDomainDef *def,
404507
                                unsigned long long pagesize,
404507
                                char **memPath);
404507
 
404507
-int qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg,
404507
+int qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg,
404507
+                                 char **path);
404507
+int qemuGetMemoryBackingDomainPath(const virDomainDef *def,
404507
+                                   virQEMUDriverConfigPtr cfg,
404507
+                                   char **path);
404507
+int qemuGetMemoryBackingPath(const virDomainDef *def,
404507
+                             virQEMUDriverConfigPtr cfg,
404507
+                             const char *alias,
404507
                              char **memPath);
404507
 #endif /* __QEMUD_CONF_H */
404507
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
404507
index 5617c78997..6096e00b2a 100644
404507
--- a/src/qemu/qemu_driver.c
404507
+++ b/src/qemu/qemu_driver.c
404507
@@ -631,6 +631,7 @@ qemuStateInitialize(bool privileged,
404507
     uid_t run_uid = -1;
404507
     gid_t run_gid = -1;
404507
     char *hugepagePath = NULL;
404507
+    char *memoryBackingPath = NULL;
404507
     size_t i;
404507
 
404507
     if (VIR_ALLOC(qemu_driver) < 0)
404507
@@ -889,6 +890,21 @@ qemuStateInitialize(bool privileged,
404507
         VIR_FREE(hugepagePath);
404507
     }
404507
 
404507
+    if (qemuGetMemoryBackingBasePath(cfg, &memoryBackingPath) < 0)
404507
+        goto error;
404507
+
404507
+    if (virFileMakePath(memoryBackingPath) < 0) {
404507
+        virReportSystemError(errno,
404507
+                             _("unable to create memory backing path %s"),
404507
+                             memoryBackingPath);
404507
+        goto error;
404507
+    }
404507
+
404507
+    if (privileged &&
404507
+        virFileUpdatePerm(memoryBackingPath,
404507
+                          0, S_IXGRP | S_IXOTH) < 0)
404507
+        goto error;
404507
+
404507
     if (!(qemu_driver->closeCallbacks = virCloseCallbacksNew()))
404507
         goto error;
404507
 
404507
@@ -946,6 +962,7 @@ qemuStateInitialize(bool privileged,
404507
     virObjectUnref(conn);
404507
     VIR_FREE(driverConf);
404507
     VIR_FREE(hugepagePath);
404507
+    VIR_FREE(memoryBackingPath);
404507
     qemuStateCleanup();
404507
     return -1;
404507
 }
404507
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
404507
index 3324cc61f1..86a4dee88e 100644
404507
--- a/src/qemu/qemu_process.c
404507
+++ b/src/qemu/qemu_process.c
404507
@@ -3324,6 +3324,36 @@ qemuProcessNeedHugepagesPath(virDomainDefPtr def,
404507
 }
404507
 
404507
 
404507
+static bool
404507
+qemuProcessNeedMemoryBackingPath(virDomainDefPtr def,
404507
+                                 virDomainMemoryDefPtr mem)
404507
+{
404507
+    size_t i;
404507
+    size_t numaNodes;
404507
+
404507
+    if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE ||
404507
+        def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)
404507
+        return true;
404507
+
404507
+    numaNodes = virDomainNumaGetNodeCount(def->numa);
404507
+    for (i = 0; i < numaNodes; i++) {
404507
+        if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)
404507
+            != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)
404507
+            return true;
404507
+    }
404507
+
404507
+    if (mem &&
404507
+        mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM &&
404507
+        (mem->access != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT ||
404507
+         (mem->targetNode >= 0 &&
404507
+          virDomainNumaGetNodeMemoryAccessMode(def->numa, mem->targetNode)
404507
+          != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)))
404507
+        return true;
404507
+
404507
+    return false;
404507
+}
404507
+
404507
+
404507
 static int
404507
 qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver,
404507
                                        virDomainDefPtr def,
404507
@@ -3363,33 +3393,46 @@ qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver,
404507
                                    bool build)
404507
 {
404507
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
404507
-    char *hugepagePath = NULL;
404507
+    char *path = NULL;
404507
     size_t i;
404507
-    bool shouldBuild = false;
404507
+    bool shouldBuildHP = false;
404507
+    bool shouldBuildMB = false;
404507
     int ret = -1;
404507
 
404507
-    if (build)
404507
-        shouldBuild = qemuProcessNeedHugepagesPath(vm->def, mem);
404507
+    if (build) {
404507
+        shouldBuildHP = qemuProcessNeedHugepagesPath(vm->def, mem);
404507
+        shouldBuildMB = qemuProcessNeedMemoryBackingPath(vm->def, mem);
404507
+    }
404507
 
404507
-    if (!build || shouldBuild) {
404507
+    if (!build || shouldBuildHP) {
404507
         for (i = 0; i < cfg->nhugetlbfs; i++) {
404507
-            VIR_FREE(hugepagePath);
404507
-            hugepagePath = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]);
404507
+            path = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]);
404507
 
404507
-            if (!hugepagePath)
404507
+            if (!path)
404507
                 goto cleanup;
404507
 
404507
             if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def,
404507
-                                                       hugepagePath, build) < 0)
404507
+                                                       path, build) < 0)
404507
                 goto cleanup;
404507
 
404507
-            VIR_FREE(hugepagePath);
404507
+            VIR_FREE(path);
404507
         }
404507
     }
404507
 
404507
+    if (!build || shouldBuildMB) {
404507
+        if (qemuGetMemoryBackingDomainPath(vm->def, cfg, &path) < 0)
404507
+            goto cleanup;
404507
+
404507
+        if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def,
404507
+                                                   path, build) < 0)
404507
+            goto cleanup;
404507
+
404507
+        VIR_FREE(path);
404507
+    }
404507
+
404507
     ret = 0;
404507
  cleanup:
404507
-    VIR_FREE(hugepagePath);
404507
+    VIR_FREE(path);
404507
     virObjectUnref(cfg);
404507
     return ret;
404507
 }
404507
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args
404507
index 5700c3413f..3528194293 100644
404507
--- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args
404507
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args
404507
@@ -10,10 +10,12 @@ QEMU_AUDIO_DRV=none \
404507
 -M pc \
404507
 -m 214 \
404507
 -smp 16,sockets=2,cores=4,threads=2 \
404507
--object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node0,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\
404507
 share=yes,size=112197632 \
404507
 -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
404507
--object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node1,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node1,\
404507
 share=no,size=112197632 \
404507
 -numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \
404507
 -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
404507
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args
404507
index 12f3d8ab8c..fa13532596 100644
404507
--- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args
404507
+++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args
404507
@@ -11,7 +11,8 @@ QEMU_AUDIO_DRV=none \
404507
 -m 14336 \
404507
 -mem-prealloc \
404507
 -smp 8,sockets=1,cores=8,threads=1 \
404507
--object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node0,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\
404507
 share=yes,size=15032385536 \
404507
 -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
404507
 -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \
404507
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args
404507
index 585e4d5061..6f73a1b99b 100644
404507
--- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args
404507
+++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args
404507
@@ -11,10 +11,12 @@ QEMU_AUDIO_DRV=none \
404507
 -m 28672 \
404507
 -mem-prealloc \
404507
 -smp 20,sockets=1,cores=8,threads=1 \
404507
--object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node0,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\
404507
 share=no,size=15032385536 \
404507
 -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \
404507
--object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node1,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node1,\
404507
 share=yes,size=15032385536 \
404507
 -numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \
404507
 -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \
404507
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args
404507
index e9a57a69e5..3c352fe035 100644
404507
--- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args
404507
+++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args
404507
@@ -11,13 +11,16 @@ QEMU_AUDIO_DRV=none \
404507
 -m 43008 \
404507
 -mem-prealloc \
404507
 -smp 32,sockets=1,cores=24,threads=1 \
404507
--object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node0,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\
404507
 share=yes,size=15032385536 \
404507
 -numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \
404507
--object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node1,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node1,\
404507
 share=yes,size=15032385536 \
404507
 -numa node,nodeid=1,cpus=2-3,memdev=ram-node1 \
404507
--object memory-backend-file,id=ram-node2,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node2,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node2,\
404507
 share=no,size=15032385536 \
404507
 -numa node,nodeid=2,cpus=4-5,memdev=ram-node2 \
404507
 -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \
404507
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args
404507
index 55db491719..d8e506c19e 100644
404507
--- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args
404507
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args
404507
@@ -10,17 +10,20 @@ QEMU_AUDIO_DRV=none \
404507
 -M pc \
404507
 -m size=4194304k,slots=16,maxmem=8388608k \
404507
 -smp 4,sockets=4,cores=1,threads=1 \
404507
--object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node0,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\
404507
 share=no,size=1073741824,host-nodes=0-3,policy=bind \
404507
 -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
404507
 -object memory-backend-file,id=ram-node1,prealloc=yes,\
404507
 mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,share=yes,size=1073741824,\
404507
 host-nodes=0-3,policy=bind \
404507
 -numa node,nodeid=1,cpus=1,memdev=ram-node1 \
404507
--object memory-backend-file,id=ram-node2,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node2,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node2,\
404507
 share=no,size=1073741824,host-nodes=0-3,policy=bind \
404507
 -numa node,nodeid=2,cpus=2,memdev=ram-node2 \
404507
--object memory-backend-file,id=ram-node3,mem-path=/var/lib/libvirt/qemu/ram,\
404507
+-object memory-backend-file,id=ram-node3,\
404507
+mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node3,\
404507
 share=no,size=1073741824,host-nodes=3,policy=bind \
404507
 -numa node,nodeid=3,cpus=3,memdev=ram-node3 \
404507
 -object memory-backend-file,id=memdimm0,prealloc=yes,\
404507
-- 
404507
2.15.0
404507