https://bugzilla.redhat.com/show_bug.cgi?id=1897708 Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx> --- 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 e0a3b4d978..2b759f5719 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 b9937220db..5289b57f04 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" @@ -3419,6 +3420,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; + g_autoptr(virJSONValue) devprops = NULL; + virErrorPtr origErr = NULL; + bool releaseaddr = false; + bool chardevAdded = false; + bool started = false; + 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 (qemuBuildVHostUserFsDevProps(fs, vm->def, charAlias, priv) < 0) + 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 (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 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