From 8abc979bb09ca4b93123e8f75f3d28cc421a0bb6 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 20 Apr 2023 10:16:43 +0200 Subject: [PATCH] qemu: Move channelTargetDir into stateDir For historical reasons (i.e. unknown reason) we put channel sockets into a path derived from cfg->libDir which is a path that survives host reboots (e.g. /var/lib/libvirt/...). This is not necessary and in fact for session daemon creates a longer prefix: XDG_CONFIG_HOME -> /home/user/.config XDG_RUNTIME_DIR -> /run/user/1000 Worse, if host is rebooted suddenly (e.g. due to power loss) then we leave files behind and nobody will ever remove them. Therefore, place the channel target dir into state dir. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2173980 Signed-off-by: Michal Privoznik Reviewed-by: Pavel Hrdina --- libvirt.spec.in | 1 - src/qemu/qemu_conf.c | 9 ++-- src/qemu/qemu_domain.c | 52 +++++++++++++++++-- .../qemuhotplug-qemu-agent-detach.xml | 2 +- ...emuhotplug-base-live+qemu-agent-detach.xml | 2 +- .../qemuhotplug-base-live+qemu-agent.xml | 2 +- .../channel-unix-source-path.xml | 4 ++ .../channel-unix-source-path-active.xml | 5 ++ .../channel-unix-source-path-inactive.xml | 4 ++ tests/testutilsqemu.c | 2 +- 10 files changed, 67 insertions(+), 16 deletions(-) diff --git a/libvirt.spec.in b/libvirt.spec.in index 3b179d1fd98..7157cfe3b4f 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -2135,7 +2135,6 @@ exit 0 %ghost %dir %{_rundir}/libvirt/qemu/slirp/ %ghost %dir %{_rundir}/libvirt/qemu/swtpm/ %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ -%dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/checkpoint/ %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/dump/ %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 532fe36be36..3f811d064fe 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -138,6 +138,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, cfg->configBaseDir = g_strdup_printf("%s/etc", root); cfg->stateDir = g_strdup_printf("%s/run/qemu", root); cfg->swtpmStateDir = g_strdup_printf("%s/run/swtpm", root); + cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->stateDir); cfg->cacheDir = g_strdup_printf("%s/cache/qemu", root); cfg->libDir = g_strdup_printf("%s/lib/qemu", root); cfg->swtpmStorageDir = g_strdup_printf("%s/lib/swtpm", root); @@ -146,7 +147,6 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, cfg->snapshotDir = g_strdup_printf("%s/snapshot", cfg->libDir); cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir); cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir); - cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->libDir); cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir); cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir); } else if (privileged) { @@ -158,8 +158,8 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, cfg->configBaseDir = g_strdup(SYSCONFDIR "/libvirt"); cfg->stateDir = g_strdup_printf("%s/libvirt/qemu", RUNSTATEDIR); - cfg->swtpmStateDir = g_strdup_printf("%s/libvirt/qemu/swtpm", RUNSTATEDIR); + cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->stateDir); cfg->cacheDir = g_strdup_printf("%s/cache/libvirt/qemu", LOCALSTATEDIR); @@ -168,7 +168,6 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, cfg->snapshotDir = g_strdup_printf("%s/snapshot", cfg->libDir); cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir); cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir); - cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->libDir); cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir); cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir); cfg->swtpmStorageDir = g_strdup_printf("%s/lib/libvirt/swtpm", @@ -191,8 +190,8 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, rundir = virGetUserRuntimeDirectory(); cfg->stateDir = g_strdup_printf("%s/qemu/run", rundir); - cfg->swtpmStateDir = g_strdup_printf("%s/swtpm", cfg->stateDir); + cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->stateDir); cfg->configBaseDir = virGetUserConfigDirectory(); @@ -202,8 +201,6 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged, cfg->checkpointDir = g_strdup_printf("%s/qemu/checkpoint", cfg->configBaseDir); cfg->autoDumpPath = g_strdup_printf("%s/qemu/dump", cfg->configBaseDir); - cfg->channelTargetDir = g_strdup_printf("%s/qemu/channel", - cfg->configBaseDir); cfg->nvramDir = g_strdup_printf("%s/qemu/nvram", cfg->configBaseDir); cfg->memoryBackingDir = g_strdup_printf("%s/qemu/ram", cfg->configBaseDir); cfg->swtpmStorageDir = g_strdup_printf("%s/qemu/swtpm", diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 224350dabc3..d46516856eb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5153,6 +5153,28 @@ qemuDomainDefaultNetModel(const virDomainDef *def, } + +static bool +qemuDomainChrMatchDefaultPath(const char *prefix, + const char *infix, + const char *target, + const char *path) +{ + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autofree char *regexp = NULL; + + virBufferEscapeRegex(&buf, "^%s", prefix); + if (infix) + virBufferEscapeRegex(&buf, "%s", infix); + virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)"); + virBufferEscapeRegex(&buf, "%s$", target); + + regexp = virBufferContentAndReset(&buf); + + return virStringMatch(path, regexp); +} + + /* * Clear auto generated unix socket paths: * @@ -5173,6 +5195,9 @@ qemuDomainDefaultNetModel(const virDomainDef *def, * * This function clears the path for migration as well, so we need to clear * the path even if we are not storing it in the XML. + * + * Please note, as of libvirt 9.7.0 the channelTargetDir is no longer derived + * from cfg->libDir but rather cfg->stateDir. */ static void qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr, @@ -5191,14 +5216,31 @@ qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr, cfg = virQEMUDriverGetConfig(driver); - virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir); - virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)"); - virBufferEscapeRegex(&buf, "%s$", chr->target.name); + if (qemuDomainChrMatchDefaultPath(cfg->channelTargetDir, + NULL, + chr->target.name, + chr->source->data.nix.path)) { + VIR_FREE(chr->source->data.nix.path); + return; + } - regexp = virBufferContentAndReset(&buf); + /* Previously, channelTargetDir was derived from cfg->libdir, or + * cfg->configBaseDir even. Try them too. */ + if (qemuDomainChrMatchDefaultPath(cfg->libDir, + "/channel", + chr->target.name, + chr->source->data.nix.path)) { + VIR_FREE(chr->source->data.nix.path); + return; + } - if (virStringMatch(chr->source->data.nix.path, regexp)) + if (qemuDomainChrMatchDefaultPath(cfg->configBaseDir, + "/qemu/channel", + chr->target.name, + chr->source->data.nix.path)) { VIR_FREE(chr->source->data.nix.path); + return; + } } diff --git a/tests/qemuxml2argvdata/channel-unix-source-path.xml b/tests/qemuxml2argvdata/channel-unix-source-path.xml index db0e99c3d12..df548d88e72 100644 --- a/tests/qemuxml2argvdata/channel-unix-source-path.xml +++ b/tests/qemuxml2argvdata/channel-unix-source-path.xml @@ -28,6 +28,10 @@ + + + + diff --git a/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml b/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml index 68835ceb151..ec927d37c68 100644 --- a/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml +++ b/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml @@ -46,6 +46,11 @@
+ + + +
+