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
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki