]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: implement input device hotplug
authorJán Tomko <jtomko@redhat.com>
Wed, 4 Oct 2017 09:09:27 +0000 (11:09 +0200)
committerJán Tomko <jtomko@redhat.com>
Thu, 19 Oct 2017 12:43:22 +0000 (14:43 +0200)
For both virtio input devices and USB input devices.

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

src/libvirt_private.syms
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_hotplug.h

index 3246cfbba1462222dcda1ee4372aa39952138803..345643915916e3d0893d6f62ad2baec1091c8b19 100644 (file)
@@ -157,6 +157,7 @@ virDomainAuditDisk;
 virDomainAuditFS;
 virDomainAuditHostdev;
 virDomainAuditInit;
+virDomainAuditInput;
 virDomainAuditIOThread;
 virDomainAuditMemory;
 virDomainAuditNet;
@@ -386,6 +387,7 @@ virDomainHubTypeFromString;
 virDomainHubTypeToString;
 virDomainHypervTypeFromString;
 virDomainHypervTypeToString;
+virDomainInputBusTypeToString;
 virDomainInputDefFind;
 virDomainInputDefFree;
 virDomainIOMMUModelTypeFromString;
index a9724f009835b6a273bc350ae108f9f7e18e9aa5..51880fc12acbbc0319202c5306a71ef79b7fcae6 100644 (file)
@@ -7664,9 +7664,16 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
         }
         break;
 
+    case VIR_DOMAIN_DEVICE_INPUT:
+        ret = qemuDomainAttachInputDevice(driver, vm, dev->data.input);
+        if (ret == 0) {
+            alias = dev->data.input->info.alias;
+            dev->data.input = NULL;
+        }
+        break;
+
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_FS:
-    case VIR_DOMAIN_DEVICE_INPUT:
     case VIR_DOMAIN_DEVICE_SOUND:
     case VIR_DOMAIN_DEVICE_VIDEO:
     case VIR_DOMAIN_DEVICE_GRAPHICS:
index c65e7e50017aedbcb056d17a18a28226e64390fb..b32acb71e16be416678079fa3b2d692c0472fc84 100644 (file)
@@ -2905,6 +2905,79 @@ qemuDomainAttachWatchdog(virQEMUDriverPtr driver,
 }
 
 
+int
+qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            virDomainInputDefPtr input)
+{
+    int ret = -1;
+    char *devstr = NULL;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_INPUT,
+                               { .input = input } };
+    bool releaseaddr = false;
+
+    if (input->bus != VIR_DOMAIN_INPUT_BUS_USB &&
+        input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("input device on bus '%s' cannot be hot plugged."),
+                       virDomainInputBusTypeToString(input->bus));
+        return -1;
+    }
+
+    if (input->bus == VIR_DOMAIN_INPUT_BUS_VIRTIO) {
+        if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev, "input") < 0)
+            return -1;
+    } else if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+        if (priv->usbaddrs) {
+            if (virDomainUSBAddressEnsure(priv->usbaddrs, &input->info) < 0)
+                goto cleanup;
+            releaseaddr = true;
+        }
+    }
+
+    if (qemuAssignDeviceInputAlias(vm->def, input, -1) < 0)
+        goto cleanup;
+
+    if (qemuBuildInputDevStr(&devstr, vm->def, input, priv->qemuCaps) < 0)
+        goto cleanup;
+
+    if (VIR_REALLOC_N(vm->def->inputs, vm->def->ninputs + 1) < 0)
+        goto cleanup;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
+        goto exit_monitor;
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        releaseaddr = false;
+        goto cleanup;
+    }
+
+    VIR_APPEND_ELEMENT_COPY_INPLACE(vm->def->inputs, vm->def->ninputs, input);
+
+    ret = 0;
+    releaseaddr = false;
+
+ audit:
+    virDomainAuditInput(vm, input, "attach", ret == 0);
+
+ cleanup:
+    if (releaseaddr)
+        qemuDomainReleaseDeviceAddress(vm, &input->info, NULL);
+
+    VIR_FREE(devstr);
+    return ret;
+
+ exit_monitor:
+    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        releaseaddr = false;
+        goto cleanup;
+    }
+    goto audit;
+}
+
+
 static int
 qemuDomainChangeNetBridge(virDomainObjPtr vm,
                           virDomainNetDefPtr olddev,
index 3455832d69b8c9e8abf557591ef5261efc2b2690..985b7495ba381c86f3ffc3f724680cdeb16e0363 100644 (file)
@@ -125,6 +125,11 @@ int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
 int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
                              virDomainObjPtr vm,
                              virDomainWatchdogDefPtr watchdog);
+
+int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
+                                virDomainObjPtr vm,
+                                virDomainInputDefPtr input);
+
 int qemuDomainAttachLease(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           virDomainLeaseDefPtr lease);