From 29f3c9b58fdb7ebd0a32e8509df8c0cd6e72aed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Mon, 22 May 2017 14:42:01 +0200 Subject: [PATCH] vm: don't try to define libvirt domain when just checking its state When libvirt domain is not defined, it isn't running for sure. This commit fixes the case when vm.is_running() appears anywhere in the code used during libvirt xml building. In this case, it's mostly about PCI device description for libvirt. --- qubes/vm/qubesvm.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 1bd75cc6..04066a6f 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -1494,6 +1494,20 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): Libvirt's enum describing precise state of a domain. ''' # pylint: disable=too-many-return-statements + # don't try to define libvirt domain, if it isn't there, VM surely + # isn't running + # reason for this "if": allow vm.is_running() in PCI (or other + # device) extension while constructing libvirt XML + if self._libvirt_domain is None: + try: + self._libvirt_domain = self.app.vmm.libvirt_conn.lookupByUUID( + self.uuid.bytes) + except libvirt.libvirtError as e: + if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN: + return 'Halted' + else: + raise + libvirt_domain = self.libvirt_domain if libvirt_domain is None: return 'Halted' @@ -1544,8 +1558,21 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM): if self.app.vmm.offline_mode: return False - # TODO context manager #1693 - return self.libvirt_domain and self.libvirt_domain.isActive() + # don't try to define libvirt domain, if it isn't there, VM surely + # isn't running + # reason for this "if": allow vm.is_running() in PCI (or other + # device) extension while constructing libvirt XML + if self._libvirt_domain is None: + try: + self._libvirt_domain = self.app.vmm.libvirt_conn.lookupByUUID( + self.uuid.bytes) + except libvirt.libvirtError as e: + if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN: + return False + else: + raise + + return self.libvirt_domain.isActive() def is_paused(self): '''Check whether this domain is paused.