Do not abort suspend hooks if any qubes.Suspend* service fails to run
First of all, do not try to call those services in VMs not having qrexec installed - for example Windows VMs without qubes tools. Then, even if service call fails for any other reason, only log it but do not prevent other services from being called. A single uncooperative VM should generally be able only to hurt itself, not break other VMs during suspend. Fixes QubesOS/qubes-issues#3489
This commit is contained in:
parent
eeec2e0ddd
commit
9257a6d14f
@ -95,13 +95,19 @@ class QubesInternalAPI(qubes.api.AbstractQubesAPI):
|
|||||||
for vm in self.app.domains:
|
for vm in self.app.domains:
|
||||||
if isinstance(vm, qubes.vm.adminvm.AdminVM):
|
if isinstance(vm, qubes.vm.adminvm.AdminVM):
|
||||||
continue
|
continue
|
||||||
if vm.is_running():
|
if not vm.is_running():
|
||||||
|
continue
|
||||||
|
if not vm.features.check_with_template('qrexec', False):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
proc = yield from vm.run_service(
|
proc = yield from vm.run_service(
|
||||||
'qubes.SuspendPreAll', user='root',
|
'qubes.SuspendPreAll', user='root',
|
||||||
stdin=subprocess.DEVNULL,
|
stdin=subprocess.DEVNULL,
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL)
|
stderr=subprocess.DEVNULL)
|
||||||
processes.append(proc)
|
processes.append(proc)
|
||||||
|
except qubes.exc.QubesException as e:
|
||||||
|
vm.log.warning('Failed to run qubes.SuspendPreAll: %s', str(e))
|
||||||
|
|
||||||
# FIXME: some timeout?
|
# FIXME: some timeout?
|
||||||
if processes:
|
if processes:
|
||||||
@ -141,13 +147,19 @@ class QubesInternalAPI(qubes.api.AbstractQubesAPI):
|
|||||||
for vm in self.app.domains:
|
for vm in self.app.domains:
|
||||||
if isinstance(vm, qubes.vm.adminvm.AdminVM):
|
if isinstance(vm, qubes.vm.adminvm.AdminVM):
|
||||||
continue
|
continue
|
||||||
if vm.is_running():
|
if not vm.is_running():
|
||||||
|
continue
|
||||||
|
if not vm.features.check_with_template('qrexec', False):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
proc = yield from vm.run_service(
|
proc = yield from vm.run_service(
|
||||||
'qubes.SuspendPostAll', user='root',
|
'qubes.SuspendPostAll', user='root',
|
||||||
stdin=subprocess.DEVNULL,
|
stdin=subprocess.DEVNULL,
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL)
|
stderr=subprocess.DEVNULL)
|
||||||
processes.append(proc)
|
processes.append(proc)
|
||||||
|
except qubes.exc.QubesException as e:
|
||||||
|
vm.log.warning('Failed to run qubes.SuspendPostAll: %s', str(e))
|
||||||
|
|
||||||
# FIXME: some timeout?
|
# FIXME: some timeout?
|
||||||
if processes:
|
if processes:
|
||||||
|
@ -1213,8 +1213,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
raise qubes.exc.QubesVMNotRunningError(self)
|
raise qubes.exc.QubesVMNotRunningError(self)
|
||||||
|
|
||||||
if list(self.devices['pci'].attached()):
|
if list(self.devices['pci'].attached()):
|
||||||
yield from self.run_service_for_stdio('qubes.SuspendPre',
|
if self.features.check_with_template('qrexec', False):
|
||||||
user='root')
|
yield from self.run_service_for_stdio('qubes.SuspendPre',
|
||||||
|
user='root')
|
||||||
self.libvirt_domain.pMSuspendForDuration(
|
self.libvirt_domain.pMSuspendForDuration(
|
||||||
libvirt.VIR_NODE_SUSPEND_TARGET_MEM, 0, 0)
|
libvirt.VIR_NODE_SUSPEND_TARGET_MEM, 0, 0)
|
||||||
else:
|
else:
|
||||||
@ -1244,8 +1245,9 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
|
|||||||
# pylint: disable=not-an-iterable
|
# pylint: disable=not-an-iterable
|
||||||
if self.get_power_state() == "Suspended":
|
if self.get_power_state() == "Suspended":
|
||||||
self.libvirt_domain.pMWakeup()
|
self.libvirt_domain.pMWakeup()
|
||||||
yield from self.run_service_for_stdio('qubes.SuspendPost',
|
if self.features.check_with_template('qrexec', False):
|
||||||
user='root')
|
yield from self.run_service_for_stdio('qubes.SuspendPost',
|
||||||
|
user='root')
|
||||||
else:
|
else:
|
||||||
yield from self.unpause()
|
yield from self.unpause()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user