core: move pci_add/pci_remove to QubesVM, add support for live add/remove (#708)
This additionally requires qubes.DetachPciDevice service in VM.
This commit is contained in:
		
							parent
							
								
									a0cb8dbf7e
								
							
						
					
					
						commit
						5da7a520c4
					
				| @ -1227,6 +1227,43 @@ class QubesVm(object): | |||||||
| 
 | 
 | ||||||
|         return conf |         return conf | ||||||
| 
 | 
 | ||||||
|  |     def pci_add(self, pci): | ||||||
|  |         if not os.path.exists('/sys/bus/pci/devices/0000:%s' % pci): | ||||||
|  |             raise QubesException("Invalid PCI device: %s" % pci) | ||||||
|  |         if self.pcidevs.count(pci): | ||||||
|  |             # already added | ||||||
|  |             return | ||||||
|  |         self.pcidevs.append(pci) | ||||||
|  |         if self.is_running(): | ||||||
|  |             try: | ||||||
|  |                 subprocess.check_call(['sudo', system_path["qubes_pciback_cmd"], pci]) | ||||||
|  |                 subprocess.check_call(['sudo', 'xl', 'pci-attach', str(self.xid), pci]) | ||||||
|  |             except Exception as e: | ||||||
|  |                 print >>sys.stderr, "Failed to attach PCI device on the fly " \ | ||||||
|  |                     "(%s), changes will be seen after VM restart" % str(e) | ||||||
|  | 
 | ||||||
|  |     def pci_remove(self, pci): | ||||||
|  |         if not self.pcidevs.count(pci): | ||||||
|  |             # not attached | ||||||
|  |             return | ||||||
|  |         self.pcidevs.remove(pci) | ||||||
|  |         if self.is_running(): | ||||||
|  |             p = subprocess.Popen(['xl', 'pci-list', str(self.xid)], | ||||||
|  |                     stdout=subprocess.PIPE) | ||||||
|  |             result = p.communicate() | ||||||
|  |             m = re.search(r"^(\d+.\d+)\s+0000:%s$" % pci, result[0], flags=re.MULTILINE) | ||||||
|  |             if not m: | ||||||
|  |                 print >>sys.stderr, "Device %s already detached" % pci | ||||||
|  |                 return | ||||||
|  |             vmdev = m.group(1) | ||||||
|  |             try: | ||||||
|  |                 self.run("QUBESRPC qubes.DetachPciDevice dom0", user="root", | ||||||
|  |                         localcmd="echo 00:%s" % vmdev, wait=True) | ||||||
|  |                 subprocess.check_call(['sudo', 'xl', 'pci-detach', str(self.xid), pci]) | ||||||
|  |             except Exception as e: | ||||||
|  |                 print >>sys.stderr, "Failed to detach PCI device on the fly " \ | ||||||
|  |                     "(%s), changes will be seen after VM restart" % str(e) | ||||||
|  | 
 | ||||||
|     def run(self, command, user = None, verbose = True, autostart = False, notify_function = None, passio = False, passio_popen = False, passio_stderr=False, ignore_stderr=False, localcmd = None, wait = False, gui = True): |     def run(self, command, user = None, verbose = True, autostart = False, notify_function = None, passio = False, passio_popen = False, passio_stderr=False, ignore_stderr=False, localcmd = None, wait = False, gui = True): | ||||||
|         """command should be in form 'cmdline' |         """command should be in form 'cmdline' | ||||||
|             When passio_popen=True, popen object with stdout connected to pipe. |             When passio_popen=True, popen object with stdout connected to pipe. | ||||||
|  | |||||||
| @ -68,13 +68,7 @@ def main(): | |||||||
|             exit (1) |             exit (1) | ||||||
| 
 | 
 | ||||||
|         pci = args[1] |         pci = args[1] | ||||||
|         if not os.path.exists('/sys/bus/pci/devices/0000:%s' % pci): |         vm.pci_add(pci) | ||||||
|             print >> sys.stderr, "Invalid PCI device: %s" % pci |  | ||||||
|             exit(1) |  | ||||||
|         if vm.pcidevs.count(pci) == 0: |  | ||||||
|             vm.pcidevs.append(pci) |  | ||||||
|             if vm.is_running(): |  | ||||||
|                 print >>sys.stderr, "NOTICE: Changes will be seen by VM after VM restart" |  | ||||||
|         qvm_collection.save() |         qvm_collection.save() | ||||||
|         qvm_collection.unlock_db() |         qvm_collection.unlock_db() | ||||||
| 
 | 
 | ||||||
| @ -84,10 +78,7 @@ def main(): | |||||||
|             exit (1) |             exit (1) | ||||||
| 
 | 
 | ||||||
|         pci = args[1] |         pci = args[1] | ||||||
|         if vm.pcidevs.count(pci) > 0: |         vm.pci_remove(pci) | ||||||
|             vm.pcidevs.remove(pci) |  | ||||||
|             if vm.is_running(): |  | ||||||
|                 print >>sys.stderr, "NOTICE: Changes will be seen by VM after VM restart" |  | ||||||
|         qvm_collection.save() |         qvm_collection.save() | ||||||
|         qvm_collection.unlock_db() |         qvm_collection.unlock_db() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -173,6 +173,9 @@ def set_pcidevs(vms, vm, args): | |||||||
|         print >> sys.stderr, "Missing pcidevs argument!" |         print >> sys.stderr, "Missing pcidevs argument!" | ||||||
|         exit (1) |         exit (1) | ||||||
| 
 | 
 | ||||||
|  |     if vm.is_running(): | ||||||
|  |         print >>sys.stderr, "Cannot modify PCI devices of running VM, " \ | ||||||
|  |             "use qvm-pci instead" | ||||||
|     vm.pcidevs = list(eval(args[0])) |     vm.pcidevs = list(eval(args[0])) | ||||||
| 
 | 
 | ||||||
| def set_netvm(vms, vm, args): | def set_netvm(vms, vm, args): | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki