]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: implement vsock hotplug
authorJán Tomko <jtomko@redhat.com>
Wed, 30 May 2018 11:53:52 +0000 (13:53 +0200)
committerJán Tomko <jtomko@redhat.com>
Tue, 5 Jun 2018 05:51:13 +0000 (07:51 +0200)
Allow hotplugging the vsock device.

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

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/libvirt_private.syms
src/qemu/qemu_alias.c
src/qemu/qemu_alias.h
src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h
src/qemu/qemu_process.c
src/qemu/qemu_process.h

index 60016359165b1187cc022f81e7c18acd10cc5dd2..5405250ee9faeda1c71a3a68a8af13503400f527 100644 (file)
@@ -574,6 +574,7 @@ virDomainVideoVGAConfTypeFromString;
 virDomainVideoVGAConfTypeToString;
 virDomainVirtTypeFromString;
 virDomainVirtTypeToString;
+virDomainVsockDefFree;
 virDomainVsockDefNew;
 virDomainWatchdogActionTypeFromString;
 virDomainWatchdogActionTypeToString;
index 89dec91ed11d3f94e3c755cb1491b7dba48a5a2a..72cba7f365ead1a87d15fbc88f3ec59a49b3bd44 100644 (file)
@@ -533,7 +533,7 @@ qemuAssignDeviceInputAlias(virDomainDefPtr def,
 }
 
 
-static int
+int
 qemuAssignDeviceVsockAlias(virDomainVsockDefPtr vsock)
 {
     if (vsock->info.alias)
index 51f64624d7881820e961ed8970baf5f952a71ca8..4ca0aaf9a6bdc43256d659c968a0335007adfbec 100644 (file)
@@ -70,6 +70,8 @@ int qemuAssignDeviceInputAlias(virDomainDefPtr def,
                                virDomainInputDefPtr input,
                                int idx);
 
+int qemuAssignDeviceVsockAlias(virDomainVsockDefPtr vsock);
+
 int qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps);
 
 int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
index 89cd931de6dcedfb39ddfb8443030cbc49457503..26aeca05bff3eb883cc0200f3fb338a876b80630 100644 (file)
@@ -9912,7 +9912,7 @@ qemuBuildSeccompSandboxCommandLine(virCommandPtr cmd,
 }
 
 
-static char *
+char *
 qemuBuildVsockDevStr(virDomainDefPtr def,
                      virDomainVsockDefPtr vsock,
                      virQEMUCapsPtr qemuCaps,
index bbbf152660326b3875319e29aafdbad4e6518403..36bf82241424dbf219596707a11308b2c1f7b7a7 100644 (file)
@@ -206,4 +206,12 @@ int qemuBuildInputDevStr(char **devstr,
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
     ATTRIBUTE_NONNULL(4);
 
+char *
+qemuBuildVsockDevStr(virDomainDefPtr def,
+                     virDomainVsockDefPtr vsock,
+                     virQEMUCapsPtr qemuCaps,
+                     const char *fdprefix)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(4);
+
 #endif /* __QEMU_COMMAND_H__*/
index 3aa694de123ee4c1471ffe692bc7bdb223b80bdb..fa94ae9e3897ef8359610e9d8ef3d32d7d61f0ab 100644 (file)
@@ -7690,6 +7690,14 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
         }
         break;
 
+    case VIR_DOMAIN_DEVICE_VSOCK:
+        ret = qemuDomainAttachVsockDevice(driver, vm, dev->data.vsock);
+        if (ret == 0) {
+            alias = dev->data.vsock->info.alias;
+            dev->data.vsock = NULL;
+        }
+        break;
+
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_SOUND:
@@ -7702,7 +7710,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
-    case VIR_DOMAIN_DEVICE_VSOCK:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%s' is not supported"),
index a14281203ac230d0639ddb0061196f2005f57a91..7cfdc4207a1d998aa092d55ba29f9184b3505a60 100644 (file)
@@ -3015,6 +3015,75 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
 }
 
 
+int
+qemuDomainAttachVsockDevice(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            virDomainVsockDefPtr vsock)
+{
+    qemuDomainVsockPrivatePtr vsockPriv = (qemuDomainVsockPrivatePtr)vsock->privateData;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_VSOCK,
+                               { .vsock = vsock } };
+    virErrorPtr originalError = NULL;
+    const char *fdprefix = "vsockfd";
+    bool releaseaddr = false;
+    char *fdname = NULL;
+    char *devstr = NULL;
+    int ret = -1;
+
+    if (vm->def->vsock) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("the domain already has a vsock device"));
+        return -1;
+    }
+
+    if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev, "vsock") < 0)
+        return -1;
+
+    if (qemuAssignDeviceVsockAlias(vsock) < 0)
+        goto cleanup;
+
+    if (qemuProcessOpenVhostVsock(vsock) < 0)
+        goto cleanup;
+
+    if (virAsprintf(&fdname, "%s%u", fdprefix, vsockPriv->vhostfd) < 0)
+        goto cleanup;
+
+    if (!(devstr = qemuBuildVsockDevStr(vm->def, vsock, priv->qemuCaps, fdprefix)))
+        goto cleanup;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vsockPriv->vhostfd, fdname) < 0)
+        goto exit_monitor;
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        releaseaddr = false;
+        goto cleanup;
+    }
+
+    VIR_STEAL_PTR(vm->def->vsock, vsock);
+
+    ret = 0;
+
+ cleanup:
+    if (ret < 0) {
+        virErrorPreserveLast(&originalError);
+        if (releaseaddr)
+            qemuDomainReleaseDeviceAddress(vm, &vsock->info, NULL);
+        virErrorRestore(&originalError);
+    }
+
+    VIR_FREE(devstr);
+    VIR_FREE(fdname);
+    return ret;
+
+ exit_monitor:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        releaseaddr = false;
+    goto cleanup;
+}
+
+
 static int
 qemuDomainChangeNetBridge(virDomainObjPtr vm,
                           virDomainNetDefPtr olddev,
index 751cbf61d48864b17ed1e3d6c672c1fe318850fc..ab298382eb9dbe9047edc5ac3ec1dc834c71b20e 100644 (file)
@@ -139,6 +139,10 @@ int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 virDomainInputDefPtr input);
 
+int qemuDomainAttachVsockDevice(virQEMUDriverPtr driver,
+                                virDomainObjPtr vm,
+                                virDomainVsockDefPtr vsock);
+
 int qemuDomainAttachLease(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           virDomainLeaseDefPtr lease);
index 30cc5904e0a7442d75d2bacd1c467603adb51103..68960cc1befe33f2d0454ac0ed2feb147c2c2dc3 100644 (file)
@@ -5948,7 +5948,7 @@ qemuProcessPrepareHostStorage(virQEMUDriverPtr driver,
 }
 
 
-static int
+int
 qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock)
 {
     qemuDomainVsockPrivatePtr priv = (qemuDomainVsockPrivatePtr)vsock->privateData;
index 5098eacfe8079f01db28d5d58864ad66e1aa6812..531c2a0cc75b9a2accdd1d4916b7fea9b2b9b158 100644 (file)
@@ -113,6 +113,8 @@ int qemuProcessPrepareDomain(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              unsigned int flags);
 
+int qemuProcessOpenVhostVsock(virDomainVsockDefPtr vsock);
+
 int qemuProcessPrepareHost(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            unsigned int flags);