[libvirt] [PATCH 14/17] Assign addresses to USB devices

Ján Tomko jtomko at redhat.com
Fri Jun 17 18:07:16 UTC 2016


Automatically assign addresses to USB devices.

Just like reserving, this is only done for newly defined domains.

https://bugzilla.redhat.com/show_bug.cgi?id=1215968
---
 src/conf/domain_addr.c                             | 109 +++++++++++++++++++--
 src/conf/domain_addr.h                             |   9 ++
 src/conf/domain_conf.c                             |  77 +++++++++++++++
 src/conf/domain_conf.h                             |   6 ++
 src/libvirt_private.syms                           |   3 +
 src/qemu/qemu_domain_address.c                     |  36 +++++++
 ...otplug-console-compat-2-live+console-virtio.xml |   1 +
 .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args  |   2 +-
 tests/qemuxml2argvdata/qemuxml2argv-bios.args      |   2 +-
 .../qemuxml2argv-console-compat-2-live.xml         |   1 +
 .../qemuxml2argv-console-compat-2.xml              |   4 +-
 .../qemuxml2argv-controller-order.args             |   8 +-
 .../qemuxml2argv-disk-usb-device-removable.args    |   3 +-
 .../qemuxml2argv-disk-usb-device.args              |   2 +-
 .../qemuxml2argv-graphics-spice-timeout.args       |   2 +-
 ...muxml2argv-hostdev-usb-address-device-boot.args |   2 +-
 .../qemuxml2argv-hostdev-usb-address-device.args   |   2 +-
 .../qemuxml2argv-hostdev-usb-address.args          |   2 +-
 .../qemuxml2argv-hugepages-numa.args               |   2 +-
 .../qemuxml2argv-input-usbmouse.args               |   2 +-
 .../qemuxml2argv-input-usbtablet.args              |   2 +-
 .../qemuxml2argv-pseries-usb-kbd.args              |   2 +-
 .../qemuxml2argv-serial-spiceport.args             |   2 +-
 .../qemuxml2argv-smartcard-controller.args         |   2 +-
 .../qemuxml2argv-smartcard-host-certificates.args  |   2 +-
 .../qemuxml2argv-smartcard-host.args               |   2 +-
 ...emuxml2argv-smartcard-passthrough-spicevmc.args |   2 +-
 .../qemuxml2argv-smartcard-passthrough-tcp.args    |   2 +-
 .../qemuxml2argv-sound-device.args                 |   2 +-
 .../qemuxml2argv-usb-port-autoassign.args          |  28 ++++++
 .../qemuxml2argv-usb-port-autoassign.xml           |  27 +++++
 tests/qemuxml2argvtest.c                           |   3 +
 32 files changed, 320 insertions(+), 31 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.xml

diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 0706e6e..e089763 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -1495,13 +1495,8 @@ virDomainUSBAddressSetAddHub(virDomainUSBAddressSetPtr addrs,
     if (!(newHub = virDomainUSBAddressHubNew(VIR_DOMAIN_USB_HUB_PORTS)))
         goto cleanup;
 
-    /* TODO: remove in the next patch.
-     * Skip hubs with no address to pass 'make check' until we start
-     * auto-assigning their addresses */
-    if (hub->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-        ret = 0;
+    if (virDomainUSBAddressEnsure(addrs, &hub->info) < 0)
         goto cleanup;
-    }
 
     if (hub->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -1551,9 +1546,89 @@ int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
 }
 
 
+static int
+virDomainUSBAddressFindFreePort(virDomainUSBAddressHubPtr hub,
+                                unsigned int *portpath,
+                                unsigned int level)
+{
+    unsigned int port;
+    ssize_t portIdx;
+    size_t i;
+
+    /* Look for free ports on the current hub */
+    if ((portIdx = virBitmapNextClearBit(hub->ports, -1)) >= 0) {
+        port = portIdx + 1;
+        VIR_DEBUG("Found a free port %u at level %u", port, level);
+        portpath[level] = port;
+        return 0;
+    }
+
+    VIR_DEBUG("No ports found on hub %p, trying the hubs on it", hub);
+
+    if (level >= VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH - 1)
+        return -1;
+
+    /* Recursively search through the ports that contain another hub */
+    for (i = 0; i < hub->nports; i++) {
+        if (!hub->hubs[i])
+            continue;
+
+        port = i + 1;
+        VIR_DEBUG("Looking at USB hub at level: %u port: %u", level, port);
+        if (virDomainUSBAddressFindFreePort(hub->hubs[i], portpath,
+                                            level + 1) < 0)
+            continue;
+
+        portpath[level] = port;
+        return 0;
+    }
+    return -1;
+}
+
+
+int
+virDomainUSBAddressAssign(virDomainUSBAddressSetPtr addrs,
+                          virDomainDeviceInfoPtr info)
+{
+    unsigned int portpath[VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH] = { 0 };
+    char *portstr = NULL;
+    size_t i;
+    int ret = -1;
+
+    for (i = 0; i < addrs->nbuses; i++) {
+        virDomainUSBAddressHubPtr hub = addrs->buses[i];
+        if (!hub)
+            continue;
+
+        if (virDomainUSBAddressFindFreePort(hub, portpath, 0) < 0)
+            continue;
+
+        /* we found a free port */
+        if (!(portstr = virDomainUSBAddressPortFormat(portpath)))
+            goto cleanup;
+
+        info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB;
+        info->addr.usb.bus = i;
+        memcpy(info->addr.usb.port, portpath, sizeof(portpath));
+        VIR_DEBUG("Assigning USB addr bus=%u port=%s",
+                  info->addr.usb.bus, portstr);
+        VIR_FREE(portstr);
+        if (virDomainUSBAddressReserve(NULL, NULL, info, addrs) < 0)
+            goto cleanup;
+
+        return 0;
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No free USB ports"));
+ cleanup:
+    VIR_FREE(portstr);
+    return ret;
+}
+
+
 int
 virDomainUSBAddressReserve(virDomainDefPtr def ATTRIBUTE_UNUSED,
-                           virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+                           virDomainDeviceDefPtr dev,
                            virDomainDeviceInfoPtr info,
                            void *data)
 {
@@ -1563,6 +1638,10 @@ virDomainUSBAddressReserve(virDomainDefPtr def ATTRIBUTE_UNUSED,
     int ret = -1;
     int targetPort;
 
+    /* USB hubs are dealt with in virDomainUSBAddressSetAddHub */
+    if (dev && dev->type == VIR_DOMAIN_DEVICE_HUB)
+        return 0;
+
     if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB)
         return 0;
 
@@ -1589,3 +1668,19 @@ virDomainUSBAddressReserve(virDomainDefPtr def ATTRIBUTE_UNUSED,
     VIR_FREE(portstr);
     return ret;
 }
+
+
+int
+virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
+                          virDomainDeviceInfoPtr info)
+{
+    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+        if (virDomainUSBAddressAssign(addrs, info) < 0)
+            return -1;
+    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
+        if (virDomainUSBAddressReserve(NULL, NULL, info, addrs) < 0)
+            return -1;
+    }
+
+    return 0;
+}
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index 502b1a2..ce640fb 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -272,9 +272,18 @@ int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
 void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
 
 int
+virDomainUSBAddressAssign(virDomainUSBAddressSetPtr addrs,
+                          virDomainDeviceInfoPtr info)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+int
 virDomainUSBAddressReserve(virDomainDefPtr def,
                            virDomainDeviceDefPtr dev,
                            virDomainDeviceInfoPtr info,
                            void *data)
     ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+int
+virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
+                          virDomainDeviceInfoPtr info)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 #endif /* __DOMAIN_ADDR_H__ */
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a2cae44..2f46c72 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -24010,6 +24010,83 @@ virDomainSmartcardDefForeach(virDomainDefPtr def,
 }
 
 
