|
|
6ae9ed |
From 6c058183513069522ab1b622f2e08eb1de440def Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <6c058183513069522ab1b622f2e08eb1de440def@dist-git>
|
|
|
6ae9ed |
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
|
6ae9ed |
Date: Thu, 21 Jul 2016 15:57:57 +0200
|
|
|
6ae9ed |
Subject: [PATCH] Auto-add one hub if there are too many USB devices
|
|
|
6ae9ed |
MIME-Version: 1.0
|
|
|
6ae9ed |
Content-Type: text/plain; charset=UTF-8
|
|
|
6ae9ed |
Content-Transfer-Encoding: 8bit
|
|
|
6ae9ed |
|
|
|
6ae9ed |
When parsing a command line with USB devices that have
|
|
|
6ae9ed |
no address specified, QEMU automatically adds a USB hub
|
|
|
6ae9ed |
if the device would fill up all the available USB ports.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
To help most of the users, add one hub if there are more
|
|
|
6ae9ed |
USB devices than available ports. For wilder configurations,
|
|
|
6ae9ed |
expect the user to provide us with more hubs and/or controllers.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit 815d98ac0bb8a4b48a412e026cb6465309e4043c)
|
|
|
6ae9ed |
Signed-off-by: Ján Tomko <jtomko@redhat.com>
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1215968
|
|
|
6ae9ed |
|
|
|
6ae9ed |
Conflicts:
|
|
|
6ae9ed |
downstream does not assume QEMU_CAPS_SMP_TOPOLOGY in tests
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
src/conf/domain_addr.c | 20 +++++++++
|
|
|
6ae9ed |
src/conf/domain_addr.h | 2 +
|
|
|
6ae9ed |
src/libvirt_private.syms | 1 +
|
|
|
6ae9ed |
src/qemu/qemu_domain_address.c | 48 ++++++++++++++++++++++
|
|
|
6ae9ed |
.../qemuxml2argv-usb-hub-autoadd.args | 28 +++++++++++++
|
|
|
6ae9ed |
.../qemuxml2argv-usb-hub-autoadd.xml | 23 +++++++++++
|
|
|
6ae9ed |
tests/qemuxml2argvtest.c | 3 ++
|
|
|
6ae9ed |
7 files changed, 125 insertions(+)
|
|
|
6ae9ed |
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args
|
|
|
6ae9ed |
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
|
|
|
6ae9ed |
index 365ee40..c3469ee 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_addr.c
|
|
|
6ae9ed |
+++ b/src/conf/domain_addr.c
|
|
|
6ae9ed |
@@ -1604,6 +1604,26 @@ virDomainUSBAddressFindFreePort(virDomainUSBAddressHubPtr hub,
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+size_t
|
|
|
6ae9ed |
+virDomainUSBAddressCountAllPorts(virDomainDefPtr def)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ size_t i, ret = 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < def->ncontrollers; i++) {
|
|
|
6ae9ed |
+ virDomainControllerDefPtr cont = def->controllers[i];
|
|
|
6ae9ed |
+ if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB)
|
|
|
6ae9ed |
+ ret += virDomainUSBAddressControllerModelToPorts(cont);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < def->nhubs; i++) {
|
|
|
6ae9ed |
+ virDomainHubDefPtr hub = def->hubs[i];
|
|
|
6ae9ed |
+ if (hub->type == VIR_DOMAIN_HUB_TYPE_USB)
|
|
|
6ae9ed |
+ ret += VIR_DOMAIN_USB_HUB_PORTS;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
/* Try to find a free port on bus @bus.
|
|
|
6ae9ed |
*
|
|
|
6ae9ed |
* Returns 0 on success
|
|
|
6ae9ed |
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
|
|
|
6ae9ed |
index cc36aed..ce94981 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_addr.h
|
|
|
6ae9ed |
+++ b/src/conf/domain_addr.h
|
|
|
6ae9ed |
@@ -277,6 +277,8 @@ int
|
|
|
6ae9ed |
virDomainUSBAddressSetAddHub(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
virDomainHubDefPtr hub)
|
|
|
6ae9ed |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
6ae9ed |
+size_t
|
|
|
6ae9ed |
+virDomainUSBAddressCountAllPorts(virDomainDefPtr def);
|
|
|
6ae9ed |
void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
int
|
|
|
6ae9ed |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
6ae9ed |
index e23bfe3..8cd1ba3 100644
|
|
|
6ae9ed |
--- a/src/libvirt_private.syms
|
|
|
6ae9ed |
+++ b/src/libvirt_private.syms
|
|
|
6ae9ed |
@@ -108,6 +108,7 @@ virDomainPCIAddressSlotInUse;
|
|
|
6ae9ed |
virDomainPCIAddressValidate;
|
|
|
6ae9ed |
virDomainPCIControllerModelToConnectType;
|
|
|
6ae9ed |
virDomainUSBAddressAssign;
|
|
|
6ae9ed |
+virDomainUSBAddressCountAllPorts;
|
|
|
6ae9ed |
virDomainUSBAddressEnsure;
|
|
|
6ae9ed |
virDomainUSBAddressPortFormat;
|
|
|
6ae9ed |
virDomainUSBAddressPortFormatBuf;
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
index 7499026..787b357 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
@@ -1680,6 +1680,51 @@ qemuDomainAssignUSBPorts(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
static int
|
|
|
6ae9ed |
+qemuDomainAssignUSBPortsCounter(virDomainDeviceInfoPtr info ATTRIBUTE_UNUSED,
|
|
|
6ae9ed |
+ void *opaque)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ struct qemuAssignUSBIteratorInfo *data = opaque;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ data->count++;
|
|
|
6ae9ed |
+ return 0;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
+qemuDomainUSBAddressAddHubs(virDomainDefPtr def)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ struct qemuAssignUSBIteratorInfo data = { .count = 0 };
|
|
|
6ae9ed |
+ virDomainHubDefPtr hub = NULL;
|
|
|
6ae9ed |
+ size_t available_ports;
|
|
|
6ae9ed |
+ int ret = -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ available_ports = virDomainUSBAddressCountAllPorts(def);
|
|
|
6ae9ed |
+ ignore_value(virDomainUSBDeviceDefForeach(def,
|
|
|
6ae9ed |
+ qemuDomainAssignUSBPortsCounter,
|
|
|
6ae9ed |
+ &data,
|
|
|
6ae9ed |
+ false));
|
|
|
6ae9ed |
+ VIR_DEBUG("Found %zu USB devices and %zu provided USB ports",
|
|
|
6ae9ed |
+ data.count, available_ports);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ /* Add one hub if there are more devices than ports
|
|
|
6ae9ed |
+ * otherwise it's up to the user to specify more hubs/controllers */
|
|
|
6ae9ed |
+ if (data.count > available_ports) {
|
|
|
6ae9ed |
+ if (VIR_ALLOC(hub) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ hub->type = VIR_DOMAIN_HUB_TYPE_USB;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (VIR_APPEND_ELEMENT(def->hubs, def->nhubs, hub) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ ret = 0;
|
|
|
6ae9ed |
+ cleanup:
|
|
|
6ae9ed |
+ VIR_FREE(hub);
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
qemuDomainAssignUSBAddresses(virDomainDefPtr def,
|
|
|
6ae9ed |
virDomainObjPtr obj)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
@@ -1690,6 +1735,9 @@ qemuDomainAssignUSBAddresses(virDomainDefPtr def,
|
|
|
6ae9ed |
if (!(addrs = virDomainUSBAddressSetCreate()))
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (qemuDomainUSBAddressAddHubs(def) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
if (virDomainUSBAddressSetAddControllers(addrs, def) < 0)
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args
|
|
|
6ae9ed |
new file mode 100644
|
|
|
6ae9ed |
index 0000000..12c9691
|
|
|
6ae9ed |
--- /dev/null
|
|
|
6ae9ed |
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args
|
|
|
6ae9ed |
@@ -0,0 +1,28 @@
|
|
|
6ae9ed |
+LC_ALL=C \
|
|
|
6ae9ed |
+PATH=/bin \
|
|
|
6ae9ed |
+HOME=/home/test \
|
|
|
6ae9ed |
+USER=test \
|
|
|
6ae9ed |
+LOGNAME=test \
|
|
|
6ae9ed |
+QEMU_AUDIO_DRV=none \
|
|
|
6ae9ed |
+/usr/bin/qemu \
|
|
|
6ae9ed |
+-name QEMUGuest1 \
|
|
|
6ae9ed |
+-S \
|
|
|
6ae9ed |
+-M pc \
|
|
|
6ae9ed |
+-m 214 \
|
|
|
6ae9ed |
+-smp 1 \
|
|
|
6ae9ed |
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
|
|
|
6ae9ed |
+-nographic \
|
|
|
6ae9ed |
+-nodefconfig \
|
|
|
6ae9ed |
+-nodefaults \
|
|
|
6ae9ed |
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
|
|
|
6ae9ed |
+server,nowait \
|
|
|
6ae9ed |
+-mon chardev=charmonitor,id=monitor,mode=readline \
|
|
|
6ae9ed |
+-no-acpi \
|
|
|
6ae9ed |
+-boot c \
|
|
|
6ae9ed |
+-usb \
|
|
|
6ae9ed |
+-device usb-hub,id=hub0,bus=usb.0,port=1 \
|
|
|
6ae9ed |
+-device usb-mouse,id=input0,bus=usb.0,port=2 \
|
|
|
6ae9ed |
+-device usb-mouse,id=input1,bus=usb.0,port=1.1 \
|
|
|
6ae9ed |
+-device usb-mouse,id=input2,bus=usb.0,port=1.2 \
|
|
|
6ae9ed |
+-device usb-tablet,id=input3,bus=usb.0,port=1.3 \
|
|
|
6ae9ed |
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
|
|
|
6ae9ed |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml
|
|
|
6ae9ed |
new file mode 100644
|
|
|
6ae9ed |
index 0000000..43e0f1f
|
|
|
6ae9ed |
--- /dev/null
|
|
|
6ae9ed |
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml
|
|
|
6ae9ed |
@@ -0,0 +1,23 @@
|
|
|
6ae9ed |
+<domain type='qemu'>
|
|
|
6ae9ed |
+ <name>QEMUGuest1</name>
|
|
|
6ae9ed |
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
|
6ae9ed |
+ <memory unit='KiB'>219136</memory>
|
|
|
6ae9ed |
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
|
6ae9ed |
+ <vcpu placement='static'>1</vcpu>
|
|
|
6ae9ed |
+ <os>
|
|
|
6ae9ed |
+ <type arch='i686' machine='pc'>hvm</type>
|
|
|
6ae9ed |
+ <boot dev='hd'/>
|
|
|
6ae9ed |
+ </os>
|
|
|
6ae9ed |
+ <devices>
|
|
|
6ae9ed |
+ <emulator>/usr/bin/qemu</emulator>
|
|
|
6ae9ed |
+ <controller type='usb' index='0'/>
|
|
|
6ae9ed |
+ <memballoon model='virtio'/>
|
|
|
6ae9ed |
+ <input type='mouse' bus='usb'>
|
|
|
6ae9ed |
+ </input>
|
|
|
6ae9ed |
+ <input type='mouse' bus='usb'>
|
|
|
6ae9ed |
+ </input>
|
|
|
6ae9ed |
+ <input type='mouse' bus='usb'>
|
|
|
6ae9ed |
+ </input>
|
|
|
6ae9ed |
+ <input type='tablet' bus='usb'/>
|
|
|
6ae9ed |
+ </devices>
|
|
|
6ae9ed |
+</domain>
|
|
|
6ae9ed |
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
|
|
|
6ae9ed |
index e434470..51bab61 100644
|
|
|
6ae9ed |
--- a/tests/qemuxml2argvtest.c
|
|
|
6ae9ed |
+++ b/tests/qemuxml2argvtest.c
|
|
|
6ae9ed |
@@ -1163,6 +1163,9 @@ mymain(void)
|
|
|
6ae9ed |
DO_TEST("usb-hub",
|
|
|
6ae9ed |
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
|
|
|
6ae9ed |
QEMU_CAPS_NODEFCONFIG);
|
|
|
6ae9ed |
+ DO_TEST("usb-hub-autoadd",
|
|
|
6ae9ed |
+ QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
|
|
|
6ae9ed |
+ QEMU_CAPS_NODEFCONFIG);
|
|
|
6ae9ed |
DO_TEST_PARSE_ERROR("usb-hub-conflict",
|
|
|
6ae9ed |
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
|
|
|
6ae9ed |
QEMU_CAPS_NODEFCONFIG);
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.9.2
|
|
|
6ae9ed |
|