[libvirt] [PATCH 3/8] qemu: build command line for virtio input devices

Ján Tomko jtomko at redhat.com
Fri Nov 20 08:59:38 UTC 2015


Add support for these qemu devices:
virtio-mouse-{pci,device}
virtio-keyboard-{pci,device}
virtio-tablet-{pci,device}

https://bugzilla.redhat.com/show_bug.cgi?id=1231114
---
 src/qemu/qemu_command.c                            | 83 +++++++++++++++++++++-
 .../qemuxml2argv-virtio-input.args                 | 23 ++++++
 tests/qemuxml2argvtest.c                           |  3 +
 3 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-input.args

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 91c55cb..570904a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1284,6 +1284,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
         }
     }
 
+    for (i = 0; i < def->ninputs; i++) {
+        if (def->inputs[i]->bus == VIR_DOMAIN_DISK_BUS_VIRTIO &&
+            def->inputs[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            def->inputs[i]->info.type = type;
+    }
+
     for (i = 0; i < def->ncontrollers; i++) {
         if ((def->controllers[i]->type ==
              VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL ||
@@ -2681,7 +2687,14 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
             goto error;
     }
     for (i = 0; i < def->ninputs; i++) {
-        /* Nada - none are PCI based (yet) */
+        if (def->inputs[i]->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO)
+            continue;
+        if (def->inputs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+
+        if (virDomainPCIAddressReserveNextSlot(addrs,
+                                               &def->inputs[i]->info, flags) < 0)
+            goto error;
     }
     for (i = 0; i < def->nparallels; i++) {
         /* Nada - none are PCI based (yet) */
@@ -5716,6 +5729,67 @@ qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev)
     return NULL;
 }
 
+static char *
+qemuBuildVirtioInputDevStr(virDomainDefPtr def,
+                           virDomainInputDefPtr dev,
+                           virQEMUCapsPtr qemuCaps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    const char *suffix;
+
+    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+        suffix = "-pci";
+    } else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
+        suffix = "-device";
+    } else {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unsupported address type %s for virtio input device"),
+                       virDomainDeviceAddressTypeToString(dev->info.type));
+        goto error;
+    }
+
+    switch ((virDomainInputType) dev->type) {
+    case VIR_DOMAIN_INPUT_TYPE_MOUSE:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_MOUSE)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("virtio-mouse is not supported by this QEMU binary"));
+            goto error;
+        }
+        virBufferAsprintf(&buf, "virtio-mouse%s,id=%s", suffix, dev->info.alias);
+        break;
+    case VIR_DOMAIN_INPUT_TYPE_TABLET:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TABLET)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("virtio-tablet is not supported by this QEMU binary"));
+            goto error;
+        }
+        virBufferAsprintf(&buf, "virtio-tablet%s,id=%s", suffix, dev->info.alias);
+        break;
+    case VIR_DOMAIN_INPUT_TYPE_KBD:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_KEYBOARD)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("virtio-keyboard is not supported by this QEMU binary"));
+            goto error;
+        }
+        virBufferAsprintf(&buf, "virtio-keyboard%s,id=%s", suffix, dev->info.alias);
+        break;
+    case VIR_DOMAIN_INPUT_TYPE_LAST:
+        break;
+    }
+
+    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
+        goto error;
+
+    if (virBufferCheckError(&buf) < 0)
+        goto error;
+
+    return virBufferContentAndReset(&buf);
+
+ error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
 char *
 qemuBuildUSBInputDevStr(virDomainDefPtr def,
                         virDomainInputDefPtr dev,
@@ -10472,6 +10546,13 @@ qemuBuildCommandLine(virConnectPtr conn,
                         break;
                 }
             }
+        } else if (input->bus == VIR_DOMAIN_INPUT_BUS_VIRTIO) {
+            char *optstr;
+            virCommandAddArg(cmd, "-device");
+            if (!(optstr = qemuBuildVirtioInputDevStr(def, input, qemuCaps)))
+                goto error;
+            virCommandAddArg(cmd, optstr);
+            VIR_FREE(optstr);
         }
     }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-input.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-input.args
new file mode 100644
index 0000000..12dfdeb
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-input.args
@@ -0,0 +1,23 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi \
+-boot c \
+-usb \
+-device virtio-mouse-pci,id=input0,bus=pci.0,addr=0x4 \
+-device virtio-keyboard-pci,id=input1,bus=pci.0,addr=0xa \
+-device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x5 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index dc8654e..bad65a6 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1748,6 +1748,9 @@ mymain(void)
     DO_TEST("qemu-ns-commandline-ns0", NONE);
     DO_TEST("qemu-ns-commandline-ns1", NONE);
 
+    DO_TEST("virtio-input", QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_KEYBOARD,
+            QEMU_CAPS_VIRTIO_MOUSE, QEMU_CAPS_VIRTIO_TABLET);
+
     qemuTestDriverFree(&driver);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
-- 
2.4.6




More information about the libvir-list mailing list