mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-10-26 17:25:22 +03:00
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 <phrdina@redhat.com>
This commit is contained in:
parent
a51eea16f8
commit
b06c91d2fc
@ -1,8 +1,8 @@
|
||||
<hostdev mode="subsystem" type="usb" managed="yes">
|
||||
<source>
|
||||
<vendor id="0x0781"/>
|
||||
<product id="0x5151"/>
|
||||
<address bus="1" device="4"/>
|
||||
<vendor id="0x1d6b"/>
|
||||
<product id="0x0002"/>
|
||||
<address bus="2" device="1"/>
|
||||
</source>
|
||||
</hostdev>
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user