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
|
||||
|
||||
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.
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user