+int
+virDomainUSBDeviceDefForeach(virDomainDefPtr def,
+                             virDomainUSBDeviceDefIterator iter,
+                             void *opaque)
+{
+    size_t i;
+
+    /* usb-hub */
+    for (i = 0; i < def->nhubs; i++) {
+        virDomainHubDefPtr hub = def->hubs[i];
+        if (hub->type == VIR_DOMAIN_HUB_TYPE_USB) {
+            if (iter(&hub->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* usb-host */
+    for (i = 0; i < def->nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+        if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+            if (iter(hostdev->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* usb-storage */
+    for (i = 0; i < def->ndisks; i++) {
+        virDomainDiskDefPtr disk = def->disks[i];
+        if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+            if (iter(&disk->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* TODO: add def->nets here when libvirt starts supporting usb-net */
+
+    /* usb-ccid */
+    for (i = 0; i < def->ncontrollers; i++) {
+        virDomainControllerDefPtr cont = def->controllers[i];
+        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_CCID) {
+            if (iter(&cont->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* usb-kbd, usb-mouse, usb-tablet */
+    for (i = 0; i < def->ninputs; i++) {
+        virDomainInputDefPtr input = def->inputs[i];
+
+        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+            if (iter(&input->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* usb-serial */
+    for (i = 0; i < def->nserials; i++) {
+        virDomainChrDefPtr serial = def->serials[i];
+        if (serial->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
+            if (iter(&serial->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    /* usb-audio model=usb */
+    for (i = 0; i < def->nsounds; i++) {
+        virDomainSoundDefPtr sound = def->sounds[i];
+        if (sound->model == VIR_DOMAIN_SOUND_MODEL_USB) {
+            if (iter(&sound->info, opaque) < 0)
+                return -1;
+        }
+    }
+
+    return 0;
+}
+
+
 /* Call iter(disk, name, depth, opaque) for each element of disk and
  * its backing chain in the pre-populated disk->src.backingStore.
  * ignoreOpenFailure determines whether to warn about a chain that
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 428f85d..2aa519c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2894,6 +2894,12 @@ typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
                                             size_t depth,
                                             void *opaque);
 
+typedef int (*virDomainUSBDeviceDefIterator)(virDomainDeviceInfoPtr info,
+                                             void *opaque);
+int virDomainUSBDeviceDefForeach(virDomainDefPtr def,
+                                 virDomainUSBDeviceDefIterator iter,
+                                 void *opaque);
+
 int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
                                 bool ignoreOpenFailure,
                                 virDomainDiskDefPathIterator iter,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 765ac0f..4b3de7b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -109,6 +109,8 @@ virDomainPCIAddressSetGrow;
 virDomainPCIAddressSlotInUse;
 virDomainPCIAddressValidate;
 virDomainPCIControllerModelToConnectType;
+virDomainUSBAddressAssign;
+virDomainUSBAddressEnsure;
 virDomainUSBAddressPortFormat;
 virDomainUSBAddressPortFormatBuf;
 virDomainUSBAddressReserve;
@@ -478,6 +480,7 @@ virDomainTPMBackendTypeToString;
 virDomainTPMDefFree;
 virDomainTPMModelTypeFromString;
 virDomainTPMModelTypeToString;
+virDomainUSBDeviceDefForeach;
 virDomainVideoDefaultRAM;
 virDomainVideoDefaultType;
 virDomainVideoDefFree;
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index c5f4150..ac07c46 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1619,6 +1619,37 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
 }
 
 
+struct qemuAssignUSBIteratorInfo {
+    virDomainUSBAddressSetPtr addrs;
+    size_t count;
+};
+
+
+static int
+qemuDomainAssignUSBPortsIterator(virDomainDeviceInfoPtr info,
+                                 void *opaque)
+{
+    struct qemuAssignUSBIteratorInfo *data = opaque;
+
+    if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+        return 0;
+
+    return virDomainUSBAddressAssign(data->addrs, info);
+}
+
+
+static int
+qemuDomainAssignUSBPorts(virDomainUSBAddressSetPtr addrs,
+                         virDomainDefPtr def)
+{
+    struct qemuAssignUSBIteratorInfo data = { .addrs = addrs };
+
+    return virDomainUSBDeviceDefForeach(def,
+                                        qemuDomainAssignUSBPortsIterator,
+                                        &data);
+}
+
+
 static int
 qemuDomainAssignUSBAddresses(virDomainDefPtr def,
                              virDomainObjPtr obj)
@@ -1638,6 +1669,11 @@ qemuDomainAssignUSBAddresses(virDomainDefPtr def,
 
     VIR_DEBUG("Existing USB addresses have been reserved");
 
+    if (qemuDomainAssignUSBPorts(addrs, def) < 0)
+        goto cleanup;
+
+    VIR_DEBUG("Finished assigning USB ports");
+
     if (obj && obj->privateData) {
         priv = obj->privateData;
         priv->usbaddrs = addrs;
diff --git a/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2-live+console-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2-live+console-virtio.xml
index 3495ee6..7ca36d5 100644
--- a/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2-live+console-virtio.xml
+++ b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2-live+console-virtio.xml
@@ -100,6 +100,7 @@
     </channel>
     <input type='tablet' bus='usb'>
       <alias name='input0'/>
+      <address type='usb' bus='0' port='1'/>
     </input>
     <input type='mouse' bus='ps2'>
       <alias name='input1'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
index fe4e419..848a029 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
@@ -21,5 +21,5 @@ QEMU_AUDIO_DRV=none \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
 -serial pty \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios.args b/tests/qemuxml2argvdata/qemuxml2argv-bios.args
index 012af85..604b871 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-bios.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios.args
@@ -22,5 +22,5 @@ QEMU_AUDIO_DRV=none \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
 -serial pty \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2-live.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2-live.xml
index b36af27..f300940 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2-live.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2-live.xml
@@ -95,6 +95,7 @@
     </channel>
     <input type='tablet' bus='usb'>
       <alias name='input0'/>
+      <address type='usb' bus='0' port='1'/>
     </input>
     <input type='mouse' bus='ps2'>
       <alias name='input1'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml
index 2ae104e..7b35709 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml
@@ -78,7 +78,9 @@
       <target type='virtio' name='org.qemu.guest_agent.0'/>
       <address type='virtio-serial' controller='0' bus='0' port='1'/>
     </channel>
-    <input type='tablet' bus='usb'/>
+    <input type='tablet' bus='usb'>
+      <address type='usb' bus='0' port='1'/>
+    </input>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
     <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-controller-order.args b/tests/qemuxml2argvdata/qemuxml2argv-controller-order.args
index 52c1a74..ac6243e 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-controller-order.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-controller-order.args
@@ -19,8 +19,8 @@ nowait \
 -boot order=cna,menu=off \
 -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
 -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x7 \
--device usb-hub,id=hub0 \
--device usb-ccid,id=ccid0 \
+-device usb-hub,id=hub0,bus=usb.0,port=1 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1.1 \
 -drive file=/tmp/fdr.img,format=raw,if=none,id=drive-virtio-disk0,cache=none,\
 aio=native \
 -device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\
@@ -37,10 +37,10 @@ media=cdrom,id=drive-ide0-1-0,readonly=on \
 -chardev spicevmc,id=charchannel0,name=vdagent \
 -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
 id=channel0,name=com.redhat.spice.0 \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1.2 \
 -spice port=5901,tls-port=5902,addr=0.0.0.0,x509-dir=/etc/pki/libvirt-spice \
 -vga cirrus \
 -device intel-hda,id=sound0,bus=pci.0,addr=0x4 \
 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 \
--device usb-host,hostbus=14,hostaddr=6,id=hostdev0 \
+-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=usb.0,port=2 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device-removable.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device-removable.args
index 63e2bb2..7cda592 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device-removable.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device-removable.args
@@ -21,5 +21,6 @@ QEMU_AUDIO_DRV=none \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
 -drive file=/tmp/usbdisk.img,format=raw,if=none,id=drive-usb-disk0 \
--device usb-storage,drive=drive-usb-disk0,id=usb-disk0,removable=on \
+-device usb-storage,bus=usb.0,port=1,drive=drive-usb-disk0,id=usb-disk0,\
+removable=on \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args
index 5d1ea98..03ef44f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args
@@ -21,5 +21,5 @@ QEMU_AUDIO_DRV=none \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
 -drive file=/tmp/usbdisk.img,format=raw,if=none,id=drive-usb-disk0 \
--device usb-storage,drive=drive-usb-disk0,id=usb-disk0 \
+-device usb-storage,bus=usb.0,port=1,drive=drive-usb-disk0,id=usb-disk0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.args
index c0be4ee..cead7d6 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.args
@@ -28,7 +28,7 @@ media=cdrom,id=drive-ide0-1-0,readonly=on \
 -device rtl8139,vlan=0,id=net0,mac=52:54:00:71:70:89,bus=pci.0,addr=0x7 \
 -net tap,fd=3,vlan=0,name=hostnet0 \
 -serial pty \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
 -spice port=5900,addr=127.0.0.1 \
 -vga std \
 -device AC97,id=sound0,bus=pci.0,addr=0x3 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device-boot.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device-boot.args
index 8c00055..86f394b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device-boot.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device-boot.args
@@ -19,5 +19,5 @@ QEMU_AUDIO_DRV=none \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bootindex=1 \
+-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bootindex=1,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
index b5e6834..7883c61 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args
@@ -20,5 +20,5 @@ QEMU_AUDIO_DRV=none \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device usb-host,hostbus=14,hostaddr=6,id=hostdev0 \
+-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.args
index bb5d55a..d1c3e8f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.args
@@ -19,4 +19,4 @@ QEMU_AUDIO_DRV=none \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device usb-host,hostbus=14,hostaddr=6,id=hostdev0
+-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=usb.0,port=1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
index c5a9e53..08ed54c 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args
@@ -46,7 +46,7 @@ id=channel0,name=org.qemu.guest_agent.0 \
 -chardev spicevmc,id=charchannel1,name=vdagent \
 -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
 id=channel1,name=com.redhat.spice.0 \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
 -spice port=5901,tls-port=5902,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice \
 -vga qxl \
 -global qxl-vga.ram_size=67108864 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args
index bd0e5c6..df96e6a 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args
@@ -19,4 +19,4 @@ QEMU_AUDIO_DRV=none \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device usb-mouse,id=input0
+-device usb-mouse,id=input0,bus=usb.0,port=1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args
index 294515f..faf21d5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args
@@ -19,4 +19,4 @@ QEMU_AUDIO_DRV=none \
 -usb \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
--device usb-tablet,id=input0
+-device usb-tablet,id=input0,bus=usb.0,port=1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args
index 25c16cb..5887616 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args
@@ -22,4 +22,4 @@ server,nowait \
 -device pci-ohci,id=usb,bus=pci,addr=0x1 \
 -chardev pty,id=charserial0 \
 -device spapr-vty,chardev=charserial0,reg=0x30000000 \
--device usb-kbd,id=input0
+-device usb-kbd,id=input0,bus=usb.0,port=1
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args
index 246e854..f05c3f2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args
@@ -23,7 +23,7 @@ server,nowait \
 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
 -chardev spiceport,id=charserial0,name=org.qemu.console.serial.0 \
 -device isa-serial,chardev=charserial0,id=serial0 \
--device usb-tablet,id=input0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
 -spice port=5903,tls-port=5904,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice \
 -device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,\
 addr=0x2 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.args
index 8cb0968..c75054b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-controller.args
@@ -20,6 +20,6 @@ server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--device usb-ccid,id=ccid0 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1 \
 -device ccid-card-emulated,backend=nss-emulated,id=smartcard0,bus=ccid0.0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args
index d4a4d31..f6f5076 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args
@@ -20,7 +20,7 @@ server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--device usb-ccid,id=ccid0 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1 \
 -device ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,\
 cert3=cert3,db=/etc/pki/nssdb,id=smartcard0,bus=ccid0.0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args
index 8cb0968..c75054b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-host.args
@@ -20,6 +20,6 @@ server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--device usb-ccid,id=ccid0 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1 \
 -device ccid-card-emulated,backend=nss-emulated,id=smartcard0,bus=ccid0.0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args
index 7411f2a..819098e 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-spicevmc.args
@@ -20,7 +20,7 @@ server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--device usb-ccid,id=ccid0 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1 \
 -chardev spicevmc,id=charsmartcard0,name=smartcard \
 -device ccid-card-passthru,chardev=charsmartcard0,id=smartcard0,bus=ccid0.0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.args b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.args
index 93bbbc4..1563f1a 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-smartcard-passthrough-tcp.args
@@ -20,7 +20,7 @@ server,nowait \
 -no-acpi \
 -boot c \
 -usb \
--device usb-ccid,id=ccid0 \
+-device usb-ccid,id=ccid0,bus=usb.0,port=1 \
 -chardev socket,id=charsmartcard0,host=127.0.0.1,port=2001,server,nowait \
 -device ccid-card-passthru,chardev=charsmartcard0,id=smartcard0,bus=ccid0.0 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
index 8d846a0..b084f4e 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
@@ -34,5 +34,5 @@ QEMU_AUDIO_DRV=none \
 -device ich9-intel-hda,id=sound7,bus=pci.0,addr=0x8 \
 -device hda-micro,id=sound7-codec0,bus=sound7.0,cad=0 \
 -device hda-duplex,id=sound7-codec1,bus=sound7.0,cad=1 \
--device usb-audio,id=sound8 \
+-device usb-audio,id=sound8,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x9
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.args
new file mode 100644
index 0000000..ac5cfdd
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.args
@@ -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 \
+-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-mouse,id=input0,bus=usb.0,port=1.1 \
+-device usb-mouse,id=input1,bus=usb.0,port=1.2 \
+-device usb-mouse,id=input2,bus=usb.0,port=1.3 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.xml
new file mode 100644
index 0000000..a2fe34e
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-port-autoassign.xml
@@ -0,0 +1,27 @@
+<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'/>
+    <hub type='usb'>
+      <address type='usb' bus='0' port='1'/>
+    </hub>
+    <input type='mouse' bus='usb'>
+    </input>
+    <hub type='usb'>
+    </hub>
+    <input type='mouse' bus='usb'>
+    </input>
+    <input type='mouse' bus='usb'>
+    </input>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 1a01240..1c97d16 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1165,6 +1165,9 @@ mymain(void)
     DO_TEST("usb-ports",
             QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
             QEMU_CAPS_NODEFCONFIG);
+    DO_TEST("usb-port-autoassign",
+            QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
+            QEMU_CAPS_NODEFCONFIG);
     DO_TEST("usb-redir",
             QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG,
             QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_USB_HUB,
-- 
2.7.3




More information about the libvir-list mailing list