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