[libvirt] [PATCH v1 0/5] Predictable file names for memory-backend-file

As discussed here [1], for some types of environment it's important to allocate memory upfront. In such cases libvirt needs to reuse the paths. However, since we don't want to expose the paths anywhere, reversed approach is implemented. If enabled in config file, libvirt builds predictable paths for memory-backend-file. 1: https://www.redhat.com/archives/libvir-list/2017-October/msg01036.html As usual, you can also find all the patches on my github: https://github.com/zippy2/libvirt/tree/aliases_from_user_v2 (Why v2? Don't ask.) Michal Privoznik (5): conf: s/virDomainObjGetShortName/virDomainDefGetShortName/ qemu: Move memPath generation from memoryBackingDir to a separate function qemu.conf: Introduce memory_predictable_file_names qemuxml2argvtest: Test memory_predictable_file_names news: Document memory_predictable_file_names docs/news.xml | 10 ++ src/conf/domain_conf.c | 4 +- src/conf/domain_conf.h | 2 +- src/libvirt_private.syms | 2 +- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 5 + src/qemu/qemu_command.c | 9 +- src/qemu/qemu_conf.c | 92 +++++++++++++- src/qemu/qemu_conf.h | 11 ++ src/qemu/qemu_domain.c | 4 +- src/qemu/qemu_driver.c | 21 ++- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 141 +++++++++++++++------ src/qemu/qemu_process.h | 8 +- src/qemu/test_libvirtd_qemu.aug.in | 1 + .../qemuxml2argv-cpu-numa-memshared.args | 6 +- .../qemuxml2argv-fd-memory-numa-topology.args | 3 +- .../qemuxml2argv-fd-memory-numa-topology2.args | 6 +- .../qemuxml2argv-fd-memory-numa-topology3.args | 9 +- .../qemuxml2argv-hugepages-memaccess2.args | 9 +- tests/qemuxml2argvtest.c | 1 + 21 files changed, 279 insertions(+), 68 deletions(-) -- 2.13.6

This function works over domain definition and not domain object. Its name is thus misleading. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 4 ++-- src/conf/domain_conf.h | 2 +- src/libvirt_private.syms | 2 +- src/qemu/qemu_conf.c | 2 +- src/qemu/qemu_domain.c | 4 ++-- src/qemu/qemu_driver.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 77c20c697..58b75c672 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -27871,14 +27871,14 @@ virDomainDefHasMemballoon(const virDomainDef *def) #define VIR_DOMAIN_SHORT_NAME_MAX 20 /** - * virDomainObjGetShortName: + * virDomainDefGetShortName: * @vm: Machine for which to get a name * @unique: Make sure the name is unique (use id as well) * * Shorten domain name to avoid possible path length limitations. */ char * -virDomainObjGetShortName(const virDomainDef *def) +virDomainDefGetShortName(const virDomainDef *def) { wchar_t wshortname[VIR_DOMAIN_SHORT_NAME_MAX + 1] = {0}; size_t len = 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 38de70b15..bd541a9c5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3366,7 +3366,7 @@ int virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def, bool virDomainDefHasMemballoon(const virDomainDef *def) ATTRIBUTE_NONNULL(1); -char *virDomainObjGetShortName(const virDomainDef *def) ATTRIBUTE_NONNULL(1); +char *virDomainDefGetShortName(const virDomainDef *def) ATTRIBUTE_NONNULL(1); int virDomainGetBlkioParametersAssignFromDef(virDomainDefPtr def, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 448d962b2..3ebff18aa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -262,6 +262,7 @@ virDomainDefGetMemoryInitial; virDomainDefGetMemoryTotal; virDomainDefGetOnlineVcpumap; virDomainDefGetSecurityLabelDef; +virDomainDefGetShortName; virDomainDefGetVcpu; virDomainDefGetVcpuPinInfoHelper; virDomainDefGetVcpus; @@ -457,7 +458,6 @@ virDomainObjGetMetadata; virDomainObjGetOneDef; virDomainObjGetOneDefState; virDomainObjGetPersistentDef; -virDomainObjGetShortName; virDomainObjGetState; virDomainObjNew; virDomainObjParseNode; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ec61c9c52..bf6b334f4 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1659,7 +1659,7 @@ qemuGetDomainHugepagePath(const virDomainDef *def, virHugeTLBFSPtr hugepage) { char *base = qemuGetBaseHugepagePath(hugepage); - char *domPath = virDomainObjGetShortName(def); + char *domPath = virDomainDefGetShortName(def); char *ret = NULL; if (base && domPath) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c7c9e94da..e828fa2f6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1705,7 +1705,7 @@ qemuDomainSetPrivatePaths(virQEMUDriverPtr driver, { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; - char *domname = virDomainObjGetShortName(vm->def); + char *domname = virDomainDefGetShortName(vm->def); int ret = -1; if (!domname) @@ -8203,7 +8203,7 @@ qemuDomainGetPreservedMountPath(virQEMUDriverConfigPtr cfg, char *path = NULL; char *tmp; const char *suffix = mountpoint + strlen(DEVPREFIX); - char *domname = virDomainObjGetShortName(vm->def); + char *domname = virDomainDefGetShortName(vm->def); size_t off; if (!domname) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 32a416f9e..dacfca9a9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4079,7 +4079,7 @@ getAutoDumpPath(virQEMUDriverPtr driver, virDomainObjPtr vm) { char *dumpfile = NULL; - char *domname = virDomainObjGetShortName(vm->def); + char *domname = virDomainDefGetShortName(vm->def); char timestr[100]; struct tm time_info; time_t curtime = time(NULL); -- 2.13.6

