vm: fix deadlock on qrexec timeout handling
vm.kill() will try to get vm.startup_lock, so it can't be called while holding it already. Fix this by extracting vm._kill_locked(), which expect the lock to be already taken by the caller.
This commit is contained in:
parent
68dffb6895
commit
328697730b
@ -1026,11 +1026,11 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
|
|
||||||
except Exception as exc: # pylint: disable=bare-except
|
except Exception as exc: # pylint: disable=bare-except
|
||||||
self.log.error('Start failed: %s', str(exc))
|
self.log.error('Start failed: %s', str(exc))
|
||||||
if self.is_running() or self.is_paused():
|
|
||||||
# This avoids losing the exception if an exception is
|
# This avoids losing the exception if an exception is
|
||||||
# raised in self.force_shutdown(), because the vm is not
|
# raised in self.force_shutdown(), because the vm is not
|
||||||
# running or paused
|
# running or paused
|
||||||
yield from self.kill() # pylint: disable=not-an-iterable
|
if self.is_running() or self.is_paused():
|
||||||
|
yield from self._kill_locked()
|
||||||
|
|
||||||
# let anyone receiving domain-pre-start know that startup failed
|
# let anyone receiving domain-pre-start know that startup failed
|
||||||
yield from self.fire_event_async('domain-start-failed',
|
yield from self.fire_event_async('domain-start-failed',
|
||||||
@ -1133,6 +1133,15 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
raise qubes.exc.QubesVMNotStartedError(self)
|
raise qubes.exc.QubesVMNotStartedError(self)
|
||||||
|
|
||||||
with (yield from self.startup_lock):
|
with (yield from self.startup_lock):
|
||||||
|
yield from self._kill_locked()
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def _kill_locked(self):
|
||||||
|
'''Forcefully shutdown (destroy) domain.
|
||||||
|
|
||||||
|
This function needs to be called with self.startup_lock held.'''
|
||||||
try:
|
try:
|
||||||
self.libvirt_domain.destroy()
|
self.libvirt_domain.destroy()
|
||||||
except libvirt.libvirtError as e:
|
except libvirt.libvirtError as e:
|
||||||
@ -1144,8 +1153,6 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
# make sure all shutdown tasks are completed
|
# make sure all shutdown tasks are completed
|
||||||
yield from self._ensure_shutdown_handled()
|
yield from self._ensure_shutdown_handled()
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
def force_shutdown(self, *args, **kwargs):
|
def force_shutdown(self, *args, **kwargs):
|
||||||
'''Deprecated alias for :py:meth:`kill`'''
|
'''Deprecated alias for :py:meth:`kill`'''
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
Loading…
Reference in New Issue
Block a user