dom0/qvm-usb: implemented usb_check_attached method, now "qvm-usb -l" indicate attachments
This commit is contained in:
parent
988d37fcb2
commit
b962debfad
@ -293,12 +293,18 @@ def block_check_attached(backend_vm, device, backend_xid = None):
|
||||
return None
|
||||
|
||||
def block_attach(vm, backend_vm, device, frontend=None, mode="w", auto_detach=False, wait=True):
|
||||
device_attach_check(vm, backend_vm, device, frontend)
|
||||
do_block_attach(vm, backend_vm, device, frontend, mode, auto_detach, wait)
|
||||
|
||||
def device_attach_check(vm, backend_vm, device, frontend):
|
||||
""" Checks all the parameters, dies on errors """
|
||||
if not vm.is_running():
|
||||
raise QubesException("VM %s not running" % vm.name)
|
||||
|
||||
if not backend_vm.is_running():
|
||||
raise QubesException("VM %s not running" % backend_vm.name)
|
||||
|
||||
def do_block_attach(vm, backend_vm, device, frontend, mode, auto_detach, wait):
|
||||
if frontend is None:
|
||||
frontend = block_find_unused_frontend(vm)
|
||||
if frontend is None:
|
||||
@ -432,11 +438,74 @@ def usb_list():
|
||||
xs.transaction_end(xs_trans)
|
||||
return devices_list
|
||||
|
||||
def usb_check_attached(backend_vm, device, backend_xid = None):
|
||||
def usb_check_attached(backend_vm, device):
|
||||
# example: /local/domain/0/backend/vusb/4/0/port/1 = "7-5"
|
||||
##print "*** usb_check_attached(%s, %s) called" % (str(backend_vm), str(device))
|
||||
# FIXME use XS transaction
|
||||
xs_trans = ''
|
||||
vms = xs.ls(xs_trans, '/local/domain/%d/backend/vusb' % backend_vm)
|
||||
##print "*** usb_check_attached: vms=%s" % str(vms)
|
||||
if vms is None:
|
||||
return None
|
||||
for vm in vms:
|
||||
# FIXME validate vm?
|
||||
frontend_devs = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%s' % (backend_vm, vm))
|
||||
##print "*** usb_check_attached: frontend_devs=%s" % str(frontend_devs)
|
||||
if frontend_devs is None:
|
||||
continue
|
||||
for frontend_dev in frontend_devs:
|
||||
# FIXME validate frontend_dev?
|
||||
##print '>>>/local/domain/%d/backend/vusb/%s/%s/port' % (backend_vm, vm, frontend_dev)
|
||||
ports = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port' % (backend_vm, vm, frontend_dev))
|
||||
##print "*** usb_check_attached: ports=%s" % str(ports)
|
||||
if ports is None:
|
||||
continue
|
||||
for port in ports:
|
||||
# FIXME validate ports?
|
||||
dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port/%s' % (backend_vm, vm, frontend_dev, port))
|
||||
##print "*** usb_check_attached: port=%s, device=%s" % (port, str(dev))
|
||||
if dev == device:
|
||||
frontend = "%s-%s" % (frontend_dev, port)
|
||||
return {"xid":int(vm), "frontend": frontend, "devid": device, "vm": "FIXME"}
|
||||
return None
|
||||
|
||||
def usb_check_frontend_busy(vm, front_dev, port):
|
||||
devport = frontend.split("-")
|
||||
if len(devport) != 2:
|
||||
raise QubesException("Malformed frontend syntax, must be in device-port format")
|
||||
# FIXME
|
||||
# return xs.read('', '/local/domain/%d/device/vusb/%d/state' % (vm.xid, frontend)) == '4'
|
||||
return False
|
||||
|
||||
def usb_find_unused_frontend(vm):
|
||||
front_dev = 0
|
||||
port = 1
|
||||
# FIXME raise QubesException("No unused frontend found")
|
||||
return '%d-%d' % (front_dev, port)
|
||||
|
||||
def usb_attach(vm, backend_vm, device, frontend=None, auto_detach=False, wait=True):
|
||||
raise NotImplementedError()
|
||||
device_attach_check(vm, backend_vm, device, frontend)
|
||||
do_usb_attach(vm, backend_vm, device, frontend, auto_detach, wait)
|
||||
|
||||
def do_usb_attach(vm, backend_vm, device, frontend, auto_detach, wait):
|
||||
if frontend is None:
|
||||
frontend = usb_find_unused_frontend(vm)
|
||||
else:
|
||||
# Check if any device attached at this frontend
|
||||
if usb_check_frontend_busy(vm, frontend):
|
||||
raise QubesException("Frontend %s busy in VM %s, detach it first" % (frontend, vm.name))
|
||||
|
||||
# Check if this device is attached to some domain
|
||||
attached_vm = usb_check_attached(backend_vm.xid, device)
|
||||
if attached_vm:
|
||||
if auto_detach:
|
||||
usb_detach(None, attached_vm['devid'], vm_xid=attached_vm['xid'])
|
||||
else:
|
||||
raise QubesException("Device %s from %s already connected to VM %s as %s" % (device, backend_vm.name, attached_vm['vm'], attached_vm['frontend']))
|
||||
|
||||
# FIXME sudo
|
||||
xl_cmd = [ 'sudo', '/usr/lib/qubes/xl-qvm-usb-attach.py', str(vm.xid), device, frontend, str(backend_vm.xid) ]
|
||||
subprocess.check_call(xl_cmd)
|
||||
|
||||
def usb_detach(vm, frontend, vm_xid = None):
|
||||
raise NotImplementedError()
|
||||
|
@ -107,7 +107,7 @@ def main():
|
||||
if not args[0] in dev_list.keys():
|
||||
parser.error ("Invalid VM or device name: %s" % args[0])
|
||||
dev = dev_list[args[0]]
|
||||
attached_to = usb_check_attached(None, dev['device'], backend_xid = dev['xid'])
|
||||
attached_to = usb_check_attached(backend_xid, dev['device'])
|
||||
if attached_to is None:
|
||||
print >> sys.stderr, "WARNING: Device not connected to any VM"
|
||||
exit(0)
|
||||
@ -117,7 +117,7 @@ def main():
|
||||
parser.error ("Too many parameters")
|
||||
# do_list
|
||||
for dev in usb_list().values():
|
||||
attached_to = usb_check_attached(None, dev['device'], backend_xid = dev['xid'])
|
||||
attached_to = usb_check_attached(dev['xid'], dev['device'])
|
||||
attached_to_str = ""
|
||||
if attached_to:
|
||||
attached_to_str = " (attached to '%s' as '%s')" % (attached_to['vm'], attached_to['frontend'])
|
||||
|
@ -5,7 +5,7 @@ d=/home/abb/qubes-core
|
||||
# Install
|
||||
cp $d/misc/qubes_usb.rules /etc/udev/rules.d/99-qubes_usb.rules
|
||||
|
||||
for f in usb_add_change usb_remove ; do
|
||||
for f in usb_add_change usb_remove xl-qvm-usb-attach.py ; do
|
||||
cp $d/misc/$f /usr/lib/qubes/$f
|
||||
done
|
||||
|
||||
@ -17,6 +17,6 @@ udevadm control --reload-rules
|
||||
# Rerun
|
||||
xenstore-rm qubes-usb-devices
|
||||
udevadm trigger --action=change
|
||||
sleep 1
|
||||
xenstore-ls -f qubes-usb-devices
|
||||
#sleep 1
|
||||
#xenstore-ls -f qubes-usb-devices
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user