In near future we will need more than just a plain VIR_STRDUP(). Better implement that in a separate function and in qemuBuildMemoryBackendStr() which is complicated enough already. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_conf.c | 18 ++++++++++++++++++ src/qemu/qemu_conf.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b1cfafa79..82d2fb2a3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3439,7 +3439,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps, } else { /* We can have both pagesize and mem source. If that's the case, * prefer hugepages as those are more specific. */ - if (VIR_STRDUP(memPath, cfg->memoryBackingDir) < 0) + if (qemuGetMemoryBackingPath(cfg, &memPath) < 0) goto cleanup; } diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index bf6b334f4..23dcc25e1 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1748,3 +1748,21 @@ qemuGetDomainHupageMemPath(const virDomainDef *def, return 0; } + + +/** + * qemuGetMemoryBackingPath: + * @cfg: the driver config + * @memPath: constructed path + * + * Constructs path to memory backing dir and stores it at @memPath. + * + * Returns: 0 on success, + * -1 otherwise (with error reported). + */ +int +qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg, + char **memPath) +{ + return VIR_STRDUP(*memPath, cfg->memoryBackingDir); +} diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 13b6f818a..9d6866816 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -363,4 +363,7 @@ int qemuGetDomainHupageMemPath(const virDomainDef *def, virQEMUDriverConfigPtr cfg, unsigned long long pagesize, char **memPath); + +int qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg, + char **memPath); #endif /* __QEMUD_CONF_H */ -- 2.13.6

