[PATCH 0/9] Another round of qemu:///embed fixes

After my first round of patches got merged [1], some new problems arose. They are not as serious (except maybe for 7/9) but they are still problematic for sure. Mostly in scenarios where a mgmt application uses the embedded driver and has multiple forks/instances sharing essentially the same config (e.g. it writes the same qemu.conf into different roots). Thing is, we may generate conflicting paths across these instances. What I've done here is, I looked at what paths can be set from qemu.conf and on their usage. Then I've grepped for virDomainDefGetShortName() and looked at its usages, because that has proven to be common denominator in patches 7-9. Some usages of the function are safe though. When the usage involves a path that is derived from the root and can't be overridden in qemu.conf it is safe. For instance, qemuDBusGetAddress() calls virDomainDefGetShortName() to construct a path to a UNIX socket. But the path has cfg->dbusStateDir prefix which is derived from cfg->stateDir which in turn is derived from the root. At the same time, neither of these paths can be overridden in qemu.conf. Therefore, no conflicts can occur. Michal Prívozník (9): tests: Fix virQEMUDriverConfigNew() calling with respect to @root conf: Move virDomainGenerateMachineName to hypervisor/ virDomainDriverGenerateMachineName: Factor out embed path hashing qemu: Introduce virQEMUDriverGetEmbedRoot qemuDomainGetMachineName: Access embeddedRoot from driver rather than cfg Revert "qemu_conf: Track embed root dir" qemu: Make hugepages path generation embed driver aware qemu: Make memory path generation embed driver aware qemu: Make auto dump path generation embed driver aware src/conf/domain_conf.c | 72 ---------------------------- src/conf/domain_conf.h | 7 --- src/hypervisor/domain_driver.c | 88 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 11 +++++ src/libvirt_private.syms | 3 +- src/lxc/lxc_domain.c | 3 +- src/qemu/qemu_command.c | 19 ++++---- src/qemu/qemu_conf.c | 64 ++++++++++++++++++------- src/qemu/qemu_conf.h | 23 ++++----- src/qemu/qemu_domain.c | 9 ++-- src/qemu/qemu_driver.c | 10 +++- src/qemu/qemu_process.c | 7 ++- tests/domaincapstest.c | 2 +- tests/testutilsqemu.c | 2 +- tests/virsystemdtest.c | 5 +- 15 files changed, 191 insertions(+), 134 deletions(-) -- 2.24.1

The virQEMUDriverConfigNew() accepts path to root directory for embed mode as an argument. If the argument is not NULL it uses the passed value as prefix for some internal paths (e.g. cfg->libDir). If it is NULL though, it looks if the other argument, @privileged is true or false and generates internal paths accordingly. But when calling the function from the test suite, instead of passing NULL for @root, an empty string is passed. Fortunately, this doesn't create a problem because in both problematic cases the generated paths are "fixed" to point somewhere into build dir or the code which is tested doesn't access them. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/domaincapstest.c | 2 +- tests/testutilsqemu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index fb803eaa47..c3a9f4ef91 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -369,7 +369,7 @@ mymain(void) #endif #if WITH_QEMU - virQEMUDriverConfigPtr cfg = virQEMUDriverConfigNew(false, ""); + virQEMUDriverConfigPtr cfg = virQEMUDriverConfigNew(false, NULL); if (!cfg) return EXIT_FAILURE; diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index f3b4e2b3b2..cb68ac0488 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -390,7 +390,7 @@ int qemuTestDriverInit(virQEMUDriver *driver) return -1; driver->hostarch = virArchFromHost(); - driver->config = virQEMUDriverConfigNew(false, ""); + driver->config = virQEMUDriverConfigNew(false, NULL); if (!driver->config) goto error; -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
The virQEMUDriverConfigNew() accepts path to root directory for embed mode as an argument. If the argument is not NULL it uses the passed value as prefix for some internal paths (e.g. cfg->libDir). If it is NULL though, it looks if the other argument, @privileged is true or false and generates internal paths accordingly. But when calling the function from the test suite, instead of passing NULL for @root, an empty string is passed. Fortunately, this doesn't create a problem because in both problematic cases the generated paths are "fixed" to point somewhere into build dir or the code which is tested doesn't access them.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/domaincapstest.c | 2 +- tests/testutilsqemu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Andrea Bolognani <abologna@redhat.com> -- Andrea Bolognani / Red Hat / Virtualization

