qvm-usb: always pass VM as object reference not a name
Make the API consistent. QubesOS/qubes-issues#531
This commit is contained in:
parent
d67636308f
commit
52fb410deb
@ -476,7 +476,7 @@ def usb_encode_device_for_qdb(device):
|
||||
""" encode actual device name (xenstore doesn't allow dot in key names, so translated it into underscore) """
|
||||
return device.replace('.', '_')
|
||||
|
||||
def usb_list_vm(vm):
|
||||
def usb_list_vm(qvmc, vm):
|
||||
if not vm.is_running():
|
||||
return {}
|
||||
|
||||
@ -512,7 +512,12 @@ def usb_list_vm(vm):
|
||||
"Invalid %s device 'connected-to' in VM '%s'" % (
|
||||
dev_name, vm.name)
|
||||
continue
|
||||
connected_to = untrusted_connected_to
|
||||
connected_to = qvmc.get_vm_by_name(untrusted_connected_to)
|
||||
if connected_to is None:
|
||||
print >>sys.stderr, \
|
||||
"Device {} appears to be connected to {}, " \
|
||||
"but such VM doesn't exist".format(
|
||||
dev_name, untrusted_connected_to)
|
||||
else:
|
||||
connected_to = None
|
||||
|
||||
@ -531,7 +536,7 @@ def usb_list_vm(vm):
|
||||
return devices
|
||||
|
||||
|
||||
def usb_list(qvmc=None, vm=None):
|
||||
def usb_list(qvmc, vm=None):
|
||||
"""
|
||||
Returns a dictionary of USB devices (for PVUSB backends running in all VM).
|
||||
The dictionary is keyed by 'name' (see below), each element is a dictionary itself:
|
||||
@ -546,16 +551,14 @@ def usb_list(qvmc=None, vm=None):
|
||||
else:
|
||||
vm_list = [vm]
|
||||
else:
|
||||
if qvmc is None:
|
||||
raise QubesException("You must pass either qvm or vm argument")
|
||||
vm_list = qvmc.values()
|
||||
|
||||
devices_list = {}
|
||||
for vm in vm_list:
|
||||
devices_list.update(usb_list_vm(vm))
|
||||
devices_list.update(usb_list_vm(qvmc, vm))
|
||||
return devices_list
|
||||
|
||||
def usb_check_attached(device):
|
||||
def usb_check_attached(qvmc, device):
|
||||
"""Reread device attachment status"""
|
||||
vm = device['vm']
|
||||
untrusted_connected_to = vm.qdb.read(
|
||||
@ -565,22 +568,27 @@ def usb_check_attached(device):
|
||||
raise QubesException(
|
||||
"Invalid %s device 'connected-to' in VM '%s'" % (
|
||||
device['device'], vm.name))
|
||||
connected_to = untrusted_connected_to
|
||||
connected_to = qvmc.get_vm_by_name(untrusted_connected_to)
|
||||
if connected_to is None:
|
||||
print >>sys.stderr, \
|
||||
"Device {} appears to be connected to {}, " \
|
||||
"but such VM doesn't exist".format(
|
||||
device['device'], untrusted_connected_to)
|
||||
else:
|
||||
connected_to = None
|
||||
return connected_to
|
||||
|
||||
def usb_attach(vm, device, auto_detach=False, wait=True):
|
||||
def usb_attach(qvmc, vm, device, auto_detach=False, wait=True):
|
||||
if not vm.is_running():
|
||||
raise QubesException("VM {} not running".format(vm.name))
|
||||
|
||||
if not device['vm'].is_running():
|
||||
raise QubesException("VM {} not running".format(device['vm'].name))
|
||||
|
||||
connected_to = usb_check_attached(device)
|
||||
connected_to = usb_check_attached(qvmc, device)
|
||||
if connected_to:
|
||||
if auto_detach:
|
||||
usb_detach(device)
|
||||
usb_detach(qvmc, device)
|
||||
else:
|
||||
raise QubesException("Device {} already connected, to {}".format(
|
||||
device['name'], connected_to
|
||||
@ -629,12 +637,13 @@ def usb_attach(vm, device, auto_detach=False, wait=True):
|
||||
f.seek(0)
|
||||
f.write(''.join(policy))
|
||||
|
||||
def usb_detach(vm, device):
|
||||
connected_to = usb_check_attached(device)
|
||||
def usb_detach(qvmc, vm, device):
|
||||
connected_to = usb_check_attached(qvmc, device)
|
||||
# detect race conditions; there is still race here, but much smaller
|
||||
if vm.name != connected_to:
|
||||
if connected_to is None or connected_to.qid != vm.qid:
|
||||
raise QubesException(
|
||||
"Device {} not connected to VM {}".format(device['name'], vm.name))
|
||||
"Device {} not connected to VM {}".format(
|
||||
device['name'], vm.name))
|
||||
|
||||
p = vm.run_service('qubes.USBDetach', passio_popen=True, user='root')
|
||||
(stdout, stderr) = p.communicate(
|
||||
|
@ -97,7 +97,7 @@ def main():
|
||||
backend_vm = qvm_collection.get_vm_by_name(args[1].split(":")[0])
|
||||
if backend_vm is None:
|
||||
parser.error("No such VM: {}".format(args[1].split(":")[0]))
|
||||
dev_list = usb_list(vm=backend_vm)
|
||||
dev_list = usb_list(qvm_collection, vm=backend_vm)
|
||||
if not args[1] in dev_list.keys():
|
||||
parser.error("Invalid device name: %s" % args[1])
|
||||
dev = dev_list[args[1]]
|
||||
@ -108,7 +108,7 @@ def main():
|
||||
# kwargs['frontend'] = options.frontend
|
||||
kwargs['auto_detach'] = options.auto_detach
|
||||
try:
|
||||
usb_attach(vm, dev, **kwargs)
|
||||
usb_attach(qvm_collection, vm, dev, **kwargs)
|
||||
except QubesException as e:
|
||||
print >> sys.stderr, "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
@ -125,7 +125,7 @@ def main():
|
||||
# kwargs['frontend'] = options.frontend
|
||||
# usb_detach(vm, **kwargs)
|
||||
#else:
|
||||
usb_detach_all(vm)
|
||||
usb_detach_all(qvm_collection, vm)
|
||||
else:
|
||||
# Maybe usbvm:device?
|
||||
|
||||
@ -137,25 +137,24 @@ def main():
|
||||
backend_vm = qvm_collection.get_vm_by_name(args[0].split(":")[0])
|
||||
if backend_vm is None:
|
||||
parser.error("No such VM: {}".format(args[0].split(":")[0]))
|
||||
dev_list = usb_list(vm=backend_vm)
|
||||
dev_list = usb_list(qvm_collection, vm=backend_vm)
|
||||
if not args[0] in dev_list.keys():
|
||||
parser.error("Invalid device name: %s" % args[0])
|
||||
dev = dev_list[args[0]]
|
||||
attached_to = usb_check_attached(dev)
|
||||
attached_to = usb_check_attached(qvm_collection, dev)
|
||||
if attached_to is None:
|
||||
print >> sys.stderr, "WARNING: Device not connected to any VM"
|
||||
exit(0)
|
||||
vm = qvm_collection.get_vm_by_name(attached_to)
|
||||
usb_detach(vm, dev)
|
||||
usb_detach(qvm_collection, attached_to, dev)
|
||||
else:
|
||||
if len(args) > 0:
|
||||
parser.error("Too many parameters")
|
||||
# do_list
|
||||
for dev in usb_list(qvmc=qvm_collection).values():
|
||||
attached_to = usb_check_attached(dev)
|
||||
for dev in usb_list(qvm_collection).values():
|
||||
attached_to = dev['connected-to']
|
||||
attached_to_str = ""
|
||||
if attached_to:
|
||||
attached_to_str = " (attached to %s)" % (attached_to)
|
||||
attached_to_str = " (attached to %s)" % (attached_to.name)
|
||||
print "%s\t%s%s" % (dev['name'], dev['desc'], attached_to_str)
|
||||
exit (0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user