dispvm: use try/finally to make sure that qubes.xml is unlocked
Even in case of some exception (in which case theoretically it should be unlocked at qfile-daemon-dvm exit, but the script may wait for something). QubesOS/qubes-issues#1636
This commit is contained in:
		
							parent
							
								
									ae848d5369
								
							
						
					
					
						commit
						5546d679c0
					
				| @ -51,68 +51,67 @@ class QfileDaemonDvm: | ||||
| 
 | ||||
|         qvm_collection = QubesVmCollection() | ||||
|         qvm_collection.lock_db_for_writing() | ||||
| 
 | ||||
|         tar_process = subprocess.Popen( | ||||
|             ['bsdtar', '-C', current_savefile_vmdir, | ||||
|              '-xSUf', os.path.join(current_savefile_vmdir, 'saved-cows.tar')]) | ||||
| 
 | ||||
|         qvm_collection.load() | ||||
|         print >>sys.stderr, "time=%s, collection loaded" % (str(time.time())) | ||||
| 
 | ||||
|         vm = qvm_collection.get_vm_by_name(self.name) | ||||
|         if vm is None: | ||||
|             sys.stderr.write('Domain ' + self.name + ' does not exist ?') | ||||
|             qvm_collection.unlock_db() | ||||
|             return None | ||||
|         label = vm.label | ||||
|         if len(sys.argv) > 4 and len(sys.argv[4]) > 0: | ||||
|             assert sys.argv[4] in QubesDispVmLabels.keys(), "Invalid label" | ||||
|             label = QubesDispVmLabels[sys.argv[4]] | ||||
|         disp_templ = self.get_disp_templ() | ||||
|         vm_disptempl = qvm_collection.get_vm_by_name(disp_templ) | ||||
|         if vm_disptempl is None: | ||||
|             sys.stderr.write('Domain ' + disp_templ + ' does not exist ?') | ||||
|             qvm_collection.unlock_db() | ||||
|             return None | ||||
|         dispvm = qvm_collection.add_new_vm('QubesDisposableVm', | ||||
|                                            disp_template=vm_disptempl, | ||||
|                                            label=label) | ||||
|         print >>sys.stderr, "time=%s, VM created" % (str(time.time())) | ||||
|         # By default inherit firewall rules from calling VM | ||||
|         disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % dispvm.name | ||||
|         dispvm.firewall_conf = disp_firewall_conf | ||||
|         if os.path.exists(vm.firewall_conf): | ||||
|             shutil.copy(vm.firewall_conf, disp_firewall_conf) | ||||
|         elif vm.qid == 0 and os.path.exists(vm_disptempl.firewall_conf): | ||||
|             # for DispVM called from dom0, copy use rules from DispVM template | ||||
|             shutil.copy(vm_disptempl.firewall_conf, disp_firewall_conf) | ||||
|         if len(sys.argv) > 5 and len(sys.argv[5]) > 0: | ||||
|             assert os.path.exists(sys.argv[5]), "Invalid firewall.conf location" | ||||
|             dispvm.firewall_conf = sys.argv[5] | ||||
|         if vm.qid != 0: | ||||
|             dispvm.uses_default_netvm = False | ||||
|             # netvm can be changed before restore, | ||||
|             # but cannot be enabled/disabled | ||||
|             if (dispvm.netvm is None) == (vm.dispvm_netvm is None): | ||||
|                 dispvm.netvm = vm.dispvm_netvm | ||||
|         # Wait for tar to finish | ||||
|         if tar_process.wait() != 0: | ||||
|             sys.stderr.write('Failed to unpack saved-cows.tar') | ||||
|             qvm_collection.unlock_db() | ||||
|             return None | ||||
|         print >>sys.stderr, "time=%s, VM starting" % (str(time.time())) | ||||
|         try: | ||||
|             dispvm.start() | ||||
|         except (MemoryError, QubesException) as e: | ||||
|             tray_notify_error(str(e)) | ||||
|             raise | ||||
|         if vm.qid != 0: | ||||
|             # if need to enable/disable netvm, do it while DispVM is alive | ||||
|             if (dispvm.netvm is None) != (vm.dispvm_netvm is None): | ||||
|                 dispvm.netvm = vm.dispvm_netvm | ||||
|         print >>sys.stderr, "time=%s, VM started" % (str(time.time())) | ||||
|         qvm_collection.save() | ||||
|         qvm_collection.unlock_db() | ||||
| 
 | ||||