The virDomainGenerateMachineName() function doesn't belong in src/conf/ really, because it has nothing to do with domain XML parsing. It landed there because of lack of better place in the past. But now that we have src/hypervisor/ the function should live there. At the same time, the function name is changed to match new location. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 72 --------------------------------- src/conf/domain_conf.h | 7 ---- src/hypervisor/domain_driver.c | 74 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 7 ++++ src/libvirt_private.syms | 2 +- src/lxc/lxc_domain.c | 3 +- src/qemu/qemu_domain.c | 7 ++-- tests/virsystemdtest.c | 5 ++- 8 files changed, 91 insertions(+), 86 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 27bc5a797b..239455ef58 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -62,7 +62,6 @@ #include "virdomainsnapshotobjlist.h" #include "virdomaincheckpointobjlist.h" #include "virutil.h" -#include "vircrypto.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -31032,77 +31031,6 @@ virDomainDiskSetBlockIOTune(virDomainDiskDefPtr disk, return 0; } -#define HOSTNAME_CHARS \ - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-" - -static void -virDomainMachineNameAppendValid(virBufferPtr buf, - const char *name) -{ - bool skip = true; - - for (; *name; name++) { - if (strlen(virBufferCurrentContent(buf)) >= 64) - break; - - if (*name == '.' || *name == '-') { - if (!skip) - virBufferAddChar(buf, *name); - skip = true; - continue; - } - - skip = false; - - if (!strchr(HOSTNAME_CHARS, *name)) - continue; - - virBufferAddChar(buf, *name); - } - - /* trailing dashes or dots are not allowed */ - virBufferTrimChars(buf, "-."); -} - -#undef HOSTNAME_CHARS - -char * -virDomainGenerateMachineName(const char *drivername, - const char *root, - int id, - const char *name, - bool privileged) -{ - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAsprintf(&buf, "%s-", drivername); - - if (root) { - g_autofree char *hash = NULL; - - /* When two embed drivers start two domains with the same @name and @id - * we would generate a non-unique name. Include parts of hashed @root - * which guarantees uniqueness. The first 8 characters of SHA256 ought - * to be enough for anybody. */ - if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256, root, &hash) < 0) - return NULL; - - virBufferAsprintf(&buf, "embed-%.8s-", hash); - } else if (!privileged) { - g_autofree char *username = NULL; - if (!(username = virGetUserName(geteuid()))) { - virBufferFreeAndReset(&buf); - return NULL; - } - virBufferAsprintf(&buf, "%s-", username); - } - - virBufferAsprintf(&buf, "%d-", id); - virDomainMachineNameAppendValid(&buf, name); - - return virBufferContentAndReset(&buf); -} - /** * virDomainNetTypeSharesHostView: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 33875d942f..575290a6ac 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3649,13 +3649,6 @@ virDomainGetBlkioParametersAssignFromDef(virDomainDefPtr def, int virDomainDiskSetBlockIOTune(virDomainDiskDefPtr disk, virDomainBlockIoTuneInfo *info); -char * -virDomainGenerateMachineName(const char *drivername, - const char *root, - int id, - const char *name, - bool privileged); - bool virDomainNetTypeSharesHostView(const virDomainNetDef *net); diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index fc5b6eeefe..7bf0fb3f98 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -23,10 +23,84 @@ #include "domain_driver.h" #include "viralloc.h" #include "virstring.h" +#include "vircrypto.h" +#include "virutil.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN +#define HOSTNAME_CHARS \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-" + +static void +virDomainMachineNameAppendValid(virBufferPtr buf, + const char *name) +{ + bool skip = true; + + for (; *name; name++) { + if (strlen(virBufferCurrentContent(buf)) >= 64) + break; + + if (*name == '.' || *name == '-') { + if (!skip) + virBufferAddChar(buf, *name); + skip = true; + continue; + } + + skip = false; + + if (!strchr(HOSTNAME_CHARS, *name)) + continue; + + virBufferAddChar(buf, *name); + } + + /* trailing dashes or dots are not allowed */ + virBufferTrimChars(buf, "-."); +} + +#undef HOSTNAME_CHARS + +char * +virDomainDriverGenerateMachineName(const char *drivername, + const char *root, + int id, + const char *name, + bool privileged) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&buf, "%s-", drivername); + + if (root) { + g_autofree char *hash = NULL; + + /* When two embed drivers start two domains with the same @name and @id + * we would generate a non-unique name. Include parts of hashed @root + * which guarantees uniqueness. The first 8 characters of SHA256 ought + * to be enough for anybody. */ + if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256, root, &hash) < 0) + return NULL; + + virBufferAsprintf(&buf, "embed-%.8s-", hash); + } else if (!privileged) { + g_autofree char *username = NULL; + if (!(username = virGetUserName(geteuid()))) { + virBufferFreeAndReset(&buf); + return NULL; + } + virBufferAsprintf(&buf, "%s-", username); + } + + virBufferAsprintf(&buf, "%d-", id); + virDomainMachineNameAppendValid(&buf, name); + + return virBufferContentAndReset(&buf); +} + + /* Modify dest_array to reflect all blkio device changes described in * src_array. */ int diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index b6d5e66bba..c52e37f038 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -22,6 +22,13 @@ #include "domain_conf.h" +char * +virDomainDriverGenerateMachineName(const char *drivername, + const char *root, + int id, + const char *name, + bool privileged); + int virDomainDriverMergeBlkioDevice(virBlkioDevicePtr *dest_array, size_t *dest_size, virBlkioDevicePtr src_array, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3f032c7963..69f278f6fb 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -406,7 +406,6 @@ virDomainFSTypeFromString; virDomainFSTypeToString; virDomainFSWrpolicyTypeFromString; virDomainFSWrpolicyTypeToString; -virDomainGenerateMachineName; virDomainGetBlkioParametersAssignFromDef; virDomainGetFilesystemForTarget; virDomainGraphicsAuthConnectedTypeFromString; @@ -1403,6 +1402,7 @@ virDomainCgroupSetupMemtune; # hypervisor/domain_driver.h +virDomainDriverGenerateMachineName; virDomainDriverMergeBlkioDevice; virDomainDriverParseBlkioDeviceStr; virDomainDriverSetupPersistentDefBlkioParams; diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c index ebd2c2b56e..59f803837a 100644 --- a/src/lxc/lxc_domain.c +++ b/src/lxc/lxc_domain.c @@ -31,6 +31,7 @@ #include "virtime.h" #include "virsystemd.h" #include "virinitctl.h" +#include "domain_driver.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -406,7 +407,7 @@ virLXCDomainGetMachineName(virDomainDefPtr def, pid_t pid) } if (!ret) - ret = virDomainGenerateMachineName("lxc", NULL, def->id, def->name, true); + ret = virDomainDriverGenerateMachineName("lxc", NULL, def->id, def->name, true); return ret; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2c9fb47d17..b921126e1c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -44,6 +44,7 @@ #include "virfile.h" #include "domain_addr.h" #include "domain_capabilities.h" +#include "domain_driver.h" #include "domain_event.h" #include "virtime.h" #include "virnetdevopenvswitch.h" @@ -16490,9 +16491,9 @@ qemuDomainGetMachineName(virDomainObjPtr vm) } if (!ret) - ret = virDomainGenerateMachineName("qemu", cfg->root, - vm->def->id, vm->def->name, - virQEMUDriverIsPrivileged(driver)); + ret = virDomainDriverGenerateMachineName("qemu", cfg->root, + vm->def->id, vm->def->name, + virQEMUDriverIsPrivileged(driver)); return ret; } diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c index 050941dce8..e7dcdea8e9 100644 --- a/tests/virsystemdtest.c +++ b/tests/virsystemdtest.c @@ -34,6 +34,7 @@ # include "virlog.h" # include "virmock.h" # include "rpc/virnetsocket.h" +# include "domain_driver.h" # define VIR_FROM_THIS VIR_FROM_NONE VIR_LOG_INIT("tests.systemdtest"); @@ -414,8 +415,8 @@ testMachineName(const void *opaque) int ret = -1; char *actual = NULL; - if (!(actual = virDomainGenerateMachineName("qemu", data->root, - data->id, data->name, true))) + if (!(actual = virDomainDriverGenerateMachineName("qemu", data->root, + data->id, data->name, true))) goto cleanup; if (STRNEQ(actual, data->expected)) { -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
The virDomainGenerateMachineName() function doesn't belong in src/conf/ really, because it has nothing to do with domain XML parsing. It landed there because of lack of better place in the past. But now that we have src/hypervisor/ the function should live there. At the same time, the function name is changed to match new location.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/conf/domain_conf.c | 72 --------------------------------- src/conf/domain_conf.h | 7 ---- src/hypervisor/domain_driver.c | 74 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 7 ++++ src/libvirt_private.syms | 2 +- src/lxc/lxc_domain.c | 3 +- src/qemu/qemu_domain.c | 7 ++-- tests/virsystemdtest.c | 5 ++- 8 files changed, 91 insertions(+), 86 deletions(-)
Reviewed-by: Andrea Bolognani <abologna@redhat.com> -- Andrea Bolognani / Red Hat / Virtualization

