From bbaf56c1e209fc479585618e972ac18ebf78d748 Mon Sep 17 00:00:00 2001 In-Reply-To: References: From: Pavel Hrdina Date: Thu, 23 Jul 2015 13:15:26 +0200 Subject: [PATCH 2/7] hostdev: add an address element for USB host devs if necessary This issue was fixed for few years but only in virt-manager, virt-install has the same bug. If you have two USB devices with same vendor and product ID, you need to use also address element to create a valid XML to define that device into a guest. This patch moves the logic from vmmAddHardware into VirtualHostDevice in order to not duplicate that code for virt-manager and virt-install. Also update the tests files to properly check this functionality. I've changed the USB device according the 'tests/testdriver.xml' and picked one of the USB HUBs, because they have the same vendor and product ID. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1230611 Signed-off-by: Pavel Hrdina (cherry picked from commit b06c91d2fc23644bfb13e174c7441f8a00c17477) Signed-off-by: Pavel Hrdina --- tests/nodedev-xml/devxml/usbdev2.xml | 6 +++--- tests/nodedev.py | 10 ++++------ virtManager/addhardware.py | 18 +++--------------- virtinst/devicehostdev.py | 19 ++++++++++++++++--- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/tests/nodedev-xml/devxml/usbdev2.xml b/tests/nodedev-xml/devxml/usbdev2.xml index 73364b5..e648c20 100644 --- a/tests/nodedev-xml/devxml/usbdev2.xml +++ b/tests/nodedev-xml/devxml/usbdev2.xml @@ -1,8 +1,8 @@ - - -
+ + +
diff --git a/tests/nodedev.py b/tests/nodedev.py index 28e0603..5d9fdec 100644 --- a/tests/nodedev.py +++ b/tests/nodedev.py @@ -81,14 +81,13 @@ class TestNodeDev(unittest.TestCase): "expect=%s\nactual=%s" % (devname, attr, expect, actual)) self.assertEqual(vals[attr], getattr(dev, attr)) - def _testNode2DeviceCompare(self, nodename, devfile, - nodedev=None, is_dup=False): + def _testNode2DeviceCompare(self, nodename, devfile, nodedev=None): devfile = os.path.join("tests/nodedev-xml/devxml", devfile) if not nodedev: nodedev = self._nodeDevFromName(nodename) dev = VirtualHostDevice(conn) - dev.set_from_nodedev(nodedev, use_full_usb=is_dup) + dev.set_from_nodedev(nodedev) utils.diff_compare(dev.get_xml_config() + "\n", devfile) def testSystemDevice(self): @@ -238,12 +237,11 @@ class TestNodeDev(unittest.TestCase): self._testNode2DeviceCompare(nodename, devfile) def testNodeDev2USB2(self): - nodename = "usb_device_781_5151_2004453082054CA1BEEE" + nodename = "usb_device_1d6b_2_0000_00_1d_7" devfile = "usbdev2.xml" nodedev = self._nodeDevFromName(nodename) - self._testNode2DeviceCompare(nodename, devfile, nodedev=nodedev, - is_dup=True) + self._testNode2DeviceCompare(nodename, devfile, nodedev=nodedev) def testNodeDev2PCI(self): nodename = "pci_1180_592" diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py index 7607529..87c71d5 100644 --- a/virtManager/addhardware.py +++ b/virtManager/addhardware.py @@ -246,7 +246,7 @@ class vmmAddHardware(vmmGObjectUI): # Host device list # model = [ Description, nodedev name ] host_dev = self.widget("host-device") - host_dev_model = Gtk.ListStore(str, str, str, object) + host_dev_model = Gtk.ListStore(str, str, object) host_dev.set_model(host_dev_model) host_col = Gtk.TreeViewColumn() @@ -1620,24 +1620,12 @@ class vmmAddHardware(vmmGObjectUI): def _validate_page_hostdev(self): row = uiutil.get_list_selected_row(self.widget("host-device")) - is_dup = False if row is None: return self.err.val_err(_("Physical Device Required"), _("A device must be selected.")) - devtype = row[2] - nodedev = row[3] - if devtype == "usb_device": - vendor = nodedev.vendor_id - product = nodedev.product_id - count = self.conn.get_nodedev_count(devtype, vendor, product) - if not count: - raise RuntimeError(_("Could not find USB device " - "(vendorId: %s, productId: %s) " - % (vendor, product))) - if count > 1: - is_dup = True + nodedev = row[2] try: dev = virtinst.VirtualHostDevice(self.conn.get_backend()) @@ -1654,7 +1642,7 @@ class vmmAddHardware(vmmGObjectUI): _("Do you really want to use the device?")) if not res: return False - dev.set_from_nodedev(nodedev, use_full_usb=is_dup) + dev.set_from_nodedev(nodedev) self._dev = dev except Exception, e: return self.err.val_err(_("Host device parameter error"), e) diff --git a/virtinst/devicehostdev.py b/virtinst/devicehostdev.py index 0396106..43297dc 100644 --- a/virtinst/devicehostdev.py +++ b/virtinst/devicehostdev.py @@ -25,7 +25,7 @@ from .xmlbuilder import XMLProperty class VirtualHostDevice(VirtualDevice): virtual_device_type = VirtualDevice.VIRTUAL_DEV_HOSTDEV - def set_from_nodedev(self, nodedev, use_full_usb=None): + def set_from_nodedev(self, nodedev): """ @use_full_usb: If set, and nodedev is USB, specify both vendor and product. Used if user requests bus/add on virt-install @@ -44,7 +44,20 @@ class VirtualHostDevice(VirtualDevice): self.vendor = nodedev.vendor_id self.product = nodedev.product_id - if use_full_usb: + count = 0 + + for dev in self.conn.fetch_all_nodedevs(): + if (dev.device_type == NodeDevice.CAPABILITY_TYPE_USBDEV and + dev.vendor_id == self.vendor and + dev.product_id == self.product): + count += 1 + + if not count: + raise RuntimeError(_("Could not find USB device " + "(vendorId: %s, productId: %s)") + % (vendor, product)) + + if count > 1: self.bus = nodedev.bus self.device = nodedev.device @@ -55,7 +68,7 @@ class VirtualHostDevice(VirtualDevice): founddev = checkdev break - self.set_from_nodedev(founddev, use_full_usb=use_full_usb) + self.set_from_nodedev(founddev) elif nodedev.device_type == nodedev.CAPABILITY_TYPE_SCSIDEV: self.type = "scsi" -- 2.5.0