From 0695e7ba78f3095b8c085fa8bff841354808010e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 7 Nov 2015 00:21:16 +0100 Subject: [PATCH] utils/QubesWatch: register libvirt event loop only when really launched Registering event implementation in libvirt and then not calling it is harmful, because libvirt expects it working. Known drawbacks: - keep-alives are advertised as supported but not really sent (cause dropping connections) - connections are not closed (sockets remains open, effectively leaking file descriptors) So call libvirt.virEventRegisterDefaultImpl only when it will be really used (libvirt.virEventRunDefaultImpl called), which means calling it in QubesWatch. Registering events implementation have effect only on new libvirt connections, so start a new one for QubesWatch. Fixes QubesOS/qubes-issues#1380 --- core/qubes.py | 1 - core/qubesutils.py | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/qubes.py b/core/qubes.py index c32a46fe..e910b66b 100755 --- a/core/qubes.py +++ b/core/qubes.py @@ -159,7 +159,6 @@ class QubesVMMConnection(object): if 'xen.lowlevel.xs' in sys.modules: self._xs = xen.lowlevel.xs.xs() - libvirt.virEventRegisterDefaultImpl() self._libvirt_conn = libvirt.open(defaults['libvirt_uri']) if self._libvirt_conn == None: raise QubesException("Failed connect to libvirt driver") diff --git a/core/qubesutils.py b/core/qubesutils.py index 0ab25e34..689138a3 100644 --- a/core/qubesutils.py +++ b/core/qubesutils.py @@ -29,7 +29,7 @@ from lxml import etree from lxml.etree import ElementTree, SubElement, Element from qubes.qubes import QubesException -from qubes.qubes import vmm +from qubes.qubes import vmm,defaults from qubes.qubes import system_path,vm_files import sys import os @@ -737,11 +737,16 @@ class QubesWatch(object): self.block_callback = None self.meminfo_callback = None self.domain_callback = None - vmm.libvirt_conn.domainEventRegisterAny( + libvirt.virEventRegisterDefaultImpl() + # open new libvirt connection because above + # virEventRegisterDefaultImpl is in practice effective only for new + # connections + self.libvirt_conn = libvirt.open(defaults['libvirt_uri']) + self.libvirt_conn.domainEventRegisterAny( None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, self._domain_list_changed, None) - vmm.libvirt_conn.domainEventRegisterAny( + self.libvirt_conn.domainEventRegisterAny( None, libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, self._device_removed, None)