In some cases management application needs to allocate memory for qemu upfront and then just let qemu use that. Since we don't want to expose path for memory-backend-file anywhere in the domain XML, we can have a configuration knob that when enabled generated predictable paths. In this case: $memoryBackingDir/libvirt/qemu/$shortName/$alias where $shortName is result of virDomainObjGetShortName(). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 5 ++ src/qemu/qemu_command.c | 9 +-- src/qemu/qemu_conf.c | 76 +++++++++++++++++++- src/qemu/qemu_conf.h | 10 ++- src/qemu/qemu_driver.c | 19 +++++ src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 141 ++++++++++++++++++++++++++----------- src/qemu/qemu_process.h | 8 +-- src/qemu/test_libvirtd_qemu.aug.in | 1 + 10 files changed, 220 insertions(+), 52 deletions(-) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index c19bf3a43..77d466b14 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -114,6 +114,7 @@ module Libvirtd_qemu = let gluster_debug_level_entry = int_entry "gluster_debug_level" let memory_entry = str_entry "memory_backing_dir" + | bool_entry "memory_predictable_file_names" let vxhs_entry = bool_entry "vxhs_tls" | str_entry "vxhs_tls_x509_cert_dir" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 2e8370a5a..dc3098148 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -769,3 +769,8 @@ # This directory is used for memoryBacking source if configured as file. # NOTE: big files will be stored here #memory_backing_dir = "/var/lib/libvirt/qemu/ram" + +# Use predictable file names. If this is enabled, Libvirt constructs +# full paths for memory-backing-file objects. This is experimental +# feature and generated paths can change across releases. Don't use it. +#memory_predictable_file_names = 1 diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 82d2fb2a3..d6d2654cd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3439,7 +3439,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps, } else { /* We can have both pagesize and mem source. If that's the case, * prefer hugepages as those are more specific. */ - if (qemuGetMemoryBackingPath(cfg, &memPath) < 0) + if (qemuGetMemoryBackingPath(def, cfg, mem->info.alias, &memPath) < 0) goto cleanup; } @@ -3542,12 +3542,13 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def, unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa, cell); + if (virAsprintf(&alias, "ram-node%zu", cell) < 0) + goto cleanup; + *backendStr = NULL; mem.size = memsize; mem.targetNode = cell; - - if (virAsprintf(&alias, "ram-node%zu", cell) < 0) - goto cleanup; + mem.info.alias = alias; if ((rc = qemuBuildMemoryBackendStr(&props, &backendType, cfg, priv->qemuCaps, def, &mem, priv->autoNodeset, false)) < 0) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 23dcc25e1..34f411137 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -912,6 +912,10 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, if (virConfGetValueString(conf, "memory_backing_dir", &cfg->memoryBackingDir) < 0) goto cleanup; + if (virConfGetValueBool(conf, "memory_predictable_file_names", + &cfg->memoryPredictableFileNames) < 0) + goto cleanup; + ret = 0; cleanup: @@ -1750,9 +1754,53 @@ qemuGetDomainHupageMemPath(const virDomainDef *def, } +int +qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg, + char **path) +{ + if (!cfg->memoryPredictableFileNames) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("predictable file names are disabled")); + return -1; + } + + return virAsprintf(path, "%s/libvirt/qemu", cfg->memoryBackingDir); +} + + +int +qemuGetMemoryBackingDomainPath(const virDomainDef *def, + virQEMUDriverConfigPtr cfg, + char **path) +{ + char *shortName = NULL; + char *base = NULL; + int ret = -1; + + if (!cfg->memoryPredictableFileNames) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("predictable file names are disabled")); + return -1; + } + + if (!(shortName = virDomainDefGetShortName(def)) || + qemuGetMemoryBackingBasePath(cfg, &base) < 0 || + virAsprintf(path, "%s/%s", base, shortName) < 0) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(base); + VIR_FREE(shortName); + return ret; +} + + /** * qemuGetMemoryBackingPath: + * @def: domain definition * @cfg: the driver config + * @alias: memory object alias * @memPath: constructed path * * Constructs path to memory backing dir and stores it at @memPath. @@ -1761,8 +1809,32 @@ qemuGetDomainHupageMemPath(const virDomainDef *def, * -1 otherwise (with error reported). */ int -qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg, +qemuGetMemoryBackingPath(const virDomainDef *def, + virQEMUDriverConfigPtr cfg, + const char *alias, char **memPath) { - return VIR_STRDUP(*memPath, cfg->memoryBackingDir); + char *domainPath = NULL; + int ret = -1; + + if (cfg->memoryPredictableFileNames) { + if (!alias) { + /* This should never happen (TM) */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("memory device alias is not assigned")); + goto cleanup; + } + + if (qemuGetMemoryBackingDomainPath(def, cfg, &domainPath) < 0 || + virAsprintf(memPath, "%s/%s", domainPath, alias) < 0) + goto cleanup; + } else { + if (VIR_STRDUP(*memPath, cfg->memoryBackingDir) < 0) + goto cleanup; + } + + ret = 0; + cleanup: + VIR_FREE(domainPath); + return ret; } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 9d6866816..5b72788c9 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -203,6 +203,7 @@ struct _virQEMUDriverConfig { unsigned int glusterDebugLevel; char *memoryBackingDir; + bool memoryPredictableFileNames; bool vxhsTLS; char *vxhsTLSx509certdir; @@ -364,6 +365,13 @@ int qemuGetDomainHupageMemPath(const virDomainDef *def, unsigned long long pagesize, char **memPath); -int qemuGetMemoryBackingPath(virQEMUDriverConfigPtr cfg, +int qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg, + char **path); +int qemuGetMemoryBackingDomainPath(const virDomainDef *def, + virQEMUDriverConfigPtr cfg, + char **path); +int qemuGetMemoryBackingPath(const virDomainDef *def, + virQEMUDriverConfigPtr cfg, + const char *alias, char **memPath); #endif /* __QEMUD_CONF_H */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index dacfca9a9..7bdefd7e8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -630,6 +630,7 @@ qemuStateInitialize(bool privileged, uid_t run_uid = -1; gid_t run_gid = -1; char *hugepagePath = NULL; + char *memoryBackingPath = NULL; size_t i; if (VIR_ALLOC(qemu_driver) < 0) @@ -888,6 +889,23 @@ qemuStateInitialize(bool privileged, VIR_FREE(hugepagePath); } + if (cfg->memoryPredictableFileNames) { + if (qemuGetMemoryBackingBasePath(cfg, &memoryBackingPath) < 0) + goto error; + + if (virFileMakePath(memoryBackingPath) < 0) { + virReportSystemError(errno, + _("unable to create memory backing path %s"), + memoryBackingPath); + goto error; + } + if (privileged && + virFileUpdatePerm(memoryBackingPath, + 0, S_IXGRP | S_IXOTH) < 0) + goto error; + VIR_FREE(memoryBackingPath); + } + if (!(qemu_driver->closeCallbacks = virCloseCallbacksNew())) goto error; @@ -945,6 +963,7 @@ qemuStateInitialize(bool privileged, virObjectUnref(conn); VIR_FREE(driverConf); VIR_FREE(hugepagePath); + VIR_FREE(memoryBackingPath); qemuStateCleanup(); return -1; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 91f7f9ed6..5701c033b 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2077,7 +2077,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, priv->qemuCaps, vm->def, mem, NULL, true) < 0) goto cleanup; - if (qemuProcessBuildDestroyHugepagesPath(driver, vm, mem, true) < 0) + if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0) goto cleanup; if (qemuDomainNamespaceSetupMemory(driver, vm, mem) < 0) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fdc868912..5dea02718 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3324,60 +3324,121 @@ qemuProcessNeedHugepagesPath(virDomainDefPtr def, } +static bool +qemuProcessNeedMemoryBackingPath(virDomainDefPtr def, + virQEMUDriverConfigPtr cfg, + virDomainMemoryDefPtr mem) +{ + size_t i; + size_t numaNodes; + + if (!cfg->memoryPredictableFileNames) + return false; + + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE || + def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT) + return true; + + numaNodes = virDomainNumaGetNodeCount(def->numa); + for (i = 0; i < numaNodes; i++) { + if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i) + != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT) + return true; + } + + if (mem && + mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM && + (mem->access != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT || + (mem->targetNode >= 0 && + virDomainNumaGetNodeMemoryAccessMode(def->numa, mem->targetNode) + != VIR_DOMAIN_MEMORY_ACCESS_DEFAULT))) + return true; + + return false; +} + + +static int +qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, + virDomainDefPtr def, + const char *path, + bool build) +{ + if (build) { + if (virFileExists(path)) + return 0; + + if (virFileMakePathWithMode(path, 0700) < 0) { + virReportSystemError(errno, + _("Unable to create %s"), + path); + return -1; + } + + if (qemuSecurityDomainSetPathLabel(driver->securityManager, + def, path) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to label %s"), path); + return -1; + } + } else { + if (rmdir(path) < 0 && + errno != ENOENT) + VIR_WARN("Unable to remove hugepage path: %s (errno=%d)", + path, errno); + } + + return 0; +} + + int -qemuProcessBuildDestroyHugepagesPath(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainMemoryDefPtr mem, - bool build) +qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainMemoryDefPtr mem, + bool build) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - char *hugepagePath = NULL; + char *path = NULL; size_t i; - bool shouldBuild = false; + bool shouldBuildHP = false; + bool shouldBuildMB = false; int ret = -1; - if (build) - shouldBuild = qemuProcessNeedHugepagesPath(vm->def, mem); + if (build) { + shouldBuildHP = qemuProcessNeedHugepagesPath(vm->def, mem); + shouldBuildMB = qemuProcessNeedMemoryBackingPath(vm->def, cfg, mem); + } - if (!build || shouldBuild) { + if (!build || shouldBuildHP) { for (i = 0; i < cfg->nhugetlbfs; i++) { - VIR_FREE(hugepagePath); - hugepagePath = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]); + path = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]); - if (!hugepagePath) + if (!path) goto cleanup; - if (build) { - if (virFileExists(hugepagePath)) { - ret = 0; - goto cleanup; - } - - if (virFileMakePathWithMode(hugepagePath, 0700) < 0) { - virReportSystemError(errno, - _("Unable to create %s"), - hugepagePath); - goto cleanup; - } + if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def, + path, build) < 0) + goto cleanup; - if (qemuSecurityDomainSetPathLabel(driver->securityManager, - vm->def, hugepagePath) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Unable to set huge path in security driver")); - goto cleanup; - } - } else { - if (rmdir(hugepagePath) < 0 && - errno != ENOENT) - VIR_WARN("Unable to remove hugepage path: %s (errno=%d)", - hugepagePath, errno); - } + VIR_FREE(path); } } + if (!build || shouldBuildMB) { + if (qemuGetMemoryBackingDomainPath(vm->def, cfg, &path) < 0) + goto cleanup; + + if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def, + path, build) < 0) + goto cleanup; + + VIR_FREE(path); + } + ret = 0; cleanup: - VIR_FREE(hugepagePath); + VIR_FREE(path); virObjectUnref(cfg); return ret; } @@ -5550,7 +5611,7 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver, NULL) < 0) goto cleanup; - if (qemuProcessBuildDestroyHugepagesPath(driver, vm, NULL, true) < 0) + if (qemuProcessBuildDestroyMemoryPaths(driver, vm, NULL, true) < 0) goto cleanup; /* Ensure no historical cgroup for this VM is lying around bogus @@ -6254,7 +6315,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, goto endjob; } - qemuProcessBuildDestroyHugepagesPath(driver, vm, NULL, false); + qemuProcessBuildDestroyMemoryPaths(driver, vm, NULL, false); vm->def->id = -1; @@ -7112,7 +7173,7 @@ qemuProcessReconnect(void *opaque) goto cleanup; } - if (qemuProcessBuildDestroyHugepagesPath(driver, obj, NULL, true) < 0) + if (qemuProcessBuildDestroyMemoryPaths(driver, obj, NULL, true) < 0) goto error; if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 814b86d8a..cd9a72031 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -38,10 +38,10 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver, virDomainPausedReason reason, qemuDomainAsyncJob asyncJob); -int qemuProcessBuildDestroyHugepagesPath(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainMemoryDefPtr mem, - bool build); +int qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainMemoryDefPtr mem, + bool build); void qemuProcessAutostartAll(virQEMUDriverPtr driver); void qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver); diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index 688e5b9fd..2f0a1277d 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -100,3 +100,4 @@ module Test_libvirtd_qemu = { "1" = "mount" } } { "memory_backing_dir" = "/var/lib/libvirt/qemu/ram" } +{ "memory_predictable_file_names" = "1" } -- 2.13.6

