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
This commit is contained in:
Marek Marczykowski-Górecki 2015-11-07 00:21:16 +01:00
parent 93b7b3cb72
commit 0695e7ba78
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 8 additions and 4 deletions

View File

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

View File

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