For both virtio input devices and USB input devices.

https://bugzilla.redhat.com/show_bug.cgi?id=1379603
---
 src/libvirt_private.syms |  2 ++
 src/qemu/qemu_driver.c   |  9 +++++-
 src/qemu/qemu_hotplug.c  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_hotplug.h  |  5 ++++
 4 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7713ecc01..f5cdbeb66 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -157,6 +157,7 @@ virDomainAuditDisk;
 virDomainAuditFS;
 virDomainAuditHostdev;
 virDomainAuditInit;
+virDomainAuditInput;
 virDomainAuditIOThread;
 virDomainAuditMemory;
 virDomainAuditNet;
@@ -385,6 +386,7 @@ virDomainHubTypeFromString;
 virDomainHubTypeToString;
 virDomainHypervTypeFromString;
 virDomainHypervTypeToString;
+virDomainInputBusTypeToString;
 virDomainInputDefFind;
 virDomainInputDefFree;
 virDomainIOMMUModelTypeFromString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 092df673c..75a0e42aa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -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:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index c65e7e500..b32acb71e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -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,
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 3455832d6..985b7495b 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -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);
-- 
2.13.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to