[virt-tools-list] [PATCH 3/3] domain: add pre-start hook to check duplicate multiple node devices

Guannan Ren gren at redhat.com
Tue Apr 30 14:53:12 UTC 2013


If there are duplicate attached USB node devices, virt-manager
can't identify unique node device any more, the hook will throw an
tip to tell it is time to remove and reattach it to get updated
bus/addr info.

For these attached USB devices with bus/addr, only one attached
USB or none of attached devices, guest startup will continue.
---
 virtManager/domain.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/virtManager/domain.py b/virtManager/domain.py
index 791f2af..84703cf 100644
--- a/virtManager/domain.py
+++ b/virtManager/domain.py
@@ -151,6 +151,8 @@ class vmmDomain(vmmLibvirtObject):
         "inspection-changed": (GObject.SignalFlags.RUN_FIRST, None, []),
     }
 
+    HOOK_STARTUP_FLAG = '_startup'
+
     def __init__(self, conn, backend, uuid):
         vmmLibvirtObject.__init__(self, conn)
 
@@ -194,6 +196,8 @@ class vmmDomain(vmmLibvirtObject):
         self._stats_disk_supported = True
         self._stats_disk_skip = []
 
+        self._startup_hooks = []
+
         self.inspection = vmmInspectionData()
 
         if isinstance(self._backend, virtinst.Guest):
@@ -201,6 +205,9 @@ class vmmDomain(vmmLibvirtObject):
 
         self._libvirt_init()
 
+        self.add_hook(self.HOOK_STARTUP_FLAG,
+                      self.duplicate_nodedev_check)
+
     def _get_getvcpus_supported(self):
         if self._getvcpus_supported is None:
             self._getvcpus_supported = True
@@ -253,6 +260,49 @@ class vmmDomain(vmmLibvirtObject):
         self.connect("status-changed", self._update_start_vcpus)
         self.connect("config-changed", self._reparse_xml)
 
+    ########################
+    # Domain hook routines #
+    ########################
+
+    def duplicate_nodedev_check(self, data=None):
+        for hostdev in self.get_hostdev_devices():
+            devtype = hostdev.type
+
+            if devtype != "usb":
+                continue
+
+            vendor = hostdev.vendor
+            product = hostdev.product
+            bus = hostdev.bus
+            device = hostdev.device
+
+            if vendor and product:
+                count = self.conn.get_nodedevs_number("usb_device",
+                                                      vendor,
+                                                      product)
+                if not count:
+                    raise RuntimeError(_("Could not find USB device "
+                                         "(vendorId: %s, productId: %s) "
+                                         % (vendor, product)))
+
+                if count > 1 and not (bus and device):
+                    raise RuntimeError(_("The attached USB device "
+                                         "(vendorId: %s, productId: %s) "
+                                         "is not unique, please remove "
+                                         "and add it again!"
+                                         % (vendor, product)))
+
+    def add_hook(self, flag, func, index=None):
+        if not func:
+            return
+
+        hooks = getattr(self, ''.join([flag, "_hooks"]))
+
+        if index is None:
+            hooks.append(func)
+        else:
+            hooks.insert(index, func)
+
 
     ###########################
     # Misc API getter methods #
@@ -1171,6 +1221,11 @@ class vmmDomain(vmmLibvirtObject):
         if self.get_cloning():
             raise RuntimeError(_("Cannot start guest while cloning "
                                  "operation in progress"))
+
+        if self._startup_hooks:
+            for hook in self._startup_hooks:
+                hook()
+
         self._backend.create()
         self.idle_add(self.force_update_status)
 
-- 
1.8.1.4




More information about the virt-tools-list mailing list