mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 19:11:16 +00:00
Auto-add one hub if there are too many USB devices
When parsing a command line with USB devices that have no address specified, QEMU automatically adds a USB hub if the device would fill up all the available USB ports. To help most of the users, add one hub if there are more USB devices than available ports. For wilder configurations, expect the user to provide us with more hubs and/or controllers.
This commit is contained in:
parent
f2a781ceb0
commit
815d98ac0b
@ -1604,6 +1604,26 @@ virDomainUSBAddressFindFreePort(virDomainUSBAddressHubPtr hub,
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
virDomainUSBAddressCountAllPorts(virDomainDefPtr def)
|
||||
{
|
||||
size_t i, ret = 0;
|
||||
|
||||
for (i = 0; i < def->ncontrollers; i++) {
|
||||
virDomainControllerDefPtr cont = def->controllers[i];
|
||||
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB)
|
||||
ret += virDomainUSBAddressControllerModelToPorts(cont);
|
||||
}
|
||||
|
||||
for (i = 0; i < def->nhubs; i++) {
|
||||
virDomainHubDefPtr hub = def->hubs[i];
|
||||
if (hub->type == VIR_DOMAIN_HUB_TYPE_USB)
|
||||
ret += VIR_DOMAIN_USB_HUB_PORTS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Try to find a free port on bus @bus.
|
||||
*
|
||||
* Returns 0 on success
|
||||
|
@ -277,6 +277,8 @@ int
|
||||
virDomainUSBAddressSetAddHub(virDomainUSBAddressSetPtr addrs,
|
||||
virDomainHubDefPtr hub)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
size_t
|
||||
virDomainUSBAddressCountAllPorts(virDomainDefPtr def);
|
||||
void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
|
||||
|
||||
int
|
||||
|
@ -108,6 +108,7 @@ virDomainPCIAddressSlotInUse;
|
||||
virDomainPCIAddressValidate;
|
||||
virDomainPCIControllerModelToConnectType;
|
||||
virDomainUSBAddressAssign;
|
||||
virDomainUSBAddressCountAllPorts;
|
||||
virDomainUSBAddressEnsure;
|
||||
virDomainUSBAddressPortFormat;
|
||||
virDomainUSBAddressPortFormatBuf;
|
||||
|
@ -1679,6 +1679,51 @@ qemuDomainAssignUSBPorts(virDomainUSBAddressSetPtr addrs,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainAssignUSBPortsCounter(virDomainDeviceInfoPtr info ATTRIBUTE_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
struct qemuAssignUSBIteratorInfo *data = opaque;
|
||||
|
||||
data->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainUSBAddressAddHubs(virDomainDefPtr def)
|
||||
{
|
||||
struct qemuAssignUSBIteratorInfo data = { .count = 0 };
|
||||
virDomainHubDefPtr hub = NULL;
|
||||
size_t available_ports;
|
||||
int ret = -1;
|
||||
|
||||
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 (VIR_ALLOC(hub) < 0)
|
||||
return -1;
|
||||
hub->type = VIR_DOMAIN_HUB_TYPE_USB;
|
||||
|
||||
if (VIR_APPEND_ELEMENT(def->hubs, def->nhubs, hub) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(hub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainAssignUSBAddresses(virDomainDefPtr def,
|
||||
virDomainObjPtr obj)
|
||||
@ -1690,6 +1735,9 @@ qemuDomainAssignUSBAddresses(virDomainDefPtr def,
|
||||
if (!(addrs = virDomainUSBAddressSetCreate()))
|
||||
goto cleanup;
|
||||
|
||||
if (qemuDomainUSBAddressAddHubs(def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainUSBAddressSetAddControllers(addrs, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
28
tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args
Normal file
28
tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.args
Normal file
@ -0,0 +1,28 @@
|
||||
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-mouse,id=input0,bus=usb.0,port=2 \
|
||||
-device usb-mouse,id=input1,bus=usb.0,port=1.1 \
|
||||
-device usb-mouse,id=input2,bus=usb.0,port=1.2 \
|
||||
-device usb-tablet,id=input3,bus=usb.0,port=1.3 \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
|
23
tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml
Normal file
23
tests/qemuxml2argvdata/qemuxml2argv-usb-hub-autoadd.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest1</name>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<memory unit='KiB'>219136</memory>
|
||||
<currentMemory unit='KiB'>219136</currentMemory>
|
||||
<vcpu placement='static'>1</vcpu>
|
||||
<os>
|
||||
<type arch='i686' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu</emulator>
|
||||
<controller type='usb' index='0'/>
|
||||
<memballoon model='virtio'/>
|
||||
<input type='mouse' bus='usb'>
|
||||
</input>
|
||||
<input type='mouse' bus='usb'>
|
||||
</input>
|
||||
<input type='mouse' bus='usb'>
|
||||
</input>
|
||||
<input type='tablet' bus='usb'/>
|
||||
</devices>
|
||||
</domain>
|
@ -1184,6 +1184,9 @@ mymain(void)
|
||||
DO_TEST("usb-hub",
|
||||
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
|
||||
QEMU_CAPS_NODEFCONFIG);
|
||||
DO_TEST("usb-hub-autoadd",
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user