diff --git a/libvirt.spec.in b/libvirt.spec.in
index 3b179d1fd9..7157cfe3b4 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 532fe36be3..3f811d064f 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -143,6 +143,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);
@@ -151,7 +152,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) {
@@ -163,8 +163,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);
@@ -173,7 +173,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",
@@ -190,8 +189,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();
@@ -201,8 +200,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 224350dabc..d46516856e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5401,6 +5401,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:
*
@@ -5421,6 +5443,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,
@@ -5439,14 +5464,31 @@ qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr,
cfg = virQEMUDriverGetConfig(driver);
- virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir);
- virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)");
- virBufferEscapeRegex(&buf, "%s$", chr->target.name);
-
- regexp = virBufferContentAndReset(&buf);
-
- if (virStringMatch(chr->source->data.nix.path, regexp))
+ if (qemuDomainChrMatchDefaultPath(cfg->channelTargetDir,
+ NULL,
+ chr->target.name,
+ chr->source->data.nix.path)) {
VIR_FREE(chr->source->data.nix.path);
+ return;
+ }
+
+ /* 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 (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/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
index 7871de59c4..dd4feae855 100644
--- a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
+++ b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
@@ -1,5 +1,5 @@