From 3ac97c2dedd2a4715d06cf506be3727df32e79eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 27 Jan 2017 14:06:29 +0100 Subject: [PATCH] qemu: Add enough USB hubs to accomodate all devices Commit 815d98a started auto-adding one hub if there are more USB devices than available USB ports. This was a strange choice, since there might be even more devices. Before USB address allocation was implemented in libvirt, QEMU automatically added a new USB hub if the old one was full. Adjust the logic to try adding as many hubs as will be needed to plug in all the specified devices. https://bugzilla.redhat.com/show_bug.cgi?id=1410188 --- src/qemu/qemu_domain_address.c | 15 ++++--- .../qemuxml2argv-usb-hub-autoadd-deluxe.args | 42 +++++++++++++++++++ .../qemuxml2argv-usb-hub-autoadd-deluxe.xml | 35 ++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.xml diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9cd1e9e0f4..70482f2240 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2300,19 +2300,24 @@ qemuDomainUSBAddressAddHubs(virDomainDefPtr def) struct qemuAssignUSBIteratorInfo data = { .count = 0 }; virDomainHubDefPtr hub = NULL; size_t available_ports; + size_t hubs_needed = 0; int ret = -1; + size_t i; available_ports = virDomainUSBAddressCountAllPorts(def); ignore_value(virDomainUSBDeviceDefForeach(def, qemuDomainAssignUSBPortsCounter, &data, false)); - VIR_DEBUG("Found %zu USB devices and %zu provided USB ports", - data.count, available_ports); - /* Add one hub if there are more devices than ports - * otherwise it's up to the user to specify more hubs/controllers */ - if (data.count > available_ports) { + if (data.count > available_ports) + hubs_needed = VIR_DIV_UP(data.count - available_ports + 1, + VIR_DOMAIN_USB_HUB_PORTS - 1); + + VIR_DEBUG("Found %zu USB devices and %zu provided USB ports; adding %zu hubs", + data.count, available_ports, hubs_needed); + + for (i = 0; i < hubs_needed; i++) { if (VIR_ALLOC(hub) < 0) return -1; hub->type = VIR_DOMAIN_HUB_TYPE_USB; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.args new file mode 100644 index 0000000000..552e1352e6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.args @@ -0,0 +1,42 @@ +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,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefconfig \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-usb \ +-device usb-hub,id=hub0,bus=usb.0,port=1 \ +-device usb-hub,id=hub1,bus=usb.0,port=2 \ +-device usb-hub,id=hub2,bus=usb.0,port=1.1 \ +-device usb-mouse,id=input0,bus=usb.0,port=1.2 \ +-device usb-mouse,id=input1,bus=usb.0,port=1.3 \ +-device usb-mouse,id=input2,bus=usb.0,port=1.4 \ +-device usb-tablet,id=input3,bus=usb.0,port=1.5 \ +-device usb-tablet,id=input4,bus=usb.0,port=1.6 \ +-device usb-tablet,id=input5,bus=usb.0,port=1.7 \ +-device usb-tablet,id=input6,bus=usb.0,port=1.8 \ +-device usb-tablet,id=input7,bus=usb.0,port=1.1.1 \ +-device usb-tablet,id=input8,bus=usb.0,port=1.1.2 \ +-device usb-tablet,id=input9,bus=usb.0,port=1.1.3 \ +-device usb-tablet,id=input10,bus=usb.0,port=1.1.4 \ +-device usb-tablet,id=input11,bus=usb.0,port=1.1.5 \ +-device usb-tablet,id=input12,bus=usb.0,port=1.1.6 \ +-device usb-tablet,id=input13,bus=usb.0,port=1.1.7 \ +-device usb-tablet,id=input14,bus=usb.0,port=1.1.8 \ +-device usb-tablet,id=input15,bus=usb.0,port=2.1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.xml new file mode 100644 index 0000000000..5787f1a8fc --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd-deluxe.xml @@ -0,0 +1,35 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + /usr/bin/qemu + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d0b0cec7e3..3532cb5ee7 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1332,6 +1332,9 @@ mymain(void) DO_TEST("usb-hub-autoadd", QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB, QEMU_CAPS_NODEFCONFIG); + DO_TEST("usb-hub-autoadd-deluxe", + QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB, + QEMU_CAPS_NODEFCONFIG); DO_TEST_PARSE_ERROR("usb-hub-conflict", QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB, QEMU_CAPS_NODEFCONFIG);