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@xxxxxxxx> 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 |
_______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list