The code that generates "qemu-embed-$hash" is going to be useful in more places. Separate it out into a function. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/hypervisor/domain_driver.c | 42 ++++++++++++++++++++++------------ src/hypervisor/domain_driver.h | 4 ++++ src/libvirt_private.syms | 1 + 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 7bf0fb3f98..8c252f211b 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -28,6 +28,22 @@ #define VIR_FROM_THIS VIR_FROM_DOMAIN +char * +virDomainDriverHashRoot(const char *drivername, + const char *root) +{ + g_autofree char *hash = NULL; + + if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256, root, &hash) < 0) + return NULL; + + /* When two embed drivers start two domains with the same @name and @id + * we would generate a non-unique name. Include parts of hashed @root + * which guarantees uniqueness. The first 8 characters of SHA256 ought + * to be enough for anybody. */ + return g_strdup_printf("%s-embed-%.8s", drivername, hash); +} + #define HOSTNAME_CHARS \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-" @@ -72,26 +88,24 @@ virDomainDriverGenerateMachineName(const char *drivername, { virBuffer buf = VIR_BUFFER_INITIALIZER; - virBufferAsprintf(&buf, "%s-", drivername); - if (root) { g_autofree char *hash = NULL; - /* When two embed drivers start two domains with the same @name and @id - * we would generate a non-unique name. Include parts of hashed @root - * which guarantees uniqueness. The first 8 characters of SHA256 ought - * to be enough for anybody. */ - if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256, root, &hash) < 0) + if (!(hash = virDomainDriverHashRoot(drivername, root))) return NULL; - virBufferAsprintf(&buf, "embed-%.8s-", hash); - } else if (!privileged) { - g_autofree char *username = NULL; - if (!(username = virGetUserName(geteuid()))) { - virBufferFreeAndReset(&buf); - return NULL; + virBufferAsprintf(&buf, "%s-", hash); + } else { + virBufferAsprintf(&buf, "%s-", drivername); + if (!privileged) { + + g_autofree char *username = NULL; + if (!(username = virGetUserName(geteuid()))) { + virBufferFreeAndReset(&buf); + return NULL; + } + virBufferAsprintf(&buf, "%s-", username); } - virBufferAsprintf(&buf, "%s-", username); } virBufferAsprintf(&buf, "%d-", id); diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index c52e37f038..6d07eeddd1 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -22,6 +22,10 @@ #include "domain_conf.h" +char * +virDomainDriverHashRoot(const char *drivername, + const char *root); + char * virDomainDriverGenerateMachineName(const char *drivername, const char *root, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 69f278f6fb..997904150d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1403,6 +1403,7 @@ virDomainCgroupSetupMemtune; # hypervisor/domain_driver.h virDomainDriverGenerateMachineName; +virDomainDriverHashRoot; virDomainDriverMergeBlkioDevice; virDomainDriverParseBlkioDeviceStr; virDomainDriverSetupPersistentDefBlkioParams; -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
The code that generates "qemu-embed-$hash" is going to be useful in more places. Separate it out into a function.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/hypervisor/domain_driver.c | 42 ++++++++++++++++++++++------------ src/hypervisor/domain_driver.h | 4 ++++ src/libvirt_private.syms | 1 + 3 files changed, 33 insertions(+), 14 deletions(-)
[...]
+char * +virDomainDriverHashRoot(const char *drivername, + const char *root)
virDomainDriverGenerateRootHash(), perhaps? Regardless, Reviewed-by: Andrea Bolognani <abologna@redhat.com> -- Andrea Bolognani / Red Hat / Virtualization