|             tar_process = subprocess.Popen( | ||||
|                 ['bsdtar', '-C', current_savefile_vmdir, | ||||
|                  '-xSUf', os.path.join(current_savefile_vmdir, 'saved-cows.tar')]) | ||||
| 
 | ||||
|             qvm_collection.load() | ||||
|             print >>sys.stderr, "time=%s, collection loaded" % (str(time.time())) | ||||
| 
 | ||||
|             vm = qvm_collection.get_vm_by_name(self.name) | ||||
|             if vm is None: | ||||
|                 sys.stderr.write('Domain ' + self.name + ' does not exist ?') | ||||
|                 return None | ||||
|             label = vm.label | ||||
|             if len(sys.argv) > 4 and len(sys.argv[4]) > 0: | ||||
|                 assert sys.argv[4] in QubesDispVmLabels.keys(), "Invalid label" | ||||
|                 label = QubesDispVmLabels[sys.argv[4]] | ||||
|             disp_templ = self.get_disp_templ() | ||||
|             vm_disptempl = qvm_collection.get_vm_by_name(disp_templ) | ||||
|             if vm_disptempl is None: | ||||
|                 sys.stderr.write('Domain ' + disp_templ + ' does not exist ?') | ||||
|                 return None | ||||
|             dispvm = qvm_collection.add_new_vm('QubesDisposableVm', | ||||
|                                                disp_template=vm_disptempl, | ||||
|                                                label=label) | ||||
|             print >>sys.stderr, "time=%s, VM created" % (str(time.time())) | ||||
|             # By default inherit firewall rules from calling VM | ||||
|             disp_firewall_conf = '/var/run/qubes/%s-firewall.xml' % dispvm.name | ||||
|             dispvm.firewall_conf = disp_firewall_conf | ||||
|             if os.path.exists(vm.firewall_conf): | ||||
|                 shutil.copy(vm.firewall_conf, disp_firewall_conf) | ||||
|             elif vm.qid == 0 and os.path.exists(vm_disptempl.firewall_conf): | ||||
|                 # for DispVM called from dom0, copy use rules from DispVM template | ||||
|                 shutil.copy(vm_disptempl.firewall_conf, disp_firewall_conf) | ||||
|             if len(sys.argv) > 5 and len(sys.argv[5]) > 0: | ||||
|                 assert os.path.exists(sys.argv[5]), "Invalid firewall.conf location" | ||||
|                 dispvm.firewall_conf = sys.argv[5] | ||||
|             if vm.qid != 0: | ||||
|                 dispvm.uses_default_netvm = False | ||||
|                 # netvm can be changed before restore, | ||||
|                 # but cannot be enabled/disabled | ||||
|                 if (dispvm.netvm is None) == (vm.dispvm_netvm is None): | ||||
|                     dispvm.netvm = vm.dispvm_netvm | ||||
|             # Wait for tar to finish | ||||
|             if tar_process.wait() != 0: | ||||
|                 sys.stderr.write('Failed to unpack saved-cows.tar') | ||||
|                 return None | ||||
|             print >>sys.stderr, "time=%s, VM starting" % (str(time.time())) | ||||
|             try: | ||||
|                 dispvm.start() | ||||
|             except (MemoryError, QubesException) as e: | ||||
|                 tray_notify_error(str(e)) | ||||
|                 raise | ||||
|             if vm.qid != 0: | ||||
|                 # if need to enable/disable netvm, do it while DispVM is alive | ||||
|                 if (dispvm.netvm is None) != (vm.dispvm_netvm is None): | ||||
|                     dispvm.netvm = vm.dispvm_netvm | ||||
|             print >>sys.stderr, "time=%s, VM started" % (str(time.time())) | ||||
|             qvm_collection.save() | ||||
|         finally: | ||||
|             qvm_collection.unlock_db() | ||||
|         # Reload firewall rules | ||||
|         print >>sys.stderr, "time=%s, reloading firewall" % (str(time.time())) | ||||
|         for vm in qvm_collection.values(): | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki