[Kimchi-devel] [PATCH] [Kimchi] Handle libvirt events for device attachment/detachment
Paulo Ricardo Paz Vital
pvital at linux.vnet.ibm.com
Mon Jul 11 23:48:24 UTC 2016
Reviewed-by: Paulo Ricardo Paz Vital <pvital at linux.vnet.ibm.com>
On Jul 11 04:31PM, Jose Ricardo Ziviani wrote:
> - kimchi will only finish the device attachment/detachment after
> receiving the appropriate event from libvirt.
>
> Signed-off-by: Jose Ricardo Ziviani <joserz at linux.vnet.ibm.com>
> ---
> model/libvirtevents.py | 48 ++++++++++++++++++++++++++++++++++++++++
> model/vmhostdevs.py | 60 +++++++++++++++++++++++++++++++++++++++++---------
> 2 files changed, 98 insertions(+), 10 deletions(-)
>
> diff --git a/model/libvirtevents.py b/model/libvirtevents.py
> index dfd22c6..0f3bfd5 100644
> --- a/model/libvirtevents.py
> +++ b/model/libvirtevents.py
> @@ -89,3 +89,51 @@ class LibvirtEvents(object):
> else:
> reason = e.message
> wok_log.error("Register of ENOSPC event failed: %s" % reason)
> +
> + def registerAttachDevicesEvent(self, conn, cb, arg):
> + """
> + register libvirt event to listen to devices attachment
> + """
> + try:
> + return conn.get().domainEventRegisterAny(
> + None,
> + libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_ADDED,
> + cb,
> + arg)
> +
> + except libvirt.libvirtError as e:
> + wok_log.error("register attach event failed: %s" % e.message)
> +
> + def registerDetachDevicesEvent(self, conn, cb, arg):
> + """
> + register libvirt event to listen to devices detachment
> + """
> + try:
> + return conn.get().domainEventRegisterAny(
> + None,
> + libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
> + cb,
> + arg)
> +
> + except libvirt.libvirtError as e:
> + wok_log.error("register detach event failed: %s" % e.message)
> +
> + def deregisterAttachDevicesEvent(self, conn, id):
> + """
> + deregister libvirt event to listen to devices attachment
> + """
> + try:
> + conn.get().domainEventDeregisterAny(id)
> +
> + except libvirt.libvirtError as e:
> + wok_log.error("deregister attach event failed: %s" % e.message)
> +
> + def deregisterDetachDevicesEvent(self, conn, id):
> + """
> + deregister libvirt event to listen to devices detachment
> + """
> + try:
> + conn.get().domainEventDeregisterAny(id)
> +
> + except libvirt.libvirtError as e:
> + wok_log.error("deregister detach event failed: %s" % e.message)
> diff --git a/model/vmhostdevs.py b/model/vmhostdevs.py
> index 2130ac4..676e40a 100644
> --- a/model/vmhostdevs.py
> +++ b/model/vmhostdevs.py
> @@ -47,8 +47,10 @@ class VMHostDevsModel(object):
> def __init__(self, **kargs):
> self.conn = kargs['conn']
> self.objstore = kargs['objstore']
> + self.events = kargs['eventsloop']
> self.caps = CapabilitiesModel(**kargs)
> self.task = TaskModel(**kargs)
> + self._eid = None
>
> def get_list(self, vmid):
> dom = VMModel.get_vm(vmid, self.conn)
> @@ -67,6 +69,17 @@ class VMHostDevsModel(object):
> if dev_name not in eligible_dev_names:
> raise InvalidParameter('KCHVMHDEV0002E', {'dev_name': dev_name})
>
> + def _event_devices(self, conn, dom, alias, opaque):
> + """
> + Callback to handle add/remove devices event
> + """
> + if self._eid is None:
> + wok_log.error("callbackID cannot be None")
> + return
> +
> + wok_log.info("Device %s added successfuly" % alias)
> + opaque('OK', True)
> +
> def create(self, vmid, params):
> dev_name = params['name']
> self._passthrough_device_validate(dev_name)
> @@ -224,6 +237,12 @@ class VMHostDevsModel(object):
> raise InvalidOperation('KCHVMHDEV0006E',
> {'name': dev_info['name']})
>
> + if self._eid is None:
> + self._eid = self.events.registerAttachDevicesEvent(
> + self.conn,
> + self._event_devices,
> + cb)
> +
> # all devices in the group that is going to be attached to the vm
> # must be detached from the host first
> with RollbackContext() as rollback:
> @@ -273,7 +292,6 @@ class VMHostDevsModel(object):
> rollback.prependDefer(dom.detachDeviceFlags, xmlstr,
> device_flags)
> rollback.commitAll()
> - cb('OK', True)
> return
>
> for pci_info in pci_infos:
> @@ -294,8 +312,6 @@ class VMHostDevsModel(object):
> xmlstr, device_flags)
> rollback.commitAll()
>
> - cb('OK', True)
> -
> def _count_3D_devices_attached(self, dom):
> counter = 0
> root = objectify.fromstring(dom.XMLDesc(0))
> @@ -407,6 +423,12 @@ class VMHostDevsModel(object):
> dev_info = params['dev_info']
> dom = VMModel.get_vm(vmid, self.conn)
>
> + if self._eid is None:
> + self._eid = self.events.registerAttachDevicesEvent(
> + self.conn,
> + self._event_devices,
> + cb)
> +
> with RollbackContext() as rollback:
> cb('Reading source device XML')
> xmlstr = self._get_scsi_device_xml(dev_info)
> @@ -421,8 +443,6 @@ class VMHostDevsModel(object):
> rollback.prependDefer(dom.detachDeviceFlags, xmlstr, device_flags)
> rollback.commitAll()
>
> - cb('OK', True)
> -
> def _get_usb_device_xml(self, dev_info):
> source = E.source(
> E.vendor(id=dev_info['vendor']['id']),
> @@ -440,6 +460,12 @@ class VMHostDevsModel(object):
> dev_info = params['dev_info']
> dom = VMModel.get_vm(vmid, self.conn)
>
> + if self._eid is None:
> + self._eid = self.events.registerAttachDevicesEvent(
> + self.conn,
> + self._event_devices,
> + cb)
> +
> with RollbackContext() as rollback:
> cb('Reading source device XML')
> xmlstr = self._get_usb_device_xml(dev_info)
> @@ -454,14 +480,14 @@ class VMHostDevsModel(object):
> rollback.prependDefer(dom.detachDeviceFlags, xmlstr, device_flags)
> rollback.commitAll()
>
> - cb('OK', True)
> -
>
> class VMHostDevModel(object):
> def __init__(self, **kargs):
> self.conn = kargs['conn']
> self.objstore = kargs['objstore']
> + self.events = kargs['eventsloop']
> self.task = TaskModel(**kargs)
> + self._eid = None
>
> def lookup(self, vmid, dev_name):
> dom = VMModel.get_vm(vmid, self.conn)
> @@ -509,6 +535,17 @@ class VMHostDevModel(object):
> task_params)
> return self.task.lookup(taskid)
>
> + def _event_devices(self, conn, dom, alias, opaque):
> + """
> + Callback to handle add/remove devices event
> + """
> + if self._eid is None:
> + wok_log.error("callbackID cannot be None")
> + return
> +
> + wok_log.info("Device %s removed successfuly" % alias)
> + opaque('OK', True)
> +
> def _detach_device(self, cb, params):
> cb('Detaching device.')
> vmid = params['vmid']
> @@ -526,12 +563,17 @@ class VMHostDevModel(object):
> raise InvalidOperation('KCHVMHDEV0006E',
> {'name': dev_info['name']})
>
> + if self._eid is None:
> + self._eid = self.events.registerDetachDevicesEvent(
> + self.conn,
> + self._event_devices,
> + cb)
> +
> if self._hotunplug_multifunction_pci(dom, hostdev, dev_name):
> if is_3D_device:
> cb('Updating MMIO from VM...')
> devsmodel = VMHostDevsModel(conn=self.conn)
> devsmodel.update_mmio_guest(vmid, False)
> - cb('OK', True)
> return
>
> for e in hostdev:
> @@ -552,8 +594,6 @@ class VMHostDevModel(object):
> raise NotFoundError('KCHVMHDEV0001E',
> {'vmid': vmid, 'dev_name': dev_name})
>
> - cb('OK', True)
> -
> def _get_devices_same_addr(self, hostdev, domain, bus, slot):
> devices = []
> for device in hostdev:
> --
> 2.7.4
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>
--
Paulo Ricardo Paz Vital
Linux Technology Center, IBM Systems
http://www.ibm.com/linux/ltc/
More information about the Kimchi-devel
mailing list