This function returns embeddedRoot member of the driver structure. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_conf.c | 12 ++++++++++++ src/qemu/qemu_conf.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 15837cece4..fb7c5a1a8a 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1230,6 +1230,18 @@ virQEMUDriverIsPrivileged(virQEMUDriverPtr driver) return driver->privileged; } +/* virQEMUDriverGetEmbedRoot: + * @driver: the QEMU driver + * + * Returns root directory specified in connection URI for embed + * mode, NULL otherwise. + */ +const char * +virQEMUDriverGetEmbedRoot(virQEMUDriverPtr driver) +{ + return driver->embeddedRoot; +} + virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver, const char *defsecmodel) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 14f9b9e81e..77e984ccdc 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -334,6 +334,7 @@ virQEMUDriverConfigSetDefaults(virQEMUDriverConfigPtr cfg); virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver); bool virQEMUDriverIsPrivileged(virQEMUDriverPtr driver); +const char *virQEMUDriverGetEmbedRoot(virQEMUDriverPtr driver); virCapsHostNUMAPtr virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver); virCPUDefPtr virQEMUDriverGetHostCPU(virQEMUDriverPtr driver); -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
This function returns embeddedRoot member of the driver structure.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_conf.c | 12 ++++++++++++ src/qemu/qemu_conf.h | 1 + 2 files changed, 13 insertions(+)
Reviewed-by: Andrea Bolognani <abologna@redhat.com> -- Andrea Bolognani / Red Hat / Virtualization

