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

Cole Robinson crobinso at redhat.com
Thu May 9 22:01:49 UTC 2013


On 04/30/2013 10:53 AM, Guannan Ren wrote:
> 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'
> +

The machinery here is duplicating gobject signals. I think you can just add a
pre-start signal, and have the domain object hook its own callback into it.
Exceptions probably don't get raised up from signal handlers though, so you
might have to have the handler return the string error, which I think you can
grab as the return value of emit()

I pushed the first two patches.

- Cole

>      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)
>  
> 




More information about the virt-tools-list mailing list