[virt-tools-list] [virt-tool-list] [PATCH V2] addhardware: Deal with the conflict host device

Lin Ma lma at suse.com
Wed Aug 13 10:38:35 UTC 2014


Changes from V1 to V2:

* merge is_using_by_active_vm function to is_conflict_hostdev function according to Giuseppe's suggestion.
  (But remained hiding mechanism for conflict host device in active vm)

* Using is_dup flag to see whether or not comparing the bus & device fields because of Bus and device fields help to
  identity device uniqueness only for attached multiple usb devices which have same vendor/product in inactive vm.


>>> Lin Ma <lma at suse.com> 08/13/14 6:17 PM >>>
If a host device is in use by an active guest, Doesn't append it to
list while adding hardware.

If a host device is in use by inactive guests, Then warn user and
let user make choice while adding hardware.

Signed-off-by: Lin Ma 
---
 virtManager/addhardware.py | 17 +++++++++++++++++
 virtinst/devicehostdev.py  | 47 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py
index 02cff57..eedb351 100644
--- a/virtManager/addhardware.py
+++ b/virtManager/addhardware.py
@@ -835,6 +835,11 @@ class vmmAddHardware(vmmGObjectUI):
 
         devs = self.conn.get_nodedevs(devtype, devcap)
         for dev in devs:
+            if virtinst.VirtualHostDevice.is_conflict_hostdev \
+                    (self.conn.get_backend(), devtype, dev, "inactive"):
+                # Doesn't append device which is in use by an active VM to list.
+                continue
+
             prettyname = dev.pretty_name()
 
             for subdev in subdevs:
@@ -1739,6 +1744,18 @@ class vmmAddHardware(vmmGObjectUI):
 
         try:
             dev = virtinst.VirtualHostDevice(self.conn.get_backend())
+            # Hostdev collision
+            names = virtinst.VirtualHostDevice.is_conflict_hostdev \
+                    (self.conn.get_backend(), devtype, nodedev, "active", \
+                    is_dup)
+            if names:
+                res = self.err.yes_no(
+                        _('The device is already in use by other guests %s') %
+                         (names),
+                        _("Do you really want to use the device?"))
+                if not res:
+                    return False
+
             dev.set_from_nodedev(nodedev, use_full_usb=is_dup)
             self._dev = dev
         except Exception, e:
diff --git a/virtinst/devicehostdev.py b/virtinst/devicehostdev.py
index a5d1a2a..39a6213 100644
--- a/virtinst/devicehostdev.py
+++ b/virtinst/devicehostdev.py
@@ -89,5 +89,52 @@ class VirtualHostDevice(VirtualDevice):
     driver_name = XMLProperty("./driver/@name")
     rom_bar = XMLProperty("./rom/@bar", is_onoff=True)
 
+    @staticmethod
+    def is_conflict_hostdev(conn, devtype, dev, vm_filter, is_dup=True):
+        if vm_filter == "active":
+            ret = []
+        vms = conn.fetch_all_guests()
+        for vm in vms:
+            _backend = vm.conn.lookupByName(vm.name)
+            if vm_filter == "inactive":
+                if not _backend.isActive():
+                    continue
+            elif vm_filter == "active":
+                if _backend.isActive():
+                    continue
+            for hostdev in vm.get_devices("hostdev"):
+                if devtype == NodeDevice.CAPABILITY_TYPE_USBDEV and \
+                        hostdev.type == "usb":
+                    if is_dup:
+                        if hostdev.bus == dev.bus and \
+                                hostdev.device == dev.device and \
+                                hostdev.vendor == dev.vendor_id and \
+                                hostdev.product == dev.product_id:
+                            if vm_filter == "inactive":
+                                return True
+                            elif vm_filter == "active":
+                                ret.append(vm.name)
+                    else:
+                        if hostdev.vendor == dev.vendor_id and \
+                                hostdev.product == dev.product_id:
+                            if vm_filter == "inactive":
+                                return True
+                            elif vm_filter == "active":
+                                ret.append(vm.name)
+                elif devtype == NodeDevice.CAPABILITY_TYPE_PCI and \
+                        hostdev.type == "pci":
+                    if str(int(hostdev.domain, 16)) == dev.domain and \
+                            str(int(hostdev.bus, 16)) == dev.bus and \
+                            str(int(hostdev.slot, 16)) == dev.slot and \
+                            str(int(hostdev.function, 16)) == dev.function:
+                        if vm_filter == "inactive":
+                            return True
+                        elif vm_filter == "active":
+                            ret.append(vm.name)
+        if vm_filter == "inactive":
+            return False
+        elif vm_filter == "active":
+            return ret
+
 
 VirtualHostDevice.register_type()
-- 
1.8.4




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20140813/7aae83fc/attachment.htm>


More information about the virt-tools-list mailing list