vm: do not start QubesDB watch instance multiple times

vm.create_qdb_entries can be called multiple times - for example when
changing VM IP. Move starting qdb watcher to start(). And just in case,
cleanup old watcher (if still exists) before starting new one.
This fixes one FD leak.
This commit is contained in:
Marek Marczykowski-Górecki 2017-09-28 16:12:05 +02:00
parent b12fa13f06
commit 12b7e22d27
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
4 changed files with 12 additions and 7 deletions

View File

@ -38,7 +38,7 @@ class TC_00_AdminVM(qubes.tests.QubesTestCase):
qubes.vm.adminvm.AdminVM, 'start_qdb_watch') as mock_qdb:
self.vm = qubes.vm.adminvm.AdminVM(self.app,
xml=None)
mock_qdb.assert_called_once_with('dom0')
mock_qdb.assert_called_once_with()
self.addCleanup(self.cleanup_adminvm)
except: # pylint: disable=bare-except
if self.id().endswith('.test_000_init'):

View File

@ -486,14 +486,20 @@ class BaseVM(qubes.PropertyHolder):
self._qdb_connection_watch.close()
self._qdb_connection_watch = None
def start_qdb_watch(self, name, loop=None):
def start_qdb_watch(self, loop=None):
'''Start watching QubesDB
Calling this method in appropriate time is responsibility of child
class.
'''
# cleanup old watch connection first, if any
if self._qdb_connection_watch is not None:
asyncio.get_event_loop().remove_reader(
self._qdb_connection_watch.watch_fd())
self._qdb_connection_watch.close()
import qubesdb # pylint: disable=import-error
self._qdb_connection_watch = qubesdb.QubesDB(name)
self._qdb_connection_watch = qubesdb.QubesDB(self.name)
if loop is None:
loop = asyncio.get_event_loop()
loop.add_reader(self._qdb_connection_watch.watch_fd(),

View File

@ -58,7 +58,7 @@ class AdminVM(qubes.vm.BaseVM):
self._libvirt_domain = None
if not self.app.vmm.offline_mode:
self.start_qdb_watch('dom0')
self.start_qdb_watch()
def __str__(self):
return self.name

View File

@ -712,7 +712,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.storage = qubes.storage.Storage(self)
if not self.app.vmm.offline_mode and self.is_running():
self.start_qdb_watch(self.name)
self.start_qdb_watch()
@qubes.events.handler('property-set:label')
def on_property_set_label(self, event, name, newvalue, oldvalue=None):
@ -847,6 +847,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.log.info('Setting Qubes DB info for the VM')
yield from self.start_qubesdb()
self.create_qdb_entries()
self.start_qdb_watch()
self.log.warning('Activating the {} VM'.format(self.name))
self.libvirt_domain.resume()
@ -1742,8 +1743,6 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self.fire_event('domain-qdb-create')
self.start_qdb_watch(self.name)
# TODO async; update this in constructor
def _update_libvirt_domain(self):
'''Re-initialise :py:attr:`libvirt_domain`.'''