On Mon, Oct 23, 2017 at 05:43:16PM +0200, Michal Privoznik wrote:
In some cases management application needs to allocate memory for qemu upfront and then just let qemu use that. Since we don't want to expose path for memory-backend-file anywhere in the domain XML, we can have a configuration knob that when enabled generated predictable paths. In this case:
$memoryBackingDir/libvirt/qemu/$shortName/$alias
where $shortName is result of virDomainObjGetShortName().
Looking at the current test cases, it seems that for huge pages we currently create a directory $hugepagesMountPoint/libvirt/qemu/$shortName and for non-hugepages we just use $memoryBackingDir (== /var/lib/libvirt/ram) In both cases, we then just let QEMU create a random tempfile name within these directories. So, IIUC, your proposal here is just making the non-hugepages case work the same way the hugepages case works, except that it is adding an extra level of $alias in the directory path. I don't think this extra level of nesting is really desirable, or needed. We should just give QEMU a filename, so that it doesn't create a random tempfile. This is achieved by simply doing a mkdir($memoryBackingDir/libvirt/qemu/$shortName) but then giving a mem-path=$memoryBackingDir/libvirt/qemu/$shortName/$alias QEMU will try to open that, and will get ENOENT, at which point it to O_CREAT that file with the exact name we've given, instead of using a tempfile name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 5 ++ src/qemu/qemu_command.c | 9 +-- src/qemu/qemu_conf.c | 76 +++++++++++++++++++- src/qemu/qemu_conf.h | 10 ++- src/qemu/qemu_driver.c | 19 +++++ src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 141 ++++++++++++++++++++++++++----------- src/qemu/qemu_process.h | 8 +-- src/qemu/test_libvirtd_qemu.aug.in | 1 + 10 files changed, 220 insertions(+), 52 deletions(-)
I'd expect to see current tests updated wrt the new naming scheme for paths
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index c19bf3a43..77d466b14 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -114,6 +114,7 @@ module Libvirtd_qemu = let gluster_debug_level_entry = int_entry "gluster_debug_level"
let memory_entry = str_entry "memory_backing_dir" + | bool_entry "memory_predictable_file_names"
let vxhs_entry = bool_entry "vxhs_tls" | str_entry "vxhs_tls_x509_cert_dir" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 2e8370a5a..dc3098148 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -769,3 +769,8 @@ # This directory is used for memoryBacking source if configured as file. # NOTE: big files will be stored here #memory_backing_dir = "/var/lib/libvirt/qemu/ram" + +# Use predictable file names. If this is enabled, Libvirt constructs +# full paths for memory-backing-file objects. This is experimental +# feature and generated paths can change across releases. Don't use it. +#memory_predictable_file_names = 1
I don't think we should expose this in the config file at all - it means we get 2 codepaths, one of which will never be tested by 99% of the deployments. I think we should just make normal mem paths uses the same naming scheme as hugepage mempaths unconditionally. There's no benefit to keeping the old naming scheme around. At the same time though, we don't need to promise anything wrt the new naming scheme. If someone wants to rely on it they can, but we're not going to promise forever compat.
+static int +qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, + virDomainDefPtr def, + const char *path, + bool build) +{ + if (build) { + if (virFileExists(path)) + return 0; + + if (virFileMakePathWithMode(path, 0700) < 0) { + virReportSystemError(errno, + _("Unable to create %s"), + path); + return -1; + }
NB, this creates potentially many levels in the dir hiearchy $memoryBackingDir/libvirt $memoryBackingDir/libvirt/qemu/ $memoryBackingDir/libvirt/qemu/$shortName $memoryBackingDir/libvirt/qemu/$shortName/$alias
+ + if (qemuSecurityDomainSetPathLabel(driver->securityManager, + def, path) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to label %s"), path); + return -1; + } + } else { + if (rmdir(path) < 0 && + errno != ENOENT) + VIR_WARN("Unable to remove hugepage path: %s (errno=%d)", + path, errno);
This only deletes $memoryBackingDir/libvirt/qemu/$shortName/$alias so we're leaving around $memoryBackingDir/libvirt/qemu/$shortName forever. So we need to delete both levels - leaving $memoryBackingDir/libvirt/qemu is ok for other guests though. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On 10/23/2017 06:47 PM, Daniel P. Berrange wrote:
On Mon, Oct 23, 2017 at 05:43:16PM +0200, Michal Privoznik wrote:
In some cases management application needs to allocate memory for qemu upfront and then just let qemu use that. Since we don't want to expose path for memory-backend-file anywhere in the domain XML, we can have a configuration knob that when enabled generated predictable paths. In this case:
$memoryBackingDir/libvirt/qemu/$shortName/$alias
where $shortName is result of virDomainObjGetShortName().
Looking at the current test cases, it seems that for huge pages we currently create a directory
$hugepagesMountPoint/libvirt/qemu/$shortName
and for non-hugepages we just use
$memoryBackingDir (== /var/lib/libvirt/ram)
In both cases, we then just let QEMU create a random tempfile name within these directories.
Correct.
So, IIUC, your proposal here is just making the non-hugepages case work the same way the hugepages case works, except that it is adding an extra level of $alias in the directory path.
Almost. $alias is actual file, not dir.
I don't think this extra level of nesting is really desirable, or needed. We should just give QEMU a filename, so that it doesn't create a random tempfile. This is achieved by simply doing a
mkdir($memoryBackingDir/libvirt/qemu/$shortName)
but then giving a
mem-path=$memoryBackingDir/libvirt/qemu/$shortName/$alias
Yes. That's exactly what I'm doing. A snippet from next patch where we can see this in action: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args index 5700c3413..352819429 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args @@ -13 +13,1 @@ QEMU_AUDIO_DRV=none \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\ And even though you're not disputing '/libvirt/qemu/' part in the path, I'll just point out for future reference that memoryBackingDir can be just any path in the system. It's just that the default is /var/lib/libvirt/qemu which makes the generated path ugly (and indeed renders the part redundant).
QEMU will try to open that, and will get ENOENT, at which point it to O_CREAT that file with the exact name we've given, instead of using a tempfile name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 5 ++ src/qemu/qemu_command.c | 9 +-- src/qemu/qemu_conf.c | 76 +++++++++++++++++++- src/qemu/qemu_conf.h | 10 ++- src/qemu/qemu_driver.c | 19 +++++ src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 141 ++++++++++++++++++++++++++----------- src/qemu/qemu_process.h | 8 +-- src/qemu/test_libvirtd_qemu.aug.in | 1 + 10 files changed, 220 insertions(+), 52 deletions(-)
I'd expect to see current tests updated wrt the new naming scheme for paths
See next patch.
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index c19bf3a43..77d466b14 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -114,6 +114,7 @@ module Libvirtd_qemu = let gluster_debug_level_entry = int_entry "gluster_debug_level"
let memory_entry = str_entry "memory_backing_dir" + | bool_entry "memory_predictable_file_names"
let vxhs_entry = bool_entry "vxhs_tls" | str_entry "vxhs_tls_x509_cert_dir" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 2e8370a5a..dc3098148 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -769,3 +769,8 @@ # This directory is used for memoryBacking source if configured as file. # NOTE: big files will be stored here #memory_backing_dir = "/var/lib/libvirt/qemu/ram" + +# Use predictable file names. If this is enabled, Libvirt constructs +# full paths for memory-backing-file objects. This is experimental +# feature and generated paths can change across releases. Don't use it. +#memory_predictable_file_names = 1
I don't think we should expose this in the config file at all - it means we get 2 codepaths, one of which will never be tested by 99% of the deployments.
I think we should just make normal mem paths uses the same naming scheme as hugepage mempaths unconditionally. There's no benefit to keeping the old naming scheme around.
At the same time though, we don't need to promise anything wrt the new naming scheme. If someone wants to rely on it they can, but we're not going to promise forever compat.
Even better! Cool.
+static int +qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, + virDomainDefPtr def, + const char *path, + bool build) +{ + if (build) { + if (virFileExists(path)) + return 0; + + if (virFileMakePathWithMode(path, 0700) < 0) { + virReportSystemError(errno, + _("Unable to create %s"), + path); + return -1; + }
NB, this creates potentially many levels in the dir hiearchy
$memoryBackingDir/libvirt $memoryBackingDir/libvirt/qemu/ $memoryBackingDir/libvirt/qemu/$shortName
Only these ^^ are dirs.
$memoryBackingDir/libvirt/qemu/$shortName/$alias
This is actual file.
+ + if (qemuSecurityDomainSetPathLabel(driver->securityManager, + def, path) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to label %s"), path); + return -1; + } + } else { + if (rmdir(path) < 0 && + errno != ENOENT) + VIR_WARN("Unable to remove hugepage path: %s (errno=%d)", + path, errno);
This only deletes
$memoryBackingDir/libvirt/qemu/$shortName/$alias
so we're leaving around
$memoryBackingDir/libvirt/qemu/$shortName
Is that so? I'm fairly certain it removes $memoryBackingDir/libvirt/qemu/$shortName Michal

On Mon, Oct 23, 2017 at 07:10:04PM +0200, Michal Privoznik wrote:
On 10/23/2017 06:47 PM, Daniel P. Berrange wrote:
On Mon, Oct 23, 2017 at 05:43:16PM +0200, Michal Privoznik wrote:
In some cases management application needs to allocate memory for qemu upfront and then just let qemu use that. Since we don't want to expose path for memory-backend-file anywhere in the domain XML, we can have a configuration knob that when enabled generated predictable paths. In this case:
$memoryBackingDir/libvirt/qemu/$shortName/$alias
where $shortName is result of virDomainObjGetShortName().
Looking at the current test cases, it seems that for huge pages we currently create a directory
$hugepagesMountPoint/libvirt/qemu/$shortName
and for non-hugepages we just use
$memoryBackingDir (== /var/lib/libvirt/ram)
In both cases, we then just let QEMU create a random tempfile name within these directories.
Correct.
So, IIUC, your proposal here is just making the non-hugepages case work the same way the hugepages case works, except that it is adding an extra level of $alias in the directory path.
Almost. $alias is actual file, not dir.
Ah, ok, I couldn't see that from the diff :-)
I don't think this extra level of nesting is really desirable, or needed. We should just give QEMU a filename, so that it doesn't create a random tempfile. This is achieved by simply doing a
mkdir($memoryBackingDir/libvirt/qemu/$shortName)
but then giving a
mem-path=$memoryBackingDir/libvirt/qemu/$shortName/$alias
Yes. That's exactly what I'm doing. A snippet from next patch where we can see this in action:
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args index 5700c3413..352819429 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args @@ -13 +13,1 @@ QEMU_AUDIO_DRV=none \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\
And even though you're not disputing '/libvirt/qemu/' part in the path, I'll just point out for future reference that memoryBackingDir can be just any path in the system. It's just that the default is /var/lib/libvirt/qemu which makes the generated path ugly (and indeed renders the part redundant).
Yeah, that makes sense, even if it feels wierd. Better to be consistent than to try to special case this. That said, it would be reasonable to consider /var/lib/libvirt/ram as default mem path, given we include the driver name.
QEMU will try to open that, and will get ENOENT, at which point it to O_CREAT that file with the exact name we've given, instead of using a tempfile name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 5 ++ src/qemu/qemu_command.c | 9 +-- src/qemu/qemu_conf.c | 76 +++++++++++++++++++- src/qemu/qemu_conf.h | 10 ++- src/qemu/qemu_driver.c | 19 +++++ src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 141 ++++++++++++++++++++++++++----------- src/qemu/qemu_process.h | 8 +-- src/qemu/test_libvirtd_qemu.aug.in | 1 + 10 files changed, 220 insertions(+), 52 deletions(-)
I'd expect to see current tests updated wrt the new naming scheme for paths
See next patch.
Ok, when you get rid of the config option, I guess you'll need to merge that into this patch to avoid temporary regression in tests.
NB, this creates potentially many levels in the dir hiearchy
$memoryBackingDir/libvirt $memoryBackingDir/libvirt/qemu/ $memoryBackingDir/libvirt/qemu/$shortName
Only these ^^ are dirs.
$memoryBackingDir/libvirt/qemu/$shortName/$alias
This is actual file.
Ok
+ if (qemuSecurityDomainSetPathLabel(driver->securityManager, + def, path) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to label %s"), path); + return -1; + } + } else { + if (rmdir(path) < 0 && + errno != ENOENT) + VIR_WARN("Unable to remove hugepage path: %s (errno=%d)", + path, errno);
This only deletes
$memoryBackingDir/libvirt/qemu/$shortName/$alias
so we're leaving around
$memoryBackingDir/libvirt/qemu/$shortName
Is that so? I'm fairly certain it removes $memoryBackingDir/libvirt/qemu/$shortName
If you say so, I'll believe you, since I can't really follow the diff too well. One other thought though - when QEMU uses a named file, rather than an autogenerated tempfile, I don't see where QEMU calls unlink() on the file. Normally for tempfiles it calls unlink() immediately, but for named files it doesn't, and I don't see where it does it during shutdown. Even if it did though, I think libvirt needs to explicitly unlink() each named file to be safe in case QEMU crashes. Maybe your patchseries already does this, but if not.... Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args | 6 ++++-- tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args | 3 ++- .../qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args | 6 ++++-- .../qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args | 9 ++++++--- tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args | 9 ++++++--- tests/qemuxml2argvtest.c | 1 + 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args index 5700c3413..352819429 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.args @@ -10,10 +10,12 @@ QEMU_AUDIO_DRV=none \ -M pc \ -m 214 \ -smp 16,sockets=2,cores=4,threads=2 \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\ share=yes,size=112197632 \ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ --object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node1,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node1,\ share=no,size=112197632 \ -numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args index 12f3d8ab8..fa1353259 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args @@ -11,7 +11,8 @@ QEMU_AUDIO_DRV=none \ -m 14336 \ -mem-prealloc \ -smp 8,sockets=1,cores=8,threads=1 \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\ share=yes,size=15032385536 \ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args index 585e4d506..6f73a1b99 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args @@ -11,10 +11,12 @@ QEMU_AUDIO_DRV=none \ -m 28672 \ -mem-prealloc \ -smp 20,sockets=1,cores=8,threads=1 \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\ share=no,size=15032385536 \ -numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ --object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node1,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node1,\ share=yes,size=15032385536 \ -numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \ -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args index e9a57a69e..3c352fe03 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args @@ -11,13 +11,16 @@ QEMU_AUDIO_DRV=none \ -m 43008 \ -mem-prealloc \ -smp 32,sockets=1,cores=24,threads=1 \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node0,\ share=yes,size=15032385536 \ -numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \ --object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node1,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node1,\ share=yes,size=15032385536 \ -numa node,nodeid=1,cpus=2-3,memdev=ram-node1 \ --object memory-backend-file,id=ram-node2,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node2,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node2,\ share=no,size=15032385536 \ -numa node,nodeid=2,cpus=4-5,memdev=ram-node2 \ -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args index 55db49171..d8e506c19 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-memaccess2.args @@ -10,17 +10,20 @@ QEMU_AUDIO_DRV=none \ -M pc \ -m size=4194304k,slots=16,maxmem=8388608k \ -smp 4,sockets=4,cores=1,threads=1 \ --object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node0,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node0,\ share=no,size=1073741824,host-nodes=0-3,policy=bind \ -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ -object memory-backend-file,id=ram-node1,prealloc=yes,\ mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,share=yes,size=1073741824,\ host-nodes=0-3,policy=bind \ -numa node,nodeid=1,cpus=1,memdev=ram-node1 \ --object memory-backend-file,id=ram-node2,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node2,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node2,\ share=no,size=1073741824,host-nodes=0-3,policy=bind \ -numa node,nodeid=2,cpus=2,memdev=ram-node2 \ --object memory-backend-file,id=ram-node3,mem-path=/var/lib/libvirt/qemu/ram,\ +-object memory-backend-file,id=ram-node3,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-QEMUGuest1/ram-node3,\ share=no,size=1073741824,host-nodes=3,policy=bind \ -numa node,nodeid=3,cpus=3,memdev=ram-node3 \ -object memory-backend-file,id=memdimm0,prealloc=yes,\ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 03b1bcbcf..86ef89433 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -619,6 +619,7 @@ mymain(void) VIR_FREE(driver.config->memoryBackingDir); if (VIR_STRDUP_QUIET(driver.config->memoryBackingDir, "/var/lib/libvirt/qemu/ram") < 0) return EXIT_FAILURE; + driver.config->memoryPredictableFileNames = true; # define DO_TEST_FULL(name, migrateFrom, migrateFd, flags, \ parseFlags, gic, ...) \ -- 2.13.6

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/news.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 989b82aa5..bba1f9968 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -49,6 +49,16 @@ easily. </description> </change> + <change> + <summary> + Allow generation of predictable paths for qemu memory backends + </summary> + <description> + If enabled in qemu.conf libvirt generates predictable paths for + memory-backend-file objects for qemu domains. However, this is + experimental feature and shouldn't be used. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.13.6
participants (2)
-
Daniel P. Berrange
-
Michal Privoznik