[libvirt PATCH 15/16] qemu: implement virtiofs hotplug

Ján Tomko jtomko at redhat.com
Wed Oct 6 07:15:21 UTC 2021


https://bugzilla.redhat.com/show_bug.cgi?id=1897708

Signed-off-by: Ján Tomko <jtomko at redhat.com>
---
 src/qemu/qemu_driver.c  |  9 +++-
 src/qemu/qemu_hotplug.c | 96 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 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..f5dad0b829 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,101 @@ 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 = qemuDomainGetVHostUserChrSourceDef(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(qemuDomainLogContextGetManager(priv->logCtxt), 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(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




More information about the libvir-list mailing list