The cfg->root is going away, therefore get the info right from the driver structure. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b921126e1c..e0a2f3c695 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -16481,7 +16481,6 @@ qemuDomainGetMachineName(virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv = vm->privateData; virQEMUDriverPtr driver = priv->driver; - g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); char *ret = NULL; if (vm->pid > 0) { @@ -16491,7 +16490,8 @@ qemuDomainGetMachineName(virDomainObjPtr vm) } if (!ret) - ret = virDomainDriverGenerateMachineName("qemu", cfg->root, + ret = virDomainDriverGenerateMachineName("qemu", + virQEMUDriverGetEmbedRoot(driver), vm->def->id, vm->def->name, virQEMUDriverIsPrivileged(driver)); -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
The cfg->root is going away, therefore get the info right from the driver structure.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Andrea Bolognani <abologna@redhat.com> Note that, even after this patch, there are multiple cases where drv->embeddedRoot is accessed directly instead of going through virQEMUDriverGetEmbedRoot(). Can you please post a separate patch taking care of that? -- Andrea Bolognani / Red Hat / Virtualization

This reverts commit 06a19921b6a522cd7b4d352c9320909752947de3. What I haven't realized when writing this ^^ commit is that the virQEMUDriver structure already stores the root directory path. And since the pointer is immutable it can be accessed right from the structure and thus there is no need to duplicate it in the driver config. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_conf.c | 2 -- src/qemu/qemu_conf.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index fb7c5a1a8a..6eb655fe21 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -115,7 +115,6 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged, if (root) { cfg->uri = g_strdup_printf("qemu:///embed?root=%s", root); - cfg->root = g_strdup(root); } else { cfg->uri = g_strdup(privileged ? "qemu:///system" : "qemu:///session"); } @@ -302,7 +301,6 @@ static void virQEMUDriverConfigDispose(void *obj) virStringListFree(cfg->cgroupDeviceACL); VIR_FREE(cfg->uri); - VIR_FREE(cfg->root); VIR_FREE(cfg->configBaseDir); VIR_FREE(cfg->configDir); diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 77e984ccdc..0f0eb60c69 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -76,8 +76,6 @@ struct _virQEMUDriverConfig { virObject parent; char *uri; - char *root; /* The root directory for embed driver, - NULL for system/session connections */ uid_t user; gid_t group; -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote:
This reverts commit 06a19921b6a522cd7b4d352c9320909752947de3.
What I haven't realized when writing this ^^ commit is that the virQEMUDriver structure already stores the root directory path. And since the pointer is immutable it can be accessed right from the structure and thus there is no need to duplicate it in the driver config.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_conf.c | 2 -- src/qemu/qemu_conf.h | 2 -- 2 files changed, 4 deletions(-)
Funnily enough, when reviewing the original patch I wanted to point out that something like "embedRoot" would have been a better name for the member, but then opted to leave out the bikeshedding... I wonder if we would have realized earlier about this if I hadn't :) Reviewed-by: Andrea Bolognani <abologna@redhat.com> -- Andrea Bolognani / Red Hat / Virtualization

So far, libvirt generates the following path for hugepages: $mnt/libvirt/qemu/$id-$shortName where $mnt is the mount point of hugetlbfs corresponding to hugepages of desired size (e.g. /dev/hugepages), $id is domain ID and $shortName is shortened version of domain name. So for instance, the generated path may look something like this: /dev/hugepages/libvirt/qemu/1-QEMUGuest But this won't work with embed driver really, because if there are two instances of embed driver, and they both want to start a domain with the same name and with hugepages, both drivers will generate the same path which is not desired. Fortunately, we can reuse the approach for machined name generation (v6.1.0-178-gc9bd08ee35) and include part of hash of the root in the generated path. Note, the important change is in qemuGetBaseHugepagePath(). The rest is needed to pass driver around. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 4 ++-- src/qemu/qemu_conf.c | 24 +++++++++++++++++------- src/qemu/qemu_conf.h | 10 ++++++---- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3a772fa3f3..6c21d28510 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3465,7 +3465,7 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, if (!priv->memPrealloc) prealloc = true; } else if (useHugepage) { - if (qemuGetDomainHupageMemPath(def, cfg, pagesize, &memPath) < 0) + if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, &memPath) < 0) return -1; if (!priv->memPrealloc) prealloc = true; @@ -7249,7 +7249,7 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, if (!pagesize && qemuBuildMemoryGetDefaultPagesize(cfg, &pagesize) < 0) return -1; - if (qemuGetDomainHupageMemPath(def, cfg, pagesize, &mem_path) < 0) + if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, &mem_path) < 0) return -1; } else if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { if (qemuGetMemoryBackingPath(def, cfg, "ram", &mem_path) < 0) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 6eb655fe21..f2e3111312 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -40,6 +40,7 @@ #include "virxml.h" #include "virlog.h" #include "cpu/cpu.h" +#include "domain_driver.h" #include "domain_nwfilter.h" #include "virfile.h" #include "virsocket.h" @@ -1894,21 +1895,29 @@ qemuTranslateSnapshotDiskSourcePool(virDomainSnapshotDiskDefPtr def) } char * -qemuGetBaseHugepagePath(virHugeTLBFSPtr hugepage) +qemuGetBaseHugepagePath(virQEMUDriverPtr driver, + virHugeTLBFSPtr hugepage) { + const char *root = virQEMUDriverGetEmbedRoot(driver); char *ret; - ret = g_strdup_printf("%s/libvirt/qemu", hugepage->mnt_dir); + if (root) { + g_autofree char * hash = virDomainDriverHashRoot(QEMU_DRIVER_NAME, root); + ret = g_strdup_printf("%s/libvirt/%s", hugepage->mnt_dir, hash); + } else { + ret = g_strdup_printf("%s/libvirt/qemu", hugepage->mnt_dir); + } return ret; } char * -qemuGetDomainHugepagePath(const virDomainDef *def, +qemuGetDomainHugepagePath(virQEMUDriverPtr driver, + const virDomainDef *def, virHugeTLBFSPtr hugepage) { - g_autofree char *base = qemuGetBaseHugepagePath(hugepage); + g_autofree char *base = qemuGetBaseHugepagePath(driver, hugepage); g_autofree char *domPath = virDomainDefGetShortName(def); char *ret = NULL; @@ -1927,11 +1936,12 @@ qemuGetDomainHugepagePath(const virDomainDef *def, * -1 otherwise. */ int -qemuGetDomainHupageMemPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +qemuGetDomainHupageMemPath(virQEMUDriverPtr driver, + const virDomainDef *def, unsigned long long pagesize, char **memPath) { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); size_t i = 0; if (!cfg->nhugetlbfs) { @@ -1954,7 +1964,7 @@ qemuGetDomainHupageMemPath(const virDomainDef *def, return -1; } - if (!(*memPath = qemuGetDomainHugepagePath(def, &cfg->hugetlbfs[i]))) + if (!(*memPath = qemuGetDomainHugepagePath(driver, def, &cfg->hugetlbfs[i]))) return -1; return 0; diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 0f0eb60c69..9b282db372 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -388,12 +388,14 @@ virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver, int qemuTranslateSnapshotDiskSourcePool(virDomainSnapshotDiskDefPtr def); -char * qemuGetBaseHugepagePath(virHugeTLBFSPtr hugepage); -char * qemuGetDomainHugepagePath(const virDomainDef *def, +char * qemuGetBaseHugepagePath(virQEMUDriverPtr driver, + virHugeTLBFSPtr hugepage); +char * qemuGetDomainHugepagePath(virQEMUDriverPtr driver, + const virDomainDef *def, virHugeTLBFSPtr hugepage); -int qemuGetDomainHupageMemPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +int qemuGetDomainHupageMemPath(virQEMUDriverPtr driver, + const virDomainDef *def, unsigned long long pagesize, char **memPath); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 209f8279bd..ac866a923d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -918,7 +918,7 @@ qemuStateInitialize(bool privileged, for (i = 0; i < cfg->nhugetlbfs; i++) { g_autofree char *hugepagePath = NULL; - hugepagePath = qemuGetBaseHugepagePath(&cfg->hugetlbfs[i]); + hugepagePath = qemuGetBaseHugepagePath(qemu_driver, &cfg->hugetlbfs[i]); if (!hugepagePath) goto error; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fcb47e8596..7035c6d426 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3881,7 +3881,7 @@ qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, if (!build || shouldBuildHP) { for (i = 0; i < cfg->nhugetlbfs; i++) { g_autofree char *path = NULL; - path = qemuGetDomainHugepagePath(vm->def, &cfg->hugetlbfs[i]); + path = qemuGetDomainHugepagePath(driver, vm->def, &cfg->hugetlbfs[i]); if (!path) return -1; -- 2.24.1

So far, libvirt generates the following path for memory: $memoryBackingDir/libvirt/qemu/$id-$shortName/ram-nodeN where $memoryBackingDir is the path where QEMU mmaps() memory for the guest (e.g. /var/lib/libvirt/qemu/ram), $id is domain ID and $shortName is shortened version of domain name. So for instance, the generated path may look something like this: /var/lib/libvirt/qemu/ram/libvirt/qemu/1-QEMUGuest/ram-node0 While in case of embed driver the following path would be generated by default: $root/lib/qemu/ram/libvirt/qemu/1-QEMUGuest/ram-node0 which is not clashing with other embed drivers, we allow users to override the default and have all embed drivers use the same prefix. This can create clashing paths. Fortunately, we can reuse the approach for machined name generation (v6.1.0-178-gc9bd08ee35) and include part of hash of the root in the generated path. Note, the important change is in qemuGetMemoryBackingBasePath(). The rest is needed to pass driver around. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_command.c | 15 +++++++-------- src/qemu/qemu_conf.c | 26 +++++++++++++++++--------- src/qemu/qemu_conf.h | 10 +++++----- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 5 ++--- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6c21d28510..773b93740f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3472,7 +3472,7 @@ qemuBuildMemoryBackendProps(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(def, cfg, mem->info.alias, &memPath) < 0) + if (qemuGetMemoryBackingPath(priv->driver, def, mem->info.alias, &memPath) < 0) return -1; } @@ -7231,11 +7231,11 @@ qemuBuildSmpCommandLine(virCommandPtr cmd, static int -qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, - const virDomainDef *def, +qemuBuildMemPathStr(const virDomainDef *def, virCommandPtr cmd, qemuDomainObjPrivatePtr priv) { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); const long system_page_size = virGetSystemPageSizeKB(); g_autofree char *mem_path = NULL; @@ -7252,7 +7252,7 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, &mem_path) < 0) return -1; } else if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { - if (qemuGetMemoryBackingPath(def, cfg, "ram", &mem_path) < 0) + if (qemuGetMemoryBackingPath(priv->driver, def, "ram", &mem_path) < 0) return -1; } else { return 0; @@ -7271,7 +7271,6 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, static int qemuBuildMemCommandLine(virCommandPtr cmd, - virQEMUDriverConfigPtr cfg, const virDomainDef *def, virQEMUCapsPtr qemuCaps, qemuDomainObjPrivatePtr priv) @@ -7303,7 +7302,7 @@ qemuBuildMemCommandLine(virCommandPtr cmd, * the hugepages and no numa node is specified. */ if (!virDomainNumaGetNodeCount(def->numa) && - qemuBuildMemPathStr(cfg, def, cmd, priv) < 0) + qemuBuildMemPathStr(def, cmd, priv) < 0) return -1; if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OVERCOMMIT)) { @@ -7384,7 +7383,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, } if (!needBackend && - qemuBuildMemPathStr(cfg, def, cmd, priv) < 0) + qemuBuildMemPathStr(def, cmd, priv) < 0) goto cleanup; for (i = 0; i < ncells; i++) { @@ -9877,7 +9876,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (!migrateURI && !snapshot && qemuDomainAlignMemorySizes(def) < 0) return NULL; - if (qemuBuildMemCommandLine(cmd, cfg, def, qemuCaps, priv) < 0) + if (qemuBuildMemCommandLine(cmd, def, qemuCaps, priv) < 0) return NULL; if (qemuBuildSmpCommandLine(cmd, def, qemuCaps) < 0) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index f2e3111312..b48d5ab3fd 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1972,16 +1972,24 @@ qemuGetDomainHupageMemPath(virQEMUDriverPtr driver, void -qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg, +qemuGetMemoryBackingBasePath(virQEMUDriverPtr driver, char **path) { - *path = g_strdup_printf("%s/libvirt/qemu", cfg->memoryBackingDir); + const char *root = virQEMUDriverGetEmbedRoot(driver); + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + + if (root) { + g_autofree char * hash = virDomainDriverHashRoot(QEMU_DRIVER_NAME, root); + *path = g_strdup_printf("%s/libvirt/%s", cfg->memoryBackingDir, hash); + } else { + *path = g_strdup_printf("%s/libvirt/qemu", cfg->memoryBackingDir); + } } int -qemuGetMemoryBackingDomainPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +qemuGetMemoryBackingDomainPath(virQEMUDriverPtr driver, + const virDomainDef *def, char **path) { g_autofree char *shortName = NULL; @@ -1990,7 +1998,7 @@ qemuGetMemoryBackingDomainPath(const virDomainDef *def, if (!(shortName = virDomainDefGetShortName(def))) return -1; - qemuGetMemoryBackingBasePath(cfg, &base); + qemuGetMemoryBackingBasePath(driver, &base); *path = g_strdup_printf("%s/%s", base, shortName); return 0; @@ -1999,8 +2007,8 @@ qemuGetMemoryBackingDomainPath(const virDomainDef *def, /** * qemuGetMemoryBackingPath: + * @driver: the qemu driver * @def: domain definition - * @cfg: the driver config * @alias: memory object alias * @memPath: constructed path * @@ -2010,8 +2018,8 @@ qemuGetMemoryBackingDomainPath(const virDomainDef *def, * -1 otherwise (with error reported). */ int -qemuGetMemoryBackingPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +qemuGetMemoryBackingPath(virQEMUDriverPtr driver, + const virDomainDef *def, const char *alias, char **memPath) { @@ -2024,7 +2032,7 @@ qemuGetMemoryBackingPath(const virDomainDef *def, return -1; } - if (qemuGetMemoryBackingDomainPath(def, cfg, &domainPath) < 0) + if (qemuGetMemoryBackingDomainPath(driver, def, &domainPath) < 0) return -1; *memPath = g_strdup_printf("%s/%s", domainPath, alias); diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 9b282db372..3ac2b149fd 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -399,12 +399,12 @@ int qemuGetDomainHupageMemPath(virQEMUDriverPtr driver, unsigned long long pagesize, char **memPath); -void qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg, +void qemuGetMemoryBackingBasePath(virQEMUDriverPtr driver, char **path); -int qemuGetMemoryBackingDomainPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +int qemuGetMemoryBackingDomainPath(virQEMUDriverPtr driver, + const virDomainDef *def, char **path); -int qemuGetMemoryBackingPath(const virDomainDef *def, - virQEMUDriverConfigPtr cfg, +int qemuGetMemoryBackingPath(virQEMUDriverPtr driver, + const virDomainDef *def, const char *alias, char **memPath); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ac866a923d..2971d54772 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -935,7 +935,7 @@ qemuStateInitialize(bool privileged, goto error; } - qemuGetMemoryBackingBasePath(cfg, &memoryBackingPath); + qemuGetMemoryBackingBasePath(qemu_driver, &memoryBackingPath); if (virFileMakePath(memoryBackingPath) < 0) { virReportSystemError(errno, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7035c6d426..8384b4a136 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3894,7 +3894,7 @@ qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, if (!build || shouldBuildMB) { g_autofree char *path = NULL; - if (qemuGetMemoryBackingDomainPath(vm->def, cfg, &path) < 0) + if (qemuGetMemoryBackingDomainPath(driver, vm->def, &path) < 0) return -1; if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm, @@ -3911,10 +3911,9 @@ qemuProcessDestroyMemoryBackingPath(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainMemoryDefPtr mem) { - g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); g_autofree char *path = NULL; - if (qemuGetMemoryBackingPath(vm->def, cfg, mem->info.alias, &path) < 0) + if (qemuGetMemoryBackingPath(driver, vm->def, mem->info.alias, &path) < 0) return -1; if (unlink(path) < 0 && -- 2.24.1

On Wed, 2020-03-25 at 11:18 +0100, Michal Privoznik wrote: [...]
void -qemuGetMemoryBackingBasePath(virQEMUDriverConfigPtr cfg, +qemuGetMemoryBackingBasePath(virQEMUDriverPtr driver, char **path) { - *path = g_strdup_printf("%s/libvirt/qemu", cfg->memoryBackingDir); + const char *root = virQEMUDriverGetEmbedRoot(driver); + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + + if (root) { + g_autofree char * hash = virDomainDriverHashRoot(QEMU_DRIVER_NAME, root); + *path = g_strdup_printf("%s/libvirt/%s", cfg->memoryBackingDir, hash); + } else { + *path = g_strdup_printf("%s/libvirt/qemu", cfg->memoryBackingDir); + }
I'll reply here for convenience, but the same comments apply to the previous and following patches as well. As anticipated during our earlier discussion, this naive approach solves the issue but it's a bit crude. It work well enough when memoryBackingDir is configured to something like /dev/shm, but if you leave that setting alone and use the default instead, the generated path will go from $root/lib/qemu/ram/libvirt/qemu/$domid-$domname/ram-node0 to $root/lib/qemu/ram/libvirt/QEMU-embed-$roothash/$domid-$domname/ram-node0 which means that we're unnecessarily repeating the disambiguation information twice. I think we need to be smarter than that, and only use the hashed version when memoryBackingDir is outside of the embedded root. Two additional nits: * QEMU_DRIVER_NAME is defined as the uppercase string "QEMU", so the hash ends up not matching the one used elsewhere; * the default non-embedded path looks like /var/lib/libvirt/qemu/ram/libvirt/qemu/$domid-$domname/ram-node0 where both "libvirt" and "qemu" are repeated twice... While not a functional issue per se, that looks like it should also be addressed, don't you think? -- Andrea Bolognani / Red Hat / Virtualization

So far, libvirt generates the following path for automatic dumps: $autoDumpPath/$id-$shortName-$timestamp where $autoDumpPath is where libvirt stores dumps of guests (e.g. /var/lib/libvirt/qemu/dump), $id is domain ID and $shortName is shortened version of domain name. So for instance, the generated path may look something like this: /var/lib/libvirt/qemu/dump/1-QEMUGuest-2020-03-25-10:40:50 While in case of embed driver the following path would be generated by default: $root/lib/libvirt/qemu/dump/1-QEMUGuest-2020-03-25-10:40:50 which is not clashing with other embed drivers, we allow users to override the default and have all embed drivers use the same prefix. This can create clashing paths. Fortunately, we can reuse the approach for machined name generation (v6.1.0-178-gc9bd08ee35) and include part of hash of the root in the generated path. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2971d54772..def2732189 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4114,6 +4114,7 @@ static char * getAutoDumpPath(virQEMUDriverPtr driver, virDomainObjPtr vm) { + const char *root = virQEMUDriverGetEmbedRoot(driver); g_autofree char *domname = virDomainDefGetShortName(vm->def); g_autoptr(GDateTime) now = g_date_time_new_now_local(); g_autofree char *nowstr = NULL; @@ -4126,6 +4127,11 @@ getAutoDumpPath(virQEMUDriverPtr driver, nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S"); + if (root) { + g_autofree char * hash = virDomainDriverHashRoot(QEMU_DRIVER_NAME, root); + return g_strdup_printf("%s/%s-%s-%s", cfg->autoDumpPath, hash, domname, nowstr); + } + return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, nowstr); } -- 2.24.1

On 3/25/20 7:18 AM, Michal Privoznik wrote:
After my first round of patches got merged [1], some new problems arose. They are not as serious (except maybe for 7/9) but they are still problematic for sure. Mostly in scenarios where a mgmt application uses the embedded driver and has multiple forks/instances sharing essentially the same config (e.g. it writes the same qemu.conf into different roots). Thing is, we may generate conflicting paths across these instances.
What I've done here is, I looked at what paths can be set from qemu.conf and on their usage. Then I've grepped for virDomainDefGetShortName() and looked at its usages, because that has proven to be common denominator in patches 7-9.
Some usages of the function are safe though. When the usage involves a path that is derived from the root and can't be overridden in qemu.conf it is safe. For instance, qemuDBusGetAddress() calls virDomainDefGetShortName() to construct a path to a UNIX socket. But the path has cfg->dbusStateDir prefix which is derived from cfg->stateDir which in turn is derived from the root. At the same time, neither of these paths can be overridden in qemu.conf. Therefore, no conflicts can occur.
Michal Prívozník (9): tests: Fix virQEMUDriverConfigNew() calling with respect to @root conf: Move virDomainGenerateMachineName to hypervisor/ virDomainDriverGenerateMachineName: Factor out embed path hashing qemu: Introduce virQEMUDriverGetEmbedRoot qemuDomainGetMachineName: Access embeddedRoot from driver rather than cfg Revert "qemu_conf: Track embed root dir" qemu: Make hugepages path generation embed driver aware qemu: Make memory path generation embed driver aware qemu: Make auto dump path generation embed driver aware
LGTM Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
participants (4)
-
Andrea Bolognani
-
Daniel Henrique Barboza
-
Michal Privoznik
-
Michal Prívozník