https://bugzilla.redhat.com/show_bug.cgi?id=1897708
Signed-off-by: Ján Tomko <jtomko(a)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 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