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:
Marek Marczykowski-Górecki 2013-09-01 01:26:43 +02:00
parent a0cb8dbf7e
commit 5da7a520c4
3 changed files with 42 additions and 11 deletions

View File

@ -1227,6 +1227,43 @@ class QubesVm(object):
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):
"""command should be in form 'cmdline'
When passio_popen=True, popen object with stdout connected to pipe.

View File

@ -68,13 +68,7 @@ def main():
exit (1)
pci = args[1]
if not os.path.exists('/sys/bus/pci/devices/0000:%s' % 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"
vm.pci_add(pci)
qvm_collection.save()
qvm_collection.unlock_db()
@ -84,10 +78,7 @@ def main():
exit (1)
pci = args[1]
if vm.pcidevs.count(pci) > 0:
vm.pcidevs.remove(pci)
if vm.is_running():
print >>sys.stderr, "NOTICE: Changes will be seen by VM after VM restart"
vm.pci_remove(pci)
qvm_collection.save()
qvm_collection.unlock_db()

View File

@ -173,6 +173,9 @@ def set_pcidevs(vms, vm, args):
print >> sys.stderr, "Missing pcidevs argument!"
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]))
def set_netvm(vms, vm, args):