summaryrefslogtreecommitdiff
path: root/libvirtaio.py
diff options
context:
space:
mode:
authorWojtek Porczyk <woju@invisiblethingslab.com>2017-08-24 21:22:49 +0200
committerDaniel P. Berrange <berrange@redhat.com>2017-09-26 11:01:33 +0100
commitf7e5a9a085b1ed4dd72a38c787ade4a3a893463e (patch)
tree10a42fb1eb9f83f21841069dce6521d5b8dd0007 /libvirtaio.py
parent6ee87778ab8a0c493fc0a76d5ac278417fd4336a (diff)
downloadlibvirt-python-f7e5a9a085b1ed4dd72a38c787ade4a3a893463e.tar.gz
libvirtaio: add more debug logging
This logging is helpful for tracing problems with unclosed connections and leaking file descriptors. Signed-off-by: Wojtek Porczyk <woju@invisiblethingslab.com>
Diffstat (limited to 'libvirtaio.py')
-rw-r--r--libvirtaio.py33
1 files changed, 25 insertions, 8 deletions
diff --git a/libvirtaio.py b/libvirtaio.py
index 7c8c396..46de9ab 100644
--- a/libvirtaio.py
+++ b/libvirtaio.py
@@ -74,7 +74,7 @@ class Callback(object):
def close(self):
'''Schedule *ff* callback'''
self.impl.log.debug('callback %d close(), scheduling ff', self.iden)
- self.impl.schedule_ff_callback(self.opaque)
+ self.impl.schedule_ff_callback(self.iden, self.opaque)
#
# file descriptors
@@ -275,6 +275,10 @@ class virEventAsyncIOImpl(object):
self.descriptors = DescriptorDict(self)
self.log = logging.getLogger(self.__class__.__name__)
+ def __repr__(self):
+ return '<{} callbacks={} descriptors={}>'.format(
+ type(self).__name__, self.callbacks, self.descriptors)
+
def register(self):
'''Register this instance as event loop implementation'''
# pylint: disable=bad-whitespace
@@ -284,9 +288,18 @@ class virEventAsyncIOImpl(object):
self._add_timeout, self._update_timeout, self._remove_timeout)
return self
- def schedule_ff_callback(self, opaque):
+ def schedule_ff_callback(self, iden, opaque):
'''Schedule a ff callback from one of the handles or timers'''
- self.loop.call_soon(libvirt.virEventInvokeFreeCallback, opaque)
+ ensure_future(self._ff_callback(iden, opaque), loop=self.loop)
+
+ @asyncio.coroutine
+ def _ff_callback(self, iden, opaque):
+ '''Directly free the opaque object
+
+ This is a coroutine.
+ '''
+ self.log.debug('ff_callback(iden=%d, opaque=...)', iden)
+ return libvirt.virEventInvokeFreeCallback(opaque)
def is_idle(self):
'''Returns False if there are leftovers from a connection
@@ -309,10 +322,10 @@ class virEventAsyncIOImpl(object):
.. seealso::
https://libvirt.org/html/libvirt-libvirt-event.html#virEventAddHandleFuncFunc
'''
- self.log.debug('add_handle(fd=%d, event=%d, cb=%r, opaque=%r)',
- fd, event, cb, opaque)
callback = FDCallback(self, cb, opaque,
descriptor=self.descriptors[fd], event=event)
+ self.log.debug('add_handle(fd=%d, event=%d, cb=..., opaque=...) = %d',
+ fd, event, callback.iden)
self.callbacks[callback.iden] = callback
self.descriptors[fd].add_handle(callback)
return callback.iden
@@ -339,7 +352,11 @@ class virEventAsyncIOImpl(object):
https://libvirt.org/html/libvirt-libvirt-event.html#virEventRemoveHandleFunc
'''
self.log.debug('remove_handle(watch=%d)', watch)
- callback = self.callbacks.pop(watch)
+ try:
+ callback = self.callbacks.pop(watch)
+ except KeyError as err:
+ self.log.warning('remove_handle(): no such handle: %r', err.args[0])
+ raise
fd = callback.descriptor.fd
assert callback is self.descriptors[fd].remove_handle(watch)
if len(self.descriptors[fd].callbacks) == 0:
@@ -358,9 +375,9 @@ class virEventAsyncIOImpl(object):
.. seealso::
https://libvirt.org/html/libvirt-libvirt-event.html#virEventAddTimeoutFunc
'''
- self.log.debug('add_timeout(timeout=%d, cb=%r, opaque=%r)',
- timeout, cb, opaque)
callback = TimeoutCallback(self, cb, opaque)
+ self.log.debug('add_timeout(timeout=%d, cb=..., opaque=...) = %d',
+ timeout, callback.iden)
self.callbacks[callback.iden] = callback
callback.update(timeout=timeout)
return callback.iden