mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-26 21:57:33 +03:00
addhardware: differentiate duplicate usb devices by bus/addr
When there are multiple usb devices with same vendor/product in the host device list, the bus/addr is going to be used when attaching one of usb devices. Currently is_dup flag is only useful to VirtualHostDeviceUSB. I put get_nodedevs_number() in connection.py, so the startup hooks can use it.
This commit is contained in:
parent
4c1039252a
commit
32f0781531
@ -1,5 +1,7 @@
|
||||
<hostdev mode='subsystem' type='usb' managed='yes'>
|
||||
<source>
|
||||
<vendor id='0x0781'/>
|
||||
<product id='0x5151'/>
|
||||
<address bus='1' device='4'/>
|
||||
</source>
|
||||
</hostdev>
|
||||
|
@ -53,12 +53,12 @@ class TestNodeDev(unittest.TestCase):
|
||||
for attr in vals.keys():
|
||||
self.assertEqual(vals[attr], getattr(dev, attr))
|
||||
|
||||
def _testNode2DeviceCompare(self, nodename, devfile, nodedev=None):
|
||||
def _testNode2DeviceCompare(self, nodename, devfile, nodedev=None, is_dup=False):
|
||||
devfile = os.path.join("tests/nodedev-xml/devxml", devfile)
|
||||
if not nodedev:
|
||||
nodedev = self._nodeDevFromName(nodename)
|
||||
|
||||
dev = VirtualHostDevice.device_from_node(conn, nodedev=nodedev)
|
||||
dev = VirtualHostDevice.device_from_node(conn, nodedev=nodedev, is_dup=is_dup)
|
||||
utils.diff_compare(dev.get_xml_config() + "\n", devfile)
|
||||
|
||||
def testSystemDevice(self):
|
||||
@ -202,11 +202,7 @@ class TestNodeDev(unittest.TestCase):
|
||||
devfile = "usbdev2.xml"
|
||||
nodedev = self._nodeDevFromName(nodename)
|
||||
|
||||
# Force xml building to use bus, addr
|
||||
nodedev.product_id = None
|
||||
nodedev.vendor_id = None
|
||||
|
||||
self._testNode2DeviceCompare(nodename, devfile, nodedev=nodedev)
|
||||
self._testNode2DeviceCompare(nodename, devfile, nodedev=nodedev, is_dup=True)
|
||||
|
||||
def testNodeDev2PCI(self):
|
||||
nodename = "pci_1180_592"
|
||||
|
@ -281,7 +281,7 @@ class vmmAddHardware(vmmGObjectUI):
|
||||
# Host device list
|
||||
# model = [ Description, nodedev name ]
|
||||
host_dev = self.widget("host-device")
|
||||
host_dev_model = Gtk.ListStore(str, str)
|
||||
host_dev_model = Gtk.ListStore(str, str, str, object)
|
||||
host_dev.set_model(host_dev_model)
|
||||
|
||||
host_col = Gtk.TreeViewColumn()
|
||||
@ -577,7 +577,7 @@ class vmmAddHardware(vmmGObjectUI):
|
||||
if dev.name == subdev.parent:
|
||||
prettyname = dev.pretty_name(subdev)
|
||||
|
||||
model.append([prettyname, dev.name])
|
||||
model.append([prettyname, dev.name, devtype, dev])
|
||||
|
||||
if len(model) == 0:
|
||||
model.append([_("No Devices Available"), None])
|
||||
@ -1403,15 +1403,32 @@ class vmmAddHardware(vmmGObjectUI):
|
||||
def validate_page_hostdev(self):
|
||||
ret = self.get_config_host_device_info()
|
||||
nodedev_name = ret and ret[1] or None
|
||||
is_dup = False
|
||||
|
||||
if nodedev_name is None:
|
||||
return self.err.val_err(_("Physical Device Required"),
|
||||
_("A device must be selected."))
|
||||
|
||||
devtype = ret[2]
|
||||
nodedev = ret[3]
|
||||
if devtype == "usb_device":
|
||||
vendor = nodedev.vendor_id
|
||||
product = nodedev.product_id
|
||||
count = self.conn.get_nodedevs_number(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
|
||||
|
||||
try:
|
||||
self._dev = virtinst.VirtualHostDevice.device_from_node(
|
||||
conn=self.conn.vmm,
|
||||
name=nodedev_name)
|
||||
name=nodedev_name,
|
||||
nodedev=nodedev,
|
||||
is_dup=is_dup)
|
||||
except Exception, e:
|
||||
return self.err.val_err(_("Host device parameter error"), e)
|
||||
|
||||
|
@ -712,6 +712,21 @@ class vmmConnection(vmmGObject):
|
||||
|
||||
return retdevs
|
||||
|
||||
def get_nodedevs_number(self, devtype, vendor, product):
|
||||
count = 0
|
||||
devs = self.get_nodedevs(devtype)
|
||||
|
||||
for dev in devs:
|
||||
if vendor == dev.vendor_id and \
|
||||
product == dev.product_id:
|
||||
count += 1
|
||||
|
||||
logging.debug("There are %d node devices with "
|
||||
"vendorId: %s, productId: %s",
|
||||
count, vendor, product)
|
||||
|
||||
return count
|
||||
|
||||
def get_net_by_name(self, name):
|
||||
for net in self.nets.values():
|
||||
if net.get_name() == name:
|
||||
|
@ -28,7 +28,7 @@ class VirtualHostDevice(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_HOSTDEV
|
||||
|
||||
def device_from_node(conn, name=None, nodedev=None):
|
||||
def device_from_node(conn, name=None, nodedev=None, is_dup=False):
|
||||
"""
|
||||
Convert the passed device name to a VirtualHostDevice
|
||||
instance, with proper error reporting. Name can be any of the
|
||||
@ -56,7 +56,7 @@ class VirtualHostDevice(VirtualDevice):
|
||||
if isinstance(nodeinst, NodeDeviceParser.PCIDevice):
|
||||
return VirtualHostDevicePCI(conn, nodedev=nodeinst)
|
||||
elif isinstance(nodeinst, NodeDeviceParser.USBDevice):
|
||||
return VirtualHostDeviceUSB(conn, nodedev=nodeinst)
|
||||
return VirtualHostDeviceUSB(conn, nodedev=nodeinst, is_dup=is_dup)
|
||||
elif isinstance(nodeinst, NodeDeviceParser.NetDevice):
|
||||
parentname = nodeinst.parent
|
||||
try:
|
||||
@ -198,11 +198,12 @@ class VirtualHostDevice(VirtualDevice):
|
||||
|
||||
class VirtualHostDeviceUSB(VirtualHostDevice):
|
||||
|
||||
def __init__(self, conn, nodedev=None):
|
||||
def __init__(self, conn, nodedev=None, is_dup=False):
|
||||
VirtualHostDevice.__init__(self, conn, nodedev)
|
||||
|
||||
self.mode = "subsystem"
|
||||
self.type = "usb"
|
||||
self.is_dup = is_dup
|
||||
|
||||
self._set_from_nodedev(self._nodedev)
|
||||
|
||||
@ -217,7 +218,7 @@ class VirtualHostDeviceUSB(VirtualHostDevice):
|
||||
self.vendor = nodedev.vendor_id
|
||||
self.product = nodedev.product_id
|
||||
|
||||
if not (self.vendor or self.product):
|
||||
if self.is_dup:
|
||||
self.bus = nodedev.bus
|
||||
self.device = nodedev.device
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user