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