[libvirt PATCHv2 0/5] qemu: implement virtiofs hot(un)plug (virtiofs epopee)

diff to v1 * do not store logCtxt in private data * qemuDomainGetVHostUserChrSourceDef inlined in the only function that uses it * a new connection to the logManager is opened when virtiofsd is started * use VIR_APPEND_ELEMENT_COPY to reuse 'fs' on the successful audit * qemuDomainRemoveFSDevice only processes virtiofs devices now Ján Tomko (5): logging: define cleanup func for virLogManager qemu: virtiofs: open a separate connection to virtlogd qemu: Revert "qemuExtDevicesStart: pass logManager" qemu: implement virtiofs hotplug qemu: implement virtiofs hotunplug src/conf/domain_conf.c | 24 +++++ src/conf/domain_conf.h | 2 + src/libvirt_private.syms | 1 + src/logging/log_manager.h | 2 + src/qemu/qemu_driver.c | 9 +- src/qemu/qemu_extdevice.c | 3 +- src/qemu/qemu_extdevice.h | 1 - src/qemu/qemu_hotplug.c | 186 +++++++++++++++++++++++++++++++++++++- src/qemu/qemu_process.c | 4 +- src/qemu/qemu_virtiofs.c | 8 +- src/qemu/qemu_virtiofs.h | 3 +- 11 files changed, 230 insertions(+), 13 deletions(-) -- 2.31.1

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/logging/log_manager.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/logging/log_manager.h b/src/logging/log_manager.h index 9a8f9b6af8..80f14934d7 100644 --- a/src/logging/log_manager.h +++ b/src/logging/log_manager.h @@ -27,6 +27,8 @@ typedef struct _virLogManager virLogManager; virLogManager *virLogManagerNew(bool privileged); void virLogManagerFree(virLogManager *mgr); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virLogManager, virLogManagerFree); + int virLogManagerDomainOpenLogFile(virLogManager *mgr, const char *driver, -- 2.31.1

On Wed, Oct 06, 2021 at 12:20:19 +0200, Ján Tomko wrote:
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/logging/log_manager.h | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

Do not depend on passing a logManager. Create a new connection. Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_extdevice.c | 4 ++-- src/qemu/qemu_virtiofs.c | 8 ++++++-- src/qemu/qemu_virtiofs.h | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index ef0b3f1981..3c34bb8321 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -166,7 +166,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver, int qemuExtDevicesStart(virQEMUDriver *driver, virDomainObj *vm, - virLogManager *logManager, + virLogManager *logManager G_GNUC_UNUSED, bool incomingMigration) { virDomainDef *def = vm->def; @@ -197,7 +197,7 @@ qemuExtDevicesStart(virQEMUDriver *driver, virDomainFSDef *fs = def->fss[i]; if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS && !fs->sock) { - if (qemuVirtioFSStart(logManager, driver, vm, fs) < 0) + if (qemuVirtioFSStart(driver, vm, fs) < 0) return -1; } } diff --git a/src/qemu/qemu_virtiofs.c b/src/qemu/qemu_virtiofs.c index 08a8b4ed42..3ca45457c1 100644 --- a/src/qemu/qemu_virtiofs.c +++ b/src/qemu/qemu_virtiofs.c @@ -157,8 +157,7 @@ qemuVirtioFSBuildCommandLine(virQEMUDriverConfig *cfg, } int -qemuVirtioFSStart(virLogManager *logManager, - virQEMUDriver *driver, +qemuVirtioFSStart(virQEMUDriver *driver, virDomainObj *vm, virDomainFSDef *fs) { @@ -191,6 +190,11 @@ qemuVirtioFSStart(virLogManager *logManager, logpath = qemuVirtioFSCreateLogFilename(cfg, vm->def, fs->info.alias); if (cfg->stdioLogD) { + g_autoptr(virLogManager) logManager = virLogManagerNew(driver->privileged); + + if (!logManager) + goto cleanup; + if ((logfd = virLogManagerDomainOpenLogFile(logManager, "qemu", vm->def->uuid, diff --git a/src/qemu/qemu_virtiofs.h b/src/qemu/qemu_virtiofs.h index 1886339394..5463acef98 100644 --- a/src/qemu/qemu_virtiofs.h +++ b/src/qemu/qemu_virtiofs.h @@ -27,8 +27,7 @@ qemuVirtioFSCreateSocketFilename(virDomainObj *vm, const char *alias); int -qemuVirtioFSStart(virLogManager *logManager, - virQEMUDriver *driver, +qemuVirtioFSStart(virQEMUDriver *driver, virDomainObj *vm, virDomainFSDef *fs); void -- 2.31.1

On Wed, Oct 06, 2021 at 12:20:20 +0200, Ján Tomko wrote:
Do not depend on passing a logManager. Create a new connection.
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_extdevice.c | 4 ++-- src/qemu/qemu_virtiofs.c | 8 ++++++-- src/qemu/qemu_virtiofs.h | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-)
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

This reverts commit b164eac5e1d4ebe17e673f0427b70f862a670f94 Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_extdevice.c | 1 - src/qemu/qemu_extdevice.h | 1 - src/qemu/qemu_process.c | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c index 3c34bb8321..537b130394 100644 --- a/src/qemu/qemu_extdevice.c +++ b/src/qemu/qemu_extdevice.c @@ -166,7 +166,6 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver, int qemuExtDevicesStart(virQEMUDriver *driver, virDomainObj *vm, - virLogManager *logManager G_GNUC_UNUSED, bool incomingMigration) { virDomainDef *def = vm->def; diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h index 5f638438a8..43d2a4dfff 100644 --- a/src/qemu/qemu_extdevice.h +++ b/src/qemu/qemu_extdevice.h @@ -46,7 +46,6 @@ void qemuExtDevicesCleanupHost(virQEMUDriver *driver, int qemuExtDevicesStart(virQEMUDriver *driver, virDomainObj *vm, - virLogManager *logManager, bool incomingMigration) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1d0165af6d..96b7d1edc7 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7238,9 +7238,7 @@ qemuProcessLaunch(virConnectPtr conn, if (qemuProcessGenID(vm, flags) < 0) goto cleanup; - if (qemuExtDevicesStart(driver, vm, - qemuDomainLogContextGetManager(logCtxt), - incoming != NULL) < 0) + if (qemuExtDevicesStart(driver, vm, incoming != NULL) < 0) goto cleanup; VIR_DEBUG("Building emulator command line"); -- 2.31.1

On Wed, Oct 06, 2021 at 12:20:21 +0200, Ján Tomko wrote:
This reverts commit b164eac5e1d4ebe17e673f0427b70f862a670f94
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_extdevice.c | 1 - src/qemu/qemu_extdevice.h | 1 - src/qemu/qemu_process.c | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-)
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

https://bugzilla.redhat.com/show_bug.cgi?id=1897708 Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_driver.c | 9 +++- src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 760d30a867..65b2ef8e86 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6945,8 +6945,15 @@ qemuDomainAttachDeviceLive(virDomainObj *vm, } break; - case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_FS: + ret = qemuDomainAttachFSDevice(driver, vm, dev->data.fs); + if (ret == 0) { + alias = dev->data.fs->info.alias; + dev->data.fs = NULL; + } + break; + + case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_GRAPHICS: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 22239b2689..73e5a39852 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -35,6 +35,7 @@ #include "qemu_security.h" #include "qemu_block.h" #include "qemu_snapshot.h" +#include "qemu_virtiofs.h" #include "domain_audit.h" #include "netdev_bandwidth_conf.h" #include "domain_nwfilter.h" @@ -3396,6 +3397,104 @@ qemuDomainAttachVsockDevice(virQEMUDriver *driver, } +int +qemuDomainAttachFSDevice(virQEMUDriver *driver, + virDomainObj *vm, + virDomainFSDef *fs) +{ + qemuDomainObjPrivate *priv = vm->privateData; + virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_FS, + { .fs = fs } }; + g_autoptr(virDomainChrSourceDef) chardev = NULL; + virErrorPtr origErr = NULL; + bool releaseaddr = false; + bool chardevAdded = false; + bool started = false; + g_autofree char *devstr = NULL; + g_autofree char *charAlias = NULL; + int ret = -1; + + if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("only virtiofs filesystems can be hotplugged")); + return -1; + } + + if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0) + return -1; + + if (qemuAssignDeviceFSAlias(vm->def, fs) < 0) + goto cleanup; + + chardev = virDomainChrSourceDefNew(priv->driver->xmlopt); + chardev->type = VIR_DOMAIN_CHR_TYPE_UNIX; + chardev->data.nix.path = qemuDomainGetVHostUserFSSocketPath(priv, fs); + + charAlias = qemuDomainGetVhostUserChrAlias(fs->info.alias); + + if (!(devstr = qemuBuildVHostUserFsDevStr(fs, vm->def, charAlias, priv))) + goto cleanup; + + if (!fs->sock) { + if (qemuVirtioFSPrepareDomain(driver, fs) < 0) + goto cleanup; + + if (qemuVirtioFSStart(driver, vm, fs) < 0) + goto cleanup; + started = true; + + if (qemuVirtioFSSetupCgroup(vm, fs, priv->cgroup) < 0) + goto cleanup; + } + + qemuDomainObjEnterMonitor(driver, vm); + + if (qemuMonitorAttachCharDev(priv->mon, charAlias, chardev) < 0) + goto exit_monitor; + chardevAdded = true; + + if (qemuDomainAttachExtensionDevice(priv->mon, &fs->info) < 0) + goto exit_monitor; + + if (qemuMonitorAddDevice(priv->mon, devstr) < 0) { + ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &fs->info)); + goto exit_monitor; + } + + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + releaseaddr = false; + goto cleanup; + } + + VIR_APPEND_ELEMENT_COPY(vm->def->fss, vm->def->nfss, fs); + + ret = 0; + + audit: + virDomainAuditFS(vm, NULL, fs, "attach", ret == 0); + cleanup: + if (ret < 0) { + virErrorPreserveLast(&origErr); + if (releaseaddr) + qemuDomainReleaseDeviceAddress(vm, &fs->info); + if (started) + qemuVirtioFSStop(driver, vm, fs); + virErrorRestore(&origErr); + } + + return ret; + + exit_monitor: + virErrorPreserveLast(&origErr); + if (chardevAdded) + ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); + if (qemuDomainObjExitMonitor(driver, vm) < 0) + releaseaddr = false; + virErrorRestore(&origErr); + goto audit; +} + + int qemuDomainAttachLease(virQEMUDriver *driver, virDomainObj *vm, -- 2.31.1

On Wed, Oct 06, 2021 at 12:20:22 +0200, Ján Tomko wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1897708
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_driver.c | 9 +++- src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-)
Reviewed-by: Peter Krempa <pkrempa@redhat.com>

Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 24 +++++++++++ src/conf/domain_conf.h | 2 + src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 87 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b8370f6950..057dbf91a5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -28829,6 +28829,30 @@ virDomainFSRemove(virDomainDef *def, size_t i) return fs; } +ssize_t +virDomainFSDefFind(virDomainDef *def, + virDomainFSDef *fs) +{ + size_t i = 0; + + for (i = 0; i < def->nfss; i++) { + virDomainFSDef *tmp = def->fss[i]; + + if (fs->dst && STRNEQ_NULLABLE(fs->dst, tmp->dst)) + continue; + + if (fs->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + !virDomainDeviceInfoAddressIsEqual(&fs->info, &tmp->info)) + continue; + + if (fs->info.alias && STRNEQ_NULLABLE(fs->info.alias, tmp->info.alias)) + continue; + + return i; + } + return -1; +} + virDomainFSDef * virDomainGetFilesystemForTarget(virDomainDef *def, const char *target) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c23c233184..1fcef7b0e1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3757,6 +3757,8 @@ virDomainFSDef *virDomainGetFilesystemForTarget(virDomainDef *def, int virDomainFSInsert(virDomainDef *def, virDomainFSDef *fs); int virDomainFSIndexByName(virDomainDef *def, const char *name); virDomainFSDef *virDomainFSRemove(virDomainDef *def, size_t i); +ssize_t virDomainFSDefFind(virDomainDef *def, + virDomainFSDef *fs); unsigned int virDomainVideoDefaultRAM(const virDomainDef *def, const virDomainVideoType type); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fd0eea0777..687a3bbc4c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -410,6 +410,7 @@ virDomainFeatureTypeFromString; virDomainFeatureTypeToString; virDomainFSAccessModeTypeToString; virDomainFSCacheModeTypeToString; +virDomainFSDefFind; virDomainFSDefFree; virDomainFSDefNew; virDomainFSDriverTypeToString; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 73e5a39852..0947243c16 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5183,6 +5183,51 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriver *driver, } +static int +qemuDomainRemoveFSDevice(virQEMUDriver *driver, + virDomainObj *vm, + virDomainFSDef *fs) +{ + g_autofree char *charAlias = NULL; + qemuDomainObjPrivate *priv = vm->privateData; + ssize_t idx; + int rc = 0; + + VIR_DEBUG("Removing FS device %s from domain %p %s", + fs->info.alias, vm, vm->def->name); + + if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("only virtiofs filesystems can be hotplugged")); + return -1; + } + + charAlias = qemuDomainGetVhostUserChrAlias(fs->info.alias); + + qemuDomainObjEnterMonitor(driver, vm); + + if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) + rc = -1; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + return -1; + + virDomainAuditFS(vm, fs, NULL, "detach", rc == 0); + + if (rc < 0) + return -1; + + if (!fs->sock) + qemuVirtioFSStop(driver, vm, fs); + + if ((idx = virDomainFSDefFind(vm->def, fs)) >= 0) + virDomainFSRemove(vm->def, idx); + qemuDomainReleaseDeviceAddress(vm, &fs->info); + virDomainFSDefFree(fs); + return 0; +} + + static void qemuDomainRemoveAuditDevice(virDomainObj *vm, virDomainDeviceDef *detach, @@ -5221,6 +5266,10 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm, virDomainAuditRedirdev(vm, detach->data.redirdev, "detach", success); break; + case VIR_DOMAIN_DEVICE_FS: + virDomainAuditFS(vm, detach->data.fs, NULL, "detach", success); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_CONTROLLER: case VIR_DOMAIN_DEVICE_WATCHDOG: @@ -5228,7 +5277,6 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm, /* These devices don't have associated audit logs */ break; - case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_GRAPHICS: @@ -5326,9 +5374,13 @@ qemuDomainRemoveDevice(virQEMUDriver *driver, return -1; break; + case VIR_DOMAIN_DEVICE_FS: + if (qemuDomainRemoveFSDevice(driver, vm, dev->data.fs) < 0) + return -1; + break; + case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LEASE: - case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_GRAPHICS: @@ -6023,6 +6075,31 @@ qemuDomainDetachPrepVsock(virDomainObj *vm, } +static int +qemuDomainDetachPrepFS(virDomainObj *vm, + virDomainFSDef *match, + virDomainFSDef **detach) +{ + ssize_t idx; + + if ((idx = virDomainFSDefFind(vm->def, match)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("matching filesystem not found")); + return -1; + } + + if (vm->def->fss[idx]->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("only virtiofs filesystems can be hotplugged")); + return -1; + } + + *detach = vm->def->fss[idx]; + + return 0; +} + + static int qemuDomainDetachDeviceLease(virQEMUDriver *driver, virDomainObj *vm, @@ -6144,6 +6221,12 @@ qemuDomainDetachDeviceLive(virDomainObj *vm, break; case VIR_DOMAIN_DEVICE_FS: + if (qemuDomainDetachPrepFS(vm, match->data.fs, + &detach.data.fs) < 0) { + return -1; + } + break; + case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_GRAPHICS: -- 2.31.1

On Wed, Oct 06, 2021 at 12:20:23 +0200, Ján Tomko wrote:
Signed-off-by: Ján Tomko <jtomko@redhat.com> --- src/conf/domain_conf.c | 24 +++++++++++ src/conf/domain_conf.h | 2 + src/libvirt_private.syms | 1 + src/qemu/qemu_hotplug.c | 87 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b8370f6950..057dbf91a5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -28829,6 +28829,30 @@ virDomainFSRemove(virDomainDef *def, size_t i) return fs; }
+ssize_t +virDomainFSDefFind(virDomainDef *def, + virDomainFSDef *fs) +{ + size_t i = 0; + + for (i = 0; i < def->nfss; i++) { + virDomainFSDef *tmp = def->fss[i]; + + if (fs->dst && STRNEQ_NULLABLE(fs->dst, tmp->dst)) + continue; + + if (fs->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + !virDomainDeviceInfoAddressIsEqual(&fs->info, &tmp->info)) + continue; + + if (fs->info.alias && STRNEQ_NULLABLE(fs->info.alias, tmp->info.alias)) + continue; + + return i; + } + return -1; +} + virDomainFSDef * virDomainGetFilesystemForTarget(virDomainDef *def, const char *target) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c23c233184..1fcef7b0e1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3757,6 +3757,8 @@ virDomainFSDef *virDomainGetFilesystemForTarget(virDomainDef *def, int virDomainFSInsert(virDomainDef *def, virDomainFSDef *fs); int virDomainFSIndexByName(virDomainDef *def, const char *name); virDomainFSDef *virDomainFSRemove(virDomainDef *def, size_t i); +ssize_t virDomainFSDefFind(virDomainDef *def, + virDomainFSDef *fs);
unsigned int virDomainVideoDefaultRAM(const virDomainDef *def, const virDomainVideoType type); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fd0eea0777..687a3bbc4c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -410,6 +410,7 @@ virDomainFeatureTypeFromString; virDomainFeatureTypeToString; virDomainFSAccessModeTypeToString; virDomainFSCacheModeTypeToString; +virDomainFSDefFind; virDomainFSDefFree; virDomainFSDefNew; virDomainFSDriverTypeToString; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 73e5a39852..0947243c16 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5183,6 +5183,51 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriver *driver, }
+static int +qemuDomainRemoveFSDevice(virQEMUDriver *driver, + virDomainObj *vm, + virDomainFSDef *fs) +{ + g_autofree char *charAlias = NULL; + qemuDomainObjPrivate *priv = vm->privateData; + ssize_t idx; + int rc = 0; + + VIR_DEBUG("Removing FS device %s from domain %p %s", + fs->info.alias, vm, vm->def->name); + + if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("only virtiofs filesystems can be hotplugged")); + return -1; + }
This is not really what I meant. This function is called after the device was already unplugged so this check here is nonsensical. If I start qemu with a p9fs <filesystem type="mount" accessmode="mapped"> <source dir="/tmp"/> <target dir="asdf"/> <alias name="fs0"/> <address type="pci" domain="0x0000" bus="0x00" slot="0x0d" function="0x0"/> </filesystem> which results into: -fsdev local,security_model=mapped,id=fsdev-fs0,path=/tmp \ -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=asdf,bus=pci.0,addr=0xd \ And I then unplug it, either from the guest or via 'virsh qemu-monitor-command' I then still get the 'DEVICE_DELETED' event: 2021-10-07 07:54:11.376+0000: 2851053: debug : qemuMonitorJSONIOProcessLine:222 : Line [{"timestamp": {"seconds": 1633593251, "microseconds": 376384}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/fs0/virtio-backend"}}] So the device clearly can be unplugged and the error message is simply a lie. While the 'fsdev' part probably can't be unplugged and thus we probably can't do anything about it, the device frontend was already deleted and thus we should remove it from the XML.
participants (2)
-
Ján Tomko
-
Peter Krempa