Merge branch 'pvusb2' of github.com:grwl/qubes-core into pvusb2
This commit is contained in:
commit
3f555e75a8
@ -407,6 +407,7 @@ def block_detach_all(vm, vm_xid = None):
|
|||||||
####### USB devices ######
|
####### USB devices ######
|
||||||
|
|
||||||
usb_ver_re = re.compile(r"^(1|2)$")
|
usb_ver_re = re.compile(r"^(1|2)$")
|
||||||
|
usb_device_re = re.compile(r"^[0-9]+-[0-9]+(_[0-9]+)?$")
|
||||||
|
|
||||||
def usb_setup(backend_vm_xid, vm_xid, devid, usb_ver):
|
def usb_setup(backend_vm_xid, vm_xid, devid, usb_ver):
|
||||||
"""
|
"""
|
||||||
@ -455,6 +456,14 @@ def usb_setup(backend_vm_xid, vm_xid, devid, usb_ver):
|
|||||||
|
|
||||||
xs.transaction_end(trans)
|
xs.transaction_end(trans)
|
||||||
|
|
||||||
|
def usb_decode_device_from_xs(xs_encoded_device):
|
||||||
|
""" recover actual device name (xenstore doesn't allow dot in key names, so it was translated to underscore) """
|
||||||
|
return xs_encoded_device.replace('_', '.')
|
||||||
|
|
||||||
|
def usb_encode_device_for_xs(device):
|
||||||
|
""" encode actual device name (xenstore doesn't allow dot in key names, so translated it into underscore) """
|
||||||
|
return device.replace('.', '_')
|
||||||
|
|
||||||
def usb_list():
|
def usb_list():
|
||||||
"""
|
"""
|
||||||
Returns a dictionary of USB devices (for PVUSB backends running in all VM).
|
Returns a dictionary of USB devices (for PVUSB backends running in all VM).
|
||||||
@ -465,7 +474,6 @@ def usb_list():
|
|||||||
name = <name of backend domain>:<frontend device number>-<frontend port number>
|
name = <name of backend domain>:<frontend device number>-<frontend port number>
|
||||||
desc = description
|
desc = description
|
||||||
"""
|
"""
|
||||||
device_re = re.compile(r"^[0-9]+-[0-9]+(_[0-9]+)?$")
|
|
||||||
# FIXME: any better idea of desc_re?
|
# FIXME: any better idea of desc_re?
|
||||||
desc_re = re.compile(r"^.{1,255}$")
|
desc_re = re.compile(r"^.{1,255}$")
|
||||||
|
|
||||||
@ -479,20 +487,20 @@ def usb_list():
|
|||||||
vm_devices = xs.ls(xs_trans, '/local/domain/%s/qubes-usb-devices' % xid)
|
vm_devices = xs.ls(xs_trans, '/local/domain/%s/qubes-usb-devices' % xid)
|
||||||
if vm_devices is None:
|
if vm_devices is None:
|
||||||
continue
|
continue
|
||||||
for device in vm_devices:
|
# when listing devices in xenstore we get encoded names
|
||||||
|
for xs_encoded_device in vm_devices:
|
||||||
# Sanitize device id
|
# Sanitize device id
|
||||||
if not device_re.match(device):
|
if not usb_device_re.match(xs_encoded_device):
|
||||||
print >> sys.stderr, "Invalid device id in VM '%s'" % vm_name
|
print >> sys.stderr, "Invalid device id in VM '%s'" % vm_name
|
||||||
continue
|
continue
|
||||||
device_desc = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/desc' % (xid, device))
|
device = usb_decode_device_from_xs(xs_encoded_device)
|
||||||
|
device_desc = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/desc' % (xid, xs_encoded_device))
|
||||||
if not desc_re.match(device_desc):
|
if not desc_re.match(device_desc):
|
||||||
print >> sys.stderr, "Invalid %s device desc in VM '%s'" % (device, vm_name)
|
print >> sys.stderr, "Invalid %s device desc in VM '%s'" % (device, vm_name)
|
||||||
continue
|
continue
|
||||||
# xenstore doesn't allow dot in key names - was translated to underscore
|
|
||||||
device = device.replace('_', '.')
|
|
||||||
visible_name = "%s:%s" % (vm_name, device)
|
visible_name = "%s:%s" % (vm_name, device)
|
||||||
# grab version
|
# grab version
|
||||||
usb_ver = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/usb-ver' % (xid, device))
|
usb_ver = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/usb-ver' % (xid, xs_encoded_device))
|
||||||
if usb_ver is None or not usb_ver_re.match(usb_ver):
|
if usb_ver is None or not usb_ver_re.match(usb_ver):
|
||||||
print >> sys.stderr, "Invalid %s device USB version in VM '%s'" % (device, vm_name)
|
print >> sys.stderr, "Invalid %s device USB version in VM '%s'" % (device, vm_name)
|
||||||
continue
|
continue
|
||||||
@ -536,11 +544,16 @@ def usb_check_attached(xs_trans, backend_vm, device):
|
|||||||
if ports is None:
|
if ports is None:
|
||||||
continue
|
continue
|
||||||
for port in ports:
|
for port in ports:
|
||||||
|
# FIXME: refactor, see similar loop in usb_find_unused_frontend(), use usb_list() instead?
|
||||||
if not port.isdigit():
|
if not port.isdigit():
|
||||||
print >> sys.stderr, "Invalid port in VM %s frontend %s" % (vm, frontend)
|
print >> sys.stderr, "Invalid port in VM %s frontend %s" % (vm, frontend)
|
||||||
continue
|
continue
|
||||||
dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port/%s' % (backend_vm, vm, frontend_dev, port))
|
xs_encoded_dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port/%s' % (backend_vm, vm, frontend_dev, port))
|
||||||
if dev == device:
|
# Sanitize device id
|
||||||
|
if not usb_device_re.match(xs_encoded_dev):
|
||||||
|
print >> sys.stderr, "Invalid device id in VM %d" % (backend_vm)
|
||||||
|
continue
|
||||||
|
if usb_decode_device_from_xs(xs_encoded_dev) == device:
|
||||||
frontend = "%s-%s" % (frontend_dev, port)
|
frontend = "%s-%s" % (frontend_dev, port)
|
||||||
vm_name = xl_ctx.domid_to_name(int(vm))
|
vm_name = xl_ctx.domid_to_name(int(vm))
|
||||||
if vm_name is None:
|
if vm_name is None:
|
||||||
@ -565,7 +578,10 @@ def usb_find_unused_frontend(xs_trans, backend_vm_xid, vm_xid, usb_ver):
|
|||||||
Returns frontend specification in <device>-<port> format.
|
Returns frontend specification in <device>-<port> format.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# This variable holds an index of last frontend scanned by the loop below.
|
||||||
|
# If nothing found, this value will be used to derive the index of a new frontend.
|
||||||
last_frontend_dev = -1
|
last_frontend_dev = -1
|
||||||
|
|
||||||
frontend_devs = xs.ls(xs_trans, "/local/domain/%d/device/vusb" % vm_xid)
|
frontend_devs = xs.ls(xs_trans, "/local/domain/%d/device/vusb" % vm_xid)
|
||||||
if frontend_devs is not None:
|
if frontend_devs is not None:
|
||||||
for frontend_dev in frontend_devs:
|
for frontend_dev in frontend_devs:
|
||||||
@ -578,20 +594,24 @@ def usb_find_unused_frontend(xs_trans, backend_vm_xid, vm_xid, usb_ver):
|
|||||||
if xs.read(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/usb-ver' % (backend_vm_xid, vm_xid, frontend_dev)) != usb_ver:
|
if xs.read(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/usb-ver' % (backend_vm_xid, vm_xid, frontend_dev)) != usb_ver:
|
||||||
last_frontend_dev = frontend_dev
|
last_frontend_dev = frontend_dev
|
||||||
continue
|
continue
|
||||||
if xs.read(xs_trans, "%s/backend-id" % fe_path) == str(backend_vm_xid):
|
# here: found an existing frontend already connected to right backend using an appropriate USB version
|
||||||
last_frontend_dev = frontend_dev
|
|
||||||
continue
|
|
||||||
ports = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/port' % (backend_vm_xid, vm_xid, frontend_dev))
|
ports = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/port' % (backend_vm_xid, vm_xid, frontend_dev))
|
||||||
if ports is None:
|
if ports is None:
|
||||||
|
print >> sys.stderr, "No ports in VM %d frontend_dev %d?" % (vm_xid, frontend_dev)
|
||||||
last_frontend_dev = frontend_dev
|
last_frontend_dev = frontend_dev
|
||||||
continue
|
continue
|
||||||
for port in ports:
|
for port in ports:
|
||||||
|
# FIXME: refactor, see similar loop in usb_check_attached(), use usb_list() instead?
|
||||||
if not port.isdigit():
|
if not port.isdigit():
|
||||||
print >> sys.stderr, "Invalid port in VM %d frontend_dev %d" % (vm_xid, frontend_dev)
|
print >> sys.stderr, "Invalid port in VM %d frontend_dev %d" % (vm_xid, frontend_dev)
|
||||||
continue
|
continue
|
||||||
port = int(port)
|
port = int(port)
|
||||||
dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/port/%d' % (backend_vm_xid, vm_xid, frontend_dev, port))
|
xs_encoded_dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/port/%d' % (backend_vm_xid, vm_xid, frontend_dev, port))
|
||||||
if dev == "":
|
# Sanitize device id
|
||||||
|
if not usb_device_re.match(xs_encoded_dev):
|
||||||
|
print >> sys.stderr, "Invalid device id in VM %d" % (backend_vm_xid)
|
||||||
|
continue
|
||||||
|
if xs_encoded_dev == "":
|
||||||
return '%d-%d' % (frontend_dev, port)
|
return '%d-%d' % (frontend_dev, port)
|
||||||
last_frontend_dev = frontend_dev
|
last_frontend_dev = frontend_dev
|
||||||
|
|
||||||
@ -605,7 +625,8 @@ def usb_attach(vm, backend_vm, device, frontend=None, auto_detach=False, wait=Tr
|
|||||||
|
|
||||||
xs_trans = xs.transaction_start()
|
xs_trans = xs.transaction_start()
|
||||||
|
|
||||||
usb_ver = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/usb-ver' % (backend_vm.xid, device))
|
xs_encoded_device = usb_encode_device_for_xs(device)
|
||||||
|
usb_ver = xs.read(xs_trans, '/local/domain/%s/qubes-usb-devices/%s/usb-ver' % (backend_vm.xid, xs_encoded_device))
|
||||||
if usb_ver is None or not usb_ver_re.match(usb_ver):
|
if usb_ver is None or not usb_ver_re.match(usb_ver):
|
||||||
xs.transaction_end(xs_trans)
|
xs.transaction_end(xs_trans)
|
||||||
raise QubesException("Invalid %s device USB version in VM '%s'" % (device, backend_vm.name))
|
raise QubesException("Invalid %s device USB version in VM '%s'" % (device, backend_vm.name))
|
||||||
|
Loading…
Reference in New Issue
Block a user