Merge branch 'master' of git://git.qubes-os.org/marmarek/core
This commit is contained in:
commit
3898b69ac1
11
Makefile
11
Makefile
@ -12,15 +12,20 @@ help:
|
|||||||
@echo "make update-repo-installer -- copy dom0 rpms to installer repo"
|
@echo "make update-repo-installer -- copy dom0 rpms to installer repo"
|
||||||
@echo "make clean -- cleanup"
|
@echo "make clean -- cleanup"
|
||||||
|
|
||||||
rpms:
|
rpms: rpms-vm rpms-dom0
|
||||||
|
|
||||||
|
rpms-vm:
|
||||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-vm.spec
|
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-vm.spec
|
||||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-vm-kernel-placeholder.spec
|
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-vm-kernel-placeholder.spec
|
||||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0.spec
|
|
||||||
rpm --addsign \
|
rpm --addsign \
|
||||||
$(RPMS_DIR)/x86_64/qubes-core-dom0-$(VERSION_DOM0)*.rpm \
|
|
||||||
$(RPMS_DIR)/x86_64/qubes-core-vm-*$(VERSION_VM)*.rpm \
|
$(RPMS_DIR)/x86_64/qubes-core-vm-*$(VERSION_VM)*.rpm \
|
||||||
$(RPMS_DIR)/x86_64/qubes-core-vm-kernel-placeholder-*.rpm
|
$(RPMS_DIR)/x86_64/qubes-core-vm-kernel-placeholder-*.rpm
|
||||||
|
|
||||||
|
rpms-dom0:
|
||||||
|
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0.spec
|
||||||
|
rpm --addsign \
|
||||||
|
$(RPMS_DIR)/x86_64/qubes-core-dom0-$(VERSION_DOM0)*.rpm
|
||||||
|
|
||||||
rpms-vaio-fixes:
|
rpms-vaio-fixes:
|
||||||
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0-vaio-fixes.spec
|
rpmbuild --define "_rpmdir $(RPMS_DIR)" -bb rpm_spec/core-dom0-vaio-fixes.spec
|
||||||
rpm --addsign $(RPMS_DIR)/x86_64/qubes-core-dom0-vaio-fixes-$(VERSION_VAIO_FIXES)*.rpm
|
rpm --addsign $(RPMS_DIR)/x86_64/qubes-core-dom0-vaio-fixes-$(VERSION_VAIO_FIXES)*.rpm
|
||||||
|
69
README.pvusb
Normal file
69
README.pvusb
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
Dedicated usbvm (optional)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
In dom0, once:
|
||||||
|
qvm-create -l red usbvm
|
||||||
|
|
||||||
|
# FIXME: use your own PCI device IDs
|
||||||
|
qvm-pci -a usbvm 00:1d.0
|
||||||
|
qvm-pci -a usbvm 00:1d.1
|
||||||
|
qvm-pci -a usbvm 00:1d.2
|
||||||
|
qvm-pci -a usbvm 00:1d.7
|
||||||
|
|
||||||
|
After each dom0 reboot:
|
||||||
|
qvm-start usbvm
|
||||||
|
|
||||||
|
List
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
In dom0:
|
||||||
|
qvm-usb -l
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
dom0:7-4 0718:061a TDKMedia_Trans-It_Drive_070326AE8AF92D95 (attached to qdvp:0-1)
|
||||||
|
dom0:7-5 0b05:1706 ASUS_802.11g_WLAN_Drive (attached to netvm:0-1)
|
||||||
|
dom0:1-1 045e:0084 Microsoft_Basic_Optical_Mouse
|
||||||
|
usbvm:4-6 05e3:0723 Generic_USB_Storage (attached to qdvp:1-1)
|
||||||
|
|
||||||
|
Attach
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
In dom0:
|
||||||
|
qvm-usb -a [--no-auto-detach] <vm-name> <device-vm-name>:<backend-controller>-<backend-port>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
qvm-usb -a netvm usbvm:4-1
|
||||||
|
|
||||||
|
Detach
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
In dom0:
|
||||||
|
qvm-usb -d <vm-name>:<vusb-controller>-<vusb-port>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
qvm-usb -d netvm:0-1
|
||||||
|
|
||||||
|
Known issues
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
List/attach/detach operations seem to work ok, devices are recognized by the target VM etc.
|
||||||
|
But actual usage of the attached devices is unstable at best. In fact the only working device
|
||||||
|
I saw was one USB stick (and this only after it took a minute to time out and reset the bus
|
||||||
|
couple times). Kernel crashes are normal as well. I have not investigated these issues yet,
|
||||||
|
I had similar experience with Marek's scripts.
|
||||||
|
|
||||||
|
* System keyboard / mouse are listed and can be detached away
|
||||||
|
* Virtual USB devices (ones created by PVUSB frontend) may be listed
|
||||||
|
* The installation/configuration is not persistent, not retained between reboots
|
||||||
|
* No debugging / logging / audit trail
|
||||||
|
* When an attached device is physically unplugged, USB port remains mapped but not displayed
|
||||||
|
in the list. If device is plugged back it continues to work. Unlisted device cannot be detached.
|
||||||
|
* We are not attaching actual devices, but USB ports (different behavior from VMWare, might be confusing)
|
||||||
|
* After device is detached from the frontend and returned back to the backend it is not alwayws usable there
|
||||||
|
* Code changing configuration of pvusb fe/be and vusb bind/unbind helper are located
|
||||||
|
misc/xl-qvm-usb-attach.py misc/xl-qvm-usb-detach.py misc/vusb-ctl.py. These helpers are
|
||||||
|
deployed into the backend domain. The initialization code is qubesutils.py in usb_setup(),
|
||||||
|
should probably also be moved into an external helper. Perhaps the functionality of these
|
||||||
|
external helpers should be merged into libxl? The is one catch is invokation of vusb helper
|
||||||
|
in the backend domain -- now it relies on qubes-specific API.
|
||||||
|
|
1
build-deps.list
Normal file
1
build-deps.list
Normal file
@ -0,0 +1 @@
|
|||||||
|
xen-devel-*DIST*
|
22238
dom0/misc/Fedora-13-comps.xml
Normal file
22238
dom0/misc/Fedora-13-comps.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -84,7 +84,7 @@ def handle_dom0updates(updatevm):
|
|||||||
if updates_error_file_handle is not None:
|
if updates_error_file_handle is not None:
|
||||||
updates_error_file_handle.close()
|
updates_error_file_handle.close()
|
||||||
# After updates received - create repo metadata
|
# After updates received - create repo metadata
|
||||||
subprocess.check_call(["/usr/bin/createrepo", "-q", updates_dir])
|
subprocess.check_call(["/usr/bin/createrepo", "-g", "/usr/share/qubes/Fedora-13-comps.xml", "-q", updates_dir])
|
||||||
os.chown(updates_repodata_dir, -1, qubes_gid)
|
os.chown(updates_repodata_dir, -1, qubes_gid)
|
||||||
os.chmod(updates_repodata_dir, 0775)
|
os.chmod(updates_repodata_dir, 0775)
|
||||||
# Clean old cache
|
# Clean old cache
|
||||||
|
@ -75,7 +75,7 @@ default_kernels_subdir = "kernels"
|
|||||||
default_firewall_conf_file = "firewall.xml"
|
default_firewall_conf_file = "firewall.xml"
|
||||||
default_memory = 400
|
default_memory = 400
|
||||||
default_kernelopts = ""
|
default_kernelopts = ""
|
||||||
default_kernelopts_pcidevs = "iommu=soft swiotlb=2048"
|
default_kernelopts_pcidevs = "iommu=soft swiotlb=4096"
|
||||||
|
|
||||||
default_hvm_disk_size = 20*1024*1024*1024
|
default_hvm_disk_size = 20*1024*1024*1024
|
||||||
default_hvm_private_img_size = 2*1024*1024*1024
|
default_hvm_private_img_size = 2*1024*1024*1024
|
||||||
@ -874,6 +874,10 @@ class QubesVm(object):
|
|||||||
"{0}/qubes-block-devices".format(domain_path),
|
"{0}/qubes-block-devices".format(domain_path),
|
||||||
'')
|
'')
|
||||||
|
|
||||||
|
xs.write('',
|
||||||
|
"{0}/qubes-usb-devices".format(domain_path),
|
||||||
|
'')
|
||||||
|
|
||||||
xs.write('', "{0}/qubes-debug-mode".format(domain_path),
|
xs.write('', "{0}/qubes-debug-mode".format(domain_path),
|
||||||
str(int(self.debug)))
|
str(int(self.debug)))
|
||||||
|
|
||||||
@ -884,6 +888,8 @@ class QubesVm(object):
|
|||||||
[{ 'dom': xid }])
|
[{ 'dom': xid }])
|
||||||
xs.set_permissions('', '{0}/qubes-block-devices'.format(domain_path),
|
xs.set_permissions('', '{0}/qubes-block-devices'.format(domain_path),
|
||||||
[{ 'dom': xid }])
|
[{ 'dom': xid }])
|
||||||
|
xs.set_permissions('', '{0}/qubes-usb-devices'.format(domain_path),
|
||||||
|
[{ 'dom': xid }])
|
||||||
|
|
||||||
def get_rootdev(self, source_template=None):
|
def get_rootdev(self, source_template=None):
|
||||||
if self.template:
|
if self.template:
|
||||||
|
@ -293,12 +293,18 @@ def block_check_attached(backend_vm, device, backend_xid = None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def block_attach(vm, backend_vm, device, frontend=None, mode="w", auto_detach=False, wait=True):
|
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():
|
if not vm.is_running():
|
||||||
raise QubesException("VM %s not running" % vm.name)
|
raise QubesException("VM %s not running" % vm.name)
|
||||||
|
|
||||||
if not backend_vm.is_running():
|
if not backend_vm.is_running():
|
||||||
raise QubesException("VM %s not running" % backend_vm.name)
|
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:
|
if frontend is None:
|
||||||
frontend = block_find_unused_frontend(vm)
|
frontend = block_find_unused_frontend(vm)
|
||||||
if frontend is None:
|
if frontend is None:
|
||||||
@ -398,6 +404,268 @@ def block_detach_all(vm, vm_xid = None):
|
|||||||
xl_cmd = [ '/usr/sbin/xl', 'block-detach', str(vm_xid), devid]
|
xl_cmd = [ '/usr/sbin/xl', 'block-detach', str(vm_xid), devid]
|
||||||
subprocess.check_call(xl_cmd)
|
subprocess.check_call(xl_cmd)
|
||||||
|
|
||||||
|
####### USB devices ######
|
||||||
|
|
||||||
|
usb_ver_re = re.compile(r"^(1|2)$")
|
||||||
|
usb_device_re = re.compile(r"^[0-9]+-[0-9]+(_[0-9]+)?$")
|
||||||
|
usb_port_re = re.compile(r"^$|^[0-9]+-[0-9]+(\.[0-9]+)?$")
|
||||||
|
|
||||||
|
def usb_setup(backend_vm_xid, vm_xid, devid, usb_ver):
|
||||||
|
"""
|
||||||
|
Attach frontend to the backend.
|
||||||
|
backend_vm_xid - id of the backend domain
|
||||||
|
vm_xid - id of the frontend domain
|
||||||
|
devid - id of the pvusb controller
|
||||||
|
"""
|
||||||
|
num_ports = 8
|
||||||
|
trans = xs.transaction_start()
|
||||||
|
|
||||||
|
be_path = "/local/domain/%d/backend/vusb/%d/%d" % (backend_vm_xid, vm_xid, devid)
|
||||||
|
fe_path = "/local/domain/%d/device/vusb/%d" % (vm_xid, devid)
|
||||||
|
|
||||||
|
be_perm = [{'dom': backend_vm_xid}, {'dom': vm_xid, 'read': True} ]
|
||||||
|
fe_perm = [{'dom': vm_xid}, {'dom': backend_vm_xid, 'read': True} ]
|
||||||
|
|
||||||
|
# Create directories and set permissions
|
||||||
|
xs.write(trans, be_path, "")
|
||||||
|
xs.set_permissions(trans, be_path, be_perm)
|
||||||
|
|
||||||
|
xs.write(trans, fe_path, "")
|
||||||
|
xs.set_permissions(trans, fe_path, fe_perm)
|
||||||
|
|
||||||
|
# Write backend information into the location that frontend looks for
|
||||||
|
xs.write(trans, "%s/backend-id" % fe_path, str(backend_vm_xid))
|
||||||
|
xs.write(trans, "%s/backend" % fe_path, be_path)
|
||||||
|
|
||||||
|
# Write frontend information into the location that backend looks for
|
||||||
|
xs.write(trans, "%s/frontend-id" % be_path, str(vm_xid))
|
||||||
|
xs.write(trans, "%s/frontend" % be_path, fe_path)
|
||||||
|
|
||||||
|
# Write USB Spec version field.
|
||||||
|
xs.write(trans, "%s/usb-ver" % be_path, usb_ver)
|
||||||
|
|
||||||
|
# Write virtual root hub field.
|
||||||
|
xs.write(trans, "%s/num-ports" % be_path, str(num_ports))
|
||||||
|
for port in range(1, num_ports+1):
|
||||||
|
# Set all port to disconnected state
|
||||||
|
xs.write(trans, "%s/port/%d" % (be_path, port), "")
|
||||||
|
|
||||||
|
# Set state to XenbusStateInitialising
|
||||||
|
xs.write(trans, "%s/state" % fe_path, "1")
|
||||||
|
xs.write(trans, "%s/state" % be_path, "1")
|
||||||
|
xs.write(trans, "%s/online" % be_path, "1")
|
||||||
|
|
||||||
|
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():
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
vm = name of the backend domain
|
||||||
|
xid = xid of the backend domain
|
||||||
|
device = <frontend device number>-<frontend port number>
|
||||||
|
name = <name of backend domain>:<frontend device number>-<frontend port number>
|
||||||
|
desc = description
|
||||||
|
"""
|
||||||
|
# FIXME: any better idea of desc_re?
|
||||||
|
desc_re = re.compile(r"^.{1,255}$")
|
||||||
|
|
||||||
|
devices_list = {}
|
||||||
|
|
||||||
|
xs_trans = xs.transaction_start()
|
||||||
|
vm_list = xs.ls(xs_trans, '/local/domain')
|
||||||
|
|
||||||
|
for xid in vm_list:
|
||||||
|
vm_name = xs.read(xs_trans, '/local/domain/%s/name' % xid)
|
||||||
|
vm_devices = xs.ls(xs_trans, '/local/domain/%s/qubes-usb-devices' % xid)
|
||||||
|
if vm_devices is None:
|
||||||
|
continue
|
||||||
|
# when listing devices in xenstore we get encoded names
|
||||||
|
for xs_encoded_device in vm_devices:
|
||||||
|
# Sanitize device id
|
||||||
|
if not usb_device_re.match(xs_encoded_device):
|
||||||
|
print >> sys.stderr, "Invalid device id in backend VM '%s'" % vm_name
|
||||||
|
continue
|
||||||
|
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):
|
||||||
|
print >> sys.stderr, "Invalid %s device desc in VM '%s'" % (device, vm_name)
|
||||||
|
continue
|
||||||
|
visible_name = "%s:%s" % (vm_name, device)
|
||||||
|
# grab version
|
||||||
|
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):
|
||||||
|
print >> sys.stderr, "Invalid %s device USB version in VM '%s'" % (device, vm_name)
|
||||||
|
continue
|
||||||
|
devices_list[visible_name] = {"name": visible_name, "xid":int(xid),
|
||||||
|
"vm": vm_name, "device":device,
|
||||||
|
"desc":device_desc,
|
||||||
|
"usb_ver":usb_ver}
|
||||||
|
|
||||||
|
xs.transaction_end(xs_trans)
|
||||||
|
return devices_list
|
||||||
|
|
||||||
|
def usb_check_attached(xs_trans, backend_vm, device):
|
||||||
|
"""
|
||||||
|
Checks if the given device in the given backend attached to any frontend.
|
||||||
|
Parameters:
|
||||||
|
backend_vm - xid of the backend domain
|
||||||
|
device - device name in the backend domain
|
||||||
|
Returns None or a dictionary:
|
||||||
|
vm - the name of the frontend domain
|
||||||
|
xid - xid of the frontend domain
|
||||||
|
frontend - frontend device number FIXME
|
||||||
|
devid - frontend port number FIXME
|
||||||
|
"""
|
||||||
|
# sample xs content: /local/domain/0/backend/vusb/4/0/port/1 = "7-5"
|
||||||
|
attached_dev = None
|
||||||
|
vms = xs.ls(xs_trans, '/local/domain/%d/backend/vusb' % backend_vm)
|
||||||
|
if vms is None:
|
||||||
|
return None
|
||||||
|
for vm in vms:
|
||||||
|
if not vm.isdigit():
|
||||||
|
print >> sys.stderr, "Invalid VM id"
|
||||||
|
continue
|
||||||
|
frontend_devs = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%s' % (backend_vm, vm))
|
||||||
|
if frontend_devs is None:
|
||||||
|
continue
|
||||||
|
for frontend_dev in frontend_devs:
|
||||||
|
if not frontend_dev.isdigit():
|
||||||
|
print >> sys.stderr, "Invalid frontend in VM %s" % vm
|
||||||
|
continue
|
||||||
|
ports = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port' % (backend_vm, vm, frontend_dev))
|
||||||
|
if ports is None:
|
||||||
|
continue
|
||||||
|
for port in ports:
|
||||||
|
# FIXME: refactor, see similar loop in usb_find_unused_frontend(), use usb_list() instead?
|
||||||
|
if not port.isdigit():
|
||||||
|
print >> sys.stderr, "Invalid port in VM %s frontend %s" % (vm, frontend)
|
||||||
|
continue
|
||||||
|
dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port/%s' % (backend_vm, vm, frontend_dev, port))
|
||||||
|
if dev == "":
|
||||||
|
continue
|
||||||
|
# Sanitize device id
|
||||||
|
if not usb_port_re.match(dev):
|
||||||
|
print >> sys.stderr, "Invalid device id in backend VM %d @ %s/%s/port/%s" % \
|
||||||
|
(backend_vm, vm, frontend_dev, port)
|
||||||
|
continue
|
||||||
|
if dev == device:
|
||||||
|
frontend = "%s-%s" % (frontend_dev, port)
|
||||||
|
vm_name = xl_ctx.domid_to_name(int(vm))
|
||||||
|
if vm_name is None:
|
||||||
|
# FIXME: should we wipe references to frontends running on nonexistent VMs?
|
||||||
|
continue
|
||||||
|
attached_dev = {"xid":int(vm), "frontend": frontend, "devid": device, "vm": vm_name}
|
||||||
|
break
|
||||||
|
return attached_dev
|
||||||
|
|
||||||
|
#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(xs_trans, backend_vm_xid, vm_xid, usb_ver):
|
||||||
|
"""
|
||||||
|
Find an unused frontend/port to link the given backend with the given frontend.
|
||||||
|
Creates new frontend if needed.
|
||||||
|
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
|
||||||
|
|
||||||
|
frontend_devs = xs.ls(xs_trans, "/local/domain/%d/device/vusb" % vm_xid)
|
||||||
|
if frontend_devs is not None:
|
||||||
|
for frontend_dev in frontend_devs:
|
||||||
|
if not frontend_dev.isdigit():
|
||||||
|
print >> sys.stderr, "Invalid frontend_dev in VM %d" % vm_xid
|
||||||
|
continue
|
||||||
|
frontend_dev = int(frontend_dev)
|
||||||
|
fe_path = "/local/domain/%d/device/vusb/%d" % (vm_xid, frontend_dev)
|
||||||
|
if xs.read(xs_trans, "%s/backend-id" % fe_path) == str(backend_vm_xid):
|
||||||
|
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
|
||||||
|
continue
|
||||||
|
# here: found an existing frontend already connected to right backend using an appropriate USB version
|
||||||
|
ports = xs.ls(xs_trans, '/local/domain/%d/backend/vusb/%d/%d/port' % (backend_vm_xid, vm_xid, frontend_dev))
|
||||||
|
if ports is None:
|
||||||
|
print >> sys.stderr, "No ports in VM %d frontend_dev %d?" % (vm_xid, frontend_dev)
|
||||||
|
last_frontend_dev = frontend_dev
|
||||||
|
continue
|
||||||
|
for port in ports:
|
||||||
|
# FIXME: refactor, see similar loop in usb_check_attached(), use usb_list() instead?
|
||||||
|
if not port.isdigit():
|
||||||
|
print >> sys.stderr, "Invalid port in VM %d frontend_dev %d" % (vm_xid, frontend_dev)
|
||||||
|
continue
|
||||||
|
port = int(port)
|
||||||
|
dev = xs.read(xs_trans, '/local/domain/%d/backend/vusb/%s/%s/port/%s' % (backend_vm, vm, frontend_dev, port))
|
||||||
|
# Sanitize device id
|
||||||
|
if not usb_port_re.match(dev):
|
||||||
|
print >> sys.stderr, "Invalid device id in backend VM %d @ %d/%d/port/%d" % \
|
||||||
|
(backend_vm_xid, vm_xid, frontend_dev, port)
|
||||||
|
continue
|
||||||
|
if dev == "":
|
||||||
|
return '%d-%d' % (frontend_dev, port)
|
||||||
|
last_frontend_dev = frontend_dev
|
||||||
|
|
||||||
|
# create a new frontend_dev and link it to the backend
|
||||||
|
frontend_dev = last_frontend_dev + 1
|
||||||
|
usb_setup(backend_vm_xid, vm_xid, frontend_dev, usb_ver)
|
||||||
|
return '%d-%d' % (frontend_dev, 1)
|
||||||
|
|
||||||
|
def usb_attach(vm, backend_vm, device, frontend=None, auto_detach=False, wait=True):
|
||||||
|
device_attach_check(vm, backend_vm, device, frontend)
|
||||||
|
|
||||||
|
xs_trans = xs.transaction_start()
|
||||||
|
|
||||||
|
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):
|
||||||
|
xs.transaction_end(xs_trans)
|
||||||
|
raise QubesException("Invalid %s device USB version in VM '%s'" % (device, backend_vm.name))
|
||||||
|
|
||||||
|
if frontend is None:
|
||||||
|
frontend = usb_find_unused_frontend(xs_trans, backend_vm.xid, vm.xid, usb_ver)
|
||||||
|
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))
|
||||||
|
xs.transaction_end(xs_trans)
|
||||||
|
raise NotImplementedError("Explicit USB frontend specification is not implemented yet")
|
||||||
|
|
||||||
|
# Check if this device is attached to some domain
|
||||||
|
attached_vm = usb_check_attached(xs_trans, backend_vm.xid, device)
|
||||||
|
xs.transaction_end(xs_trans)
|
||||||
|
|
||||||
|
if attached_vm:
|
||||||
|
if auto_detach:
|
||||||
|
usb_detach(backend_vm, attached_vm)
|
||||||
|
else:
|
||||||
|
raise QubesException("Device %s from %s already connected to VM %s as %s" % (device, backend_vm.name, attached_vm['vm'], attached_vm['frontend']))
|
||||||
|
|
||||||
|
# Run helper script
|
||||||
|
xl_cmd = [ '/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(backend_vm, attachment):
|
||||||
|
xl_cmd = [ '/usr/lib/qubes/xl-qvm-usb-detach.py', str(attachment['xid']), attachment['devid'], attachment['frontend'], str(backend_vm.xid) ]
|
||||||
|
subprocess.check_call(xl_cmd)
|
||||||
|
|
||||||
|
def usb_detach_all(vm):
|
||||||
|
raise NotImplementedError("Detaching all devices from a given VM is not implemented yet")
|
||||||
|
|
||||||
####### QubesWatch ######
|
####### QubesWatch ######
|
||||||
|
|
||||||
def only_in_first_list(l1, l2):
|
def only_in_first_list(l1, l2):
|
||||||
|
157
dom0/qvm-tools/qvm-usb
Executable file
157
dom0/qvm-tools/qvm-usb
Executable file
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
#
|
||||||
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
|
#
|
||||||
|
# Copyright (C) 2010 Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from qubes.qubes import QubesVmCollection, QubesException
|
||||||
|
from qubes.qubesutils import usb_list,usb_attach,usb_detach,usb_detach_all,usb_check_attached
|
||||||
|
from optparse import OptionParser
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
pvusb_enable_flagfile = '/var/lib/qubes/pvusb-enable.flag'
|
||||||
|
|
||||||
|
def main():
|
||||||
|
usage = "usage: %prog -l [options]\n"\
|
||||||
|
"usage: %prog -a [options] <vm-name> <device-vm-name>:<device>\n"\
|
||||||
|
"usage: %prog -d [options] <device-vm-name>:<device>\n"\
|
||||||
|
"List/set VM USB devices."
|
||||||
|
# "usage: %prog -d [options] <vm-name>\n"\
|
||||||
|
|
||||||
|
parser = OptionParser (usage)
|
||||||
|
parser.add_option ("-l", "--list", action="store_true", dest="do_list", default=False)
|
||||||
|
parser.add_option ("-a", "--attach", action="store_true", dest="do_attach", default=False)
|
||||||
|
parser.add_option ("-d", "--detach", action="store_true", dest="do_detach", default=False)
|
||||||
|
# parser.add_option ("-f", "--frontend", dest="frontend",
|
||||||
|
# help="Specify device id at destination VM [default: first unused]")
|
||||||
|
parser.add_option ("--no-auto-detach", dest="auto_detach", action="store_false", default=True,
|
||||||
|
help="Fail when device already connected to other VM")
|
||||||
|
parser.add_option ("--force-root", action="store_true", dest="force_root", default=False,
|
||||||
|
help="Force to run, even with root privileges")
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args ()
|
||||||
|
|
||||||
|
if not os.path.exists(pvusb_enable_flagfile):
|
||||||
|
print >> sys.stderr, ""
|
||||||
|
print >> sys.stderr, "******* WARNING *** WARNING *** WARNING *** WARNING *******"
|
||||||
|
print >> sys.stderr, "*** ***"
|
||||||
|
print >> sys.stderr, "*** PVUSB passthrough kernel support is still unstable. ***"
|
||||||
|
print >> sys.stderr, "*** It can CRASH your VMs. ***"
|
||||||
|
print >> sys.stderr, "*** ***"
|
||||||
|
print >> sys.stderr, "***********************************************************"
|
||||||
|
print >> sys.stderr, ""
|
||||||
|
print >> sys.stderr, "To use it, you need install kernel from \"unstable\" repository"
|
||||||
|
print >> sys.stderr, "If you still want to enable it, type capital YES"
|
||||||
|
print >> sys.stderr, ""
|
||||||
|
prompt = raw_input ("Do you want enable PV USB support? ")
|
||||||
|
if prompt == "YES":
|
||||||
|
open(pvusb_enable_flagfile, "w").close()
|
||||||
|
else:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if os.geteuid() == 0:
|
||||||
|
if not options.force_root:
|
||||||
|
print >> sys.stderr, "*** Running this tool as root is strongly discouraged, this will lead you in permissions problems."
|
||||||
|
print >> sys.stderr, "Retry as unprivileged user."
|
||||||
|
print >> sys.stderr, "... or use --force-root to continue anyway."
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if options.do_list + options.do_attach + options.do_detach > 1:
|
||||||
|
print >> sys.stderr, "Only one of -l -a -d is allowed!"
|
||||||
|
exit (1)
|
||||||
|
|
||||||
|
if options.do_attach or options.do_detach:
|
||||||
|
qvm_collection = QubesVmCollection()
|
||||||
|
qvm_collection.lock_db_for_reading()
|
||||||
|
qvm_collection.load()
|
||||||
|
qvm_collection.unlock_db()
|
||||||
|
|
||||||
|
if options.do_attach:
|
||||||
|
if (len (args) != 2):
|
||||||
|
parser.error ("You must provide vm name and device!")
|
||||||
|
vm = qvm_collection.get_vm_by_name(args[0])
|
||||||
|
if vm is None:
|
||||||
|
parser.error ("Invalid VM name: %s" % args[0])
|
||||||
|
|
||||||
|
# FIXME: here we assume that device is always in form "domain:dev", which can be changed in the future
|
||||||
|
if args[1].find(":") < 0:
|
||||||
|
parser.error ("Invalid device syntax: %s" % args[1])
|
||||||
|
dev_list = usb_list()
|
||||||
|
if not args[1] in dev_list.keys():
|
||||||
|
parser.error ("Invalid device name: %s" % args[1])
|
||||||
|
dev = dev_list[args[1]]
|
||||||
|
backend_vm = qvm_collection.get_vm_by_name(dev['vm'])
|
||||||
|
assert backend_vm is not None
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
|
# if options.frontend:
|
||||||
|
# kwargs['frontend'] = options.frontend
|
||||||
|
kwargs['auto_detach'] = options.auto_detach
|
||||||
|
try:
|
||||||
|
usb_attach(vm, backend_vm, dev['device'], **kwargs)
|
||||||
|
except QubesException as e:
|
||||||
|
print >> sys.stderr, "ERROR: %s" % str(e)
|
||||||
|
sys.exit(1)
|
||||||
|
elif options.do_detach:
|
||||||
|
if (len (args) < 1):
|
||||||
|
parser.error ("You must provide device or vm name!")
|
||||||
|
if len(args) > 1:
|
||||||
|
parser.error ("Too many parameters")
|
||||||
|
# Check if provided name is VM
|
||||||
|
vm = qvm_collection.get_vm_by_name(args[0])
|
||||||
|
if vm is not None:
|
||||||
|
#kwargs = {}
|
||||||
|
#if options.frontend:
|
||||||
|
# kwargs['frontend'] = options.frontend
|
||||||
|
# usb_detach(vm, **kwargs)
|
||||||
|
#else:
|
||||||
|
usb_detach_all(vm)
|
||||||
|
else:
|
||||||
|
# Maybe usbvm:device?
|
||||||
|
|
||||||
|
# FIXME: nasty copy-paste from attach code half a page above
|
||||||
|
# FIXME: here we assume that device is always in form "domain:dev", which can be changed in the future
|
||||||
|
if args[0].find(":") < 0:
|
||||||
|
parser.error ("Invalid device syntax: %s" % args[0])
|
||||||
|
dev_list = usb_list()
|
||||||
|
if not args[0] in dev_list.keys():
|
||||||
|
parser.error ("Invalid device name: %s" % args[0])
|
||||||
|
dev = dev_list[args[0]]
|
||||||
|
backend_vm = qvm_collection.get_vm_by_name(dev['vm'])
|
||||||
|
assert backend_vm is not None
|
||||||
|
|
||||||
|
attached_to = usb_check_attached('', backend_vm.xid, dev['device'])
|
||||||
|
if attached_to is None:
|
||||||
|
print >> sys.stderr, "WARNING: Device not connected to any VM"
|
||||||
|
exit(0)
|
||||||
|
usb_detach(backend_vm, attached_to)
|
||||||
|
else:
|
||||||
|
if len(args) > 0:
|
||||||
|
parser.error ("Too many parameters")
|
||||||
|
# do_list
|
||||||
|
for dev in usb_list().values():
|
||||||
|
attached_to = usb_check_attached('', dev['xid'], dev['device'])
|
||||||
|
attached_to_str = ""
|
||||||
|
if attached_to:
|
||||||
|
attached_to_str = " (attached to %s:%s)" % (attached_to['vm'], attached_to['frontend'])
|
||||||
|
print "%s\t%s%s (USBv%s)" % (dev['name'], dev['desc'], attached_to_str, dev['usb_ver'])
|
||||||
|
exit (0)
|
||||||
|
|
||||||
|
main()
|
@ -1,2 +1,3 @@
|
|||||||
modprobe evtchn 2>/dev/null || modprobe xen-evtchn
|
modprobe evtchn 2>/dev/null || modprobe xen-evtchn
|
||||||
modprobe xen-blkback 2> /dev/null || modprobe blkbk
|
modprobe xen-blkback 2> /dev/null || modprobe blkbk
|
||||||
|
modprobe xen-usbfront 2> /dev/null
|
||||||
|
10
misc/qubes_usb.rules
Normal file
10
misc/qubes_usb.rules
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Expose all USB devices (except block) via xenstore
|
||||||
|
|
||||||
|
# Handle only USB devices
|
||||||
|
SUBSYSTEM!="usb", GOTO="qubes_usb_end"
|
||||||
|
|
||||||
|
ACTION=="add", IMPORT{program}="/usr/lib/qubes/usb_add_change"
|
||||||
|
ACTION=="change", IMPORT{program}="/usr/lib/qubes/usb_add_change"
|
||||||
|
ACTION=="remove", RUN+="/usr/lib/qubes/usb_remove"
|
||||||
|
|
||||||
|
LABEL="qubes_usb_end"
|
40
misc/usb_add_change
Executable file
40
misc/usb_add_change
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
##
|
||||||
|
## This script is invoked by udev rules whenever USB device appears or
|
||||||
|
## changes. This happens in usbvm domain (or dom0 if USB controller
|
||||||
|
## drivers are in dom0). The script records information about available
|
||||||
|
## USB devices into XS directory, making it available to qvm-usb tool
|
||||||
|
## running in dom0.
|
||||||
|
##
|
||||||
|
|
||||||
|
# FIXME: Ignore USB hubs and other wierd devices (see also in usb_remove).
|
||||||
|
[ "`echo $TYPE | cut -f1 -d/`" = "9" ] && exit 0
|
||||||
|
[ "$DEVTYPE" != "usb_device" ] && exit 0
|
||||||
|
|
||||||
|
# xenstore doesn't allow dot in key name
|
||||||
|
XSNAME=`basename ${DEVPATH} | tr . _`
|
||||||
|
|
||||||
|
# FIXME: For some devices (my Cherry keyboard) ID_SERIAL does not
|
||||||
|
# contain proper human-readable name, should find better method to
|
||||||
|
# build devide description.
|
||||||
|
#DESC=`python -c "dev='%d-%d' % (int('${BUSNUM}'.lstrip('0')), (int('${DEVNUM}'.lstrip('0'))-1)); from xen.util import vusb_util; print vusb_util.get_usbdevice_info(dev);"`
|
||||||
|
DESC="${ID_VENDOR_ID}:${ID_MODEL_ID} ${ID_SERIAL}"
|
||||||
|
|
||||||
|
VERSION=`cat /sys/$DEVPATH/version`
|
||||||
|
if [ "${VERSION}" = " 1.00" -o "${VERSION}" = " 1.10" ] ; then
|
||||||
|
VERSION=1
|
||||||
|
elif [ "${VERSION}" = " 2.00" ] ; then
|
||||||
|
VERSION=2
|
||||||
|
else
|
||||||
|
# FIXME: silently ignoring devices with unexpected USB version
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
XS_KEY="qubes-usb-devices/$XSNAME"
|
||||||
|
|
||||||
|
xenstore-write "$XS_KEY/desc" "$DESC"
|
||||||
|
xenstore-write "$XS_KEY/usb-ver" "$VERSION"
|
||||||
|
|
||||||
|
# Make sure PVUSB backend driver is loaded.
|
||||||
|
/sbin/modprobe xen-usbback 2> /dev/null || /sbin/modprobe usbbk
|
9
misc/usb_remove
Executable file
9
misc/usb_remove
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# FIXME: Ignore USB hubs.
|
||||||
|
[ "`echo $TYPE | cut -f1 -d/`" = "9" ] && exit 0
|
||||||
|
|
||||||
|
NAME=`basename ${DEVPATH} | tr . _`
|
||||||
|
XS_KEY="qubes-usb-devices/$NAME"
|
||||||
|
|
||||||
|
xenstore-rm "$XS_KEY"
|
24
misc/vusb-ctl.py
Executable file
24
misc/vusb-ctl.py
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
##
|
||||||
|
## Python script wrapper around xen.util.vusb_util bind_usb_device() and unbind_usb_device() methods
|
||||||
|
## Run as root in usbvm
|
||||||
|
##
|
||||||
|
|
||||||
|
from xen.util import vusb_util
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
if len(sys.argv)!=3:
|
||||||
|
print 'usage: vusb-ctl <bind|unbind> device'
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
device=sys.argv[2]
|
||||||
|
if sys.argv[1] == 'bind':
|
||||||
|
vusb_util.bind_usb_device(device)
|
||||||
|
elif sys.argv[1] == 'unbind':
|
||||||
|
vusb_util.unbind_usb_device(device)
|
||||||
|
else:
|
||||||
|
print "Invalid command, must be 'bind' or 'unbind'"
|
||||||
|
sys.exit(1)
|
||||||
|
|
48
misc/xl-qvm-usb-attach.py
Executable file
48
misc/xl-qvm-usb-attach.py
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
##
|
||||||
|
## This script is for dom0
|
||||||
|
## The syntax is modelled after "xl block-attach"
|
||||||
|
##
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import xen.lowlevel.xl
|
||||||
|
|
||||||
|
|
||||||
|
# parse command line
|
||||||
|
if (len(sys.argv)<4) or (len(sys.argv)>5):
|
||||||
|
print 'usage: xl-qvm-usb-attach.py <frontendvm-xid> <backendvm-device> <frontendvm-device> [<backendvm-xid>]'
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
frontendvm_xid=sys.argv[1]
|
||||||
|
backendvm_device=sys.argv[2]
|
||||||
|
|
||||||
|
frontend=sys.argv[3].split('-')
|
||||||
|
if len(frontend)!=2:
|
||||||
|
print 'Error: frontendvm-device must be in <controller>-<port> format'
|
||||||
|
sys.exit(1)
|
||||||
|
(controller, port)=frontend
|
||||||
|
|
||||||
|
if len(sys.argv)>4:
|
||||||
|
backendvm_xid=int(sys.argv[4])
|
||||||
|
backendvm_name=xen.lowlevel.xl.ctx().domid_to_name(backendvm_xid)
|
||||||
|
else:
|
||||||
|
backendvm_xid=0
|
||||||
|
|
||||||
|
# FIXME: command injection
|
||||||
|
os.system("xenstore-write /local/domain/%s/backend/vusb/%s/%s/port/%s '%s'"
|
||||||
|
% (backendvm_xid, frontendvm_xid, controller, port, backendvm_device))
|
||||||
|
|
||||||
|
cmd = "/usr/lib/qubes/vusb-ctl.py bind '%s'" % backendvm_device
|
||||||
|
if backendvm_xid == 0:
|
||||||
|
os.system("sudo %s" % cmd)
|
||||||
|
else:
|
||||||
|
from qubes.qubes import QubesVmCollection
|
||||||
|
qvm_collection = QubesVmCollection()
|
||||||
|
qvm_collection.lock_db_for_reading()
|
||||||
|
qvm_collection.load()
|
||||||
|
qvm_collection.unlock_db()
|
||||||
|
|
||||||
|
# launch
|
||||||
|
qvm_collection.get_vm_by_name(backendvm_name).run("root: %s" % cmd)
|
49
misc/xl-qvm-usb-detach.py
Executable file
49
misc/xl-qvm-usb-detach.py
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
##
|
||||||
|
## This script is for dom0
|
||||||
|
## The syntax is modelled after "xl block-attach"
|
||||||
|
## FIXME: should be modelled after block-detach instead
|
||||||
|
##
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import xen.lowlevel.xl
|
||||||
|
|
||||||
|
# parse command line
|
||||||
|
if (len(sys.argv)<4) or (len(sys.argv)>5):
|
||||||
|
print 'usage: xl-qvm-usb-detach.py <frontendvm-xid> <backendvm-device> <frontendvm-device> [<backendvm-xid>]'
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
frontendvm_xid=sys.argv[1]
|
||||||
|
backendvm_device=sys.argv[2]
|
||||||
|
|
||||||
|
frontend=sys.argv[3].split('-')
|
||||||
|
if len(frontend)!=2:
|
||||||
|
print 'Error: frontendvm-device must be in <controller>-<port> format'
|
||||||
|
sys.exit(1)
|
||||||
|
(controller, port)=frontend
|
||||||
|
|
||||||
|
if len(sys.argv)>4:
|
||||||
|
backendvm_xid=int(sys.argv[4])
|
||||||
|
backendvm_name=xen.lowlevel.xl.ctx().domid_to_name(backendvm_xid)
|
||||||
|
else:
|
||||||
|
backendvm_xid=0
|
||||||
|
|
||||||
|
cmd = "/usr/lib/qubes/vusb-ctl.py unbind '%s'" % backendvm_device
|
||||||
|
if backendvm_xid == 0:
|
||||||
|
os.system("sudo %s" % cmd)
|
||||||
|
else:
|
||||||
|
from qubes.qubes import QubesVmCollection
|
||||||
|
qvm_collection = QubesVmCollection()
|
||||||
|
qvm_collection.lock_db_for_reading()
|
||||||
|
qvm_collection.load()
|
||||||
|
qvm_collection.unlock_db()
|
||||||
|
|
||||||
|
# launch
|
||||||
|
qvm_collection.get_vm_by_name(backendvm_name).run("root: %s" % cmd)
|
||||||
|
|
||||||
|
# FIXME: command injection
|
||||||
|
os.system("xenstore-write /local/domain/%s/backend/vusb/%s/%s/port/%s ''"
|
||||||
|
% (backendvm_xid, frontendvm_xid, controller, port))
|
||||||
|
|
@ -56,9 +56,10 @@ python -O -m compileall qvm-core qmemman
|
|||||||
make -C restore
|
make -C restore
|
||||||
make -C qubes_rpc
|
make -C qubes_rpc
|
||||||
make -C ../qubes_rpc
|
make -C ../qubes_rpc
|
||||||
make -C ../vchan -f Makefile.linux
|
|
||||||
make -C ../u2mfn
|
make -C ../u2mfn
|
||||||
|
make -C ../vchan -f Makefile.linux
|
||||||
make -C ../qrexec
|
make -C ../qrexec
|
||||||
|
make -C ../misc
|
||||||
|
|
||||||
%install
|
%install
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ ln -s block-snapshot $RPM_BUILD_ROOT/etc/xen/scripts/block-origin
|
|||||||
|
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
|
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||||
cp ../misc/qubes_block.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_block.rules
|
cp ../misc/qubes_block.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_block.rules
|
||||||
|
cp ../misc/qubes_usb.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_usb.rules
|
||||||
|
|
||||||
mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
cp qvm-core/qubes.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
cp qvm-core/qubes.py $RPM_BUILD_ROOT%{python_sitearch}/qubes
|
||||||
@ -117,6 +119,11 @@ cp qubes_rpc/qubes-receive-updates $RPM_BUILD_ROOT/usr/lib/qubes/
|
|||||||
cp ../misc/block_add_change $RPM_BUILD_ROOT/usr/lib/qubes/
|
cp ../misc/block_add_change $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
cp ../misc/block_remove $RPM_BUILD_ROOT/usr/lib/qubes/
|
cp ../misc/block_remove $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
cp ../misc/block_cleanup $RPM_BUILD_ROOT/usr/lib/qubes/
|
cp ../misc/block_cleanup $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
cp ../misc/usb_add_change $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
cp ../misc/usb_remove $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
cp ../misc/vusb-ctl.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
cp ../misc/xl-qvm-usb-attach.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
cp ../misc/xl-qvm-usb-detach.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
cp aux-tools/block_cleaner_daemon.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
cp aux-tools/block_cleaner_daemon.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
cp aux-tools/fix_dir_perms.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
cp aux-tools/fix_dir_perms.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
|
||||||
@ -168,6 +175,7 @@ cp misc/qubes-appmenu-select.desktop $RPM_BUILD_ROOT/usr/share/qubes/
|
|||||||
cp misc/qubes-start.desktop $RPM_BUILD_ROOT/usr/share/qubes/
|
cp misc/qubes-start.desktop $RPM_BUILD_ROOT/usr/share/qubes/
|
||||||
cp misc/vm-template.conf $RPM_BUILD_ROOT/usr/share/qubes/
|
cp misc/vm-template.conf $RPM_BUILD_ROOT/usr/share/qubes/
|
||||||
cp misc/vm-template-hvm.conf $RPM_BUILD_ROOT/usr/share/qubes/
|
cp misc/vm-template-hvm.conf $RPM_BUILD_ROOT/usr/share/qubes/
|
||||||
|
cp misc/Fedora-13-comps.xml $RPM_BUILD_ROOT/usr/share/qubes/
|
||||||
|
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||||
cp ../network/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/lib/qubes
|
cp ../network/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/lib/qubes
|
||||||
@ -367,16 +375,21 @@ fi
|
|||||||
/usr/lib/qubes/block_remove
|
/usr/lib/qubes/block_remove
|
||||||
/usr/lib/qubes/block_cleanup
|
/usr/lib/qubes/block_cleanup
|
||||||
/usr/lib/qubes/block_cleaner_daemon.py*
|
/usr/lib/qubes/block_cleaner_daemon.py*
|
||||||
|
/usr/lib/qubes/usb_add_change
|
||||||
|
/usr/lib/qubes/usb_remove
|
||||||
|
/usr/lib/qubes/vusb-ctl.py*
|
||||||
|
/usr/lib/qubes/xl-qvm-usb-attach.py*
|
||||||
|
/usr/lib/qubes/xl-qvm-usb-detach.py*
|
||||||
/usr/lib/qubes/fix_dir_perms.sh
|
/usr/lib/qubes/fix_dir_perms.sh
|
||||||
%attr(4750,root,qubes) /usr/lib/qubes/qfile-dom0-unpacker
|
%attr(4750,root,qubes) /usr/lib/qubes/qfile-dom0-unpacker
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes
|
%attr(0770,root,qubes) %dir /var/lib/qubes
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/vm-templates
|
%attr(0770,root,qubes) %dir /var/lib/qubes/vm-templates
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/appvms
|
%attr(0770,root,qubes) %dir /var/lib/qubes/appvms
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/servicevms
|
%attr(0770,root,qubes) %dir /var/lib/qubes/servicevms
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/backup
|
%attr(0770,root,qubes) %dir /var/lib/qubes/backup
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/dvmdata
|
%attr(0770,root,qubes) %dir /var/lib/qubes/dvmdata
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/updates
|
%attr(0770,root,qubes) %dir /var/lib/qubes/updates
|
||||||
%attr(770,root,qubes) %dir /var/lib/qubes/vm-kernels
|
%attr(0770,root,qubes) %dir /var/lib/qubes/vm-kernels
|
||||||
/usr/share/qubes/icons/*.png
|
/usr/share/qubes/icons/*.png
|
||||||
/usr/share/qubes/qubes-vm.directory.template
|
/usr/share/qubes/qubes-vm.directory.template
|
||||||
/usr/share/qubes/qubes-templatevm.directory.template
|
/usr/share/qubes/qubes-templatevm.directory.template
|
||||||
@ -387,6 +400,7 @@ fi
|
|||||||
/usr/share/qubes/qubes-start.desktop
|
/usr/share/qubes/qubes-start.desktop
|
||||||
/usr/share/qubes/vm-template.conf
|
/usr/share/qubes/vm-template.conf
|
||||||
/usr/share/qubes/vm-template-hvm.conf
|
/usr/share/qubes/vm-template-hvm.conf
|
||||||
|
/usr/share/qubes/Fedora-13-comps.xml
|
||||||
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
||||||
/usr/lib/qubes/qubes_fix_nm_conf.sh
|
/usr/lib/qubes/qubes_fix_nm_conf.sh
|
||||||
/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
||||||
@ -421,7 +435,7 @@ fi
|
|||||||
/etc/qubes_rpc/qubes.ReceiveUpdates
|
/etc/qubes_rpc/qubes.ReceiveUpdates
|
||||||
%attr(4750,root,qubes) /usr/lib/qubes/qrexec_daemon
|
%attr(4750,root,qubes) /usr/lib/qubes/qrexec_daemon
|
||||||
%attr(2770,root,qubes) %dir /var/log/qubes
|
%attr(2770,root,qubes) %dir /var/log/qubes
|
||||||
%attr(770,root,qubes) %dir /var/run/qubes
|
%attr(0770,root,qubes) %dir /var/run/qubes
|
||||||
%{_libdir}/libvchan.so
|
%{_libdir}/libvchan.so
|
||||||
%{_libdir}/libu2mfn.so
|
%{_libdir}/libu2mfn.so
|
||||||
/etc/yum.real.repos.d/qubes-cached.repo
|
/etc/yum.real.repos.d/qubes-cached.repo
|
||||||
@ -429,8 +443,9 @@ fi
|
|||||||
/etc/xdg/autostart/qubes-guid.desktop
|
/etc/xdg/autostart/qubes-guid.desktop
|
||||||
/etc/security/limits.d/99-qubes.conf
|
/etc/security/limits.d/99-qubes.conf
|
||||||
/etc/udev/rules.d/99-qubes_block.rules
|
/etc/udev/rules.d/99-qubes_block.rules
|
||||||
/etc/cron.daily/qubes-dom0-updates.cron
|
/etc/udev/rules.d/99-qubes_usb.rules
|
||||||
/etc/cron.d/qubes-sync-clock.cron
|
%attr(0644,root,root) /etc/cron.daily/qubes-dom0-updates.cron
|
||||||
|
%attr(0644,root,root) /etc/cron.d/qubes-sync-clock.cron
|
||||||
/etc/dracut.conf.d/*
|
/etc/dracut.conf.d/*
|
||||||
%dir /usr/share/dracut/modules.d/90qubes-pciback
|
%dir /usr/share/dracut/modules.d/90qubes-pciback
|
||||||
/usr/share/dracut/modules.d/90qubes-pciback/*
|
/usr/share/dracut/modules.d/90qubes-pciback/*
|
||||||
|
@ -113,9 +113,12 @@ install -D misc/xenstore-watch $RPM_BUILD_ROOT/usr/bin/xenstore-watch-qubes
|
|||||||
install -d $RPM_BUILD_ROOT/etc/udev/rules.d
|
install -d $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||||
install -m 0644 misc/qubes_memory.rules $RPM_BUILD_ROOT/etc/udev/rules.d/50-qubes_memory.rules
|
install -m 0644 misc/qubes_memory.rules $RPM_BUILD_ROOT/etc/udev/rules.d/50-qubes_memory.rules
|
||||||
install -m 0644 misc/qubes_block.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_block.rules
|
install -m 0644 misc/qubes_block.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_block.rules
|
||||||
|
install -m 0644 misc/qubes_usb.rules $RPM_BUILD_ROOT/etc/udev/rules.d/99-qubes_usb.rules
|
||||||
install -d $RPM_BUILD_ROOT/usr/lib/qubes/
|
install -d $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
install misc/qubes_download_dom0_updates.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
install misc/qubes_download_dom0_updates.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
install misc/{block_add_change,block_remove,block_cleanup} $RPM_BUILD_ROOT/usr/lib/qubes/
|
install misc/{block_add_change,block_remove,block_cleanup} $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
install misc/{usb_add_change,usb_remove} $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
|
install misc/vusb-ctl.py $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
install misc/qubes_trigger_sync_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
install misc/qubes_trigger_sync_appmenus.sh $RPM_BUILD_ROOT/usr/lib/qubes/
|
||||||
install -D -m 0644 misc/qubes_trigger_sync_appmenus.action $RPM_BUILD_ROOT/etc/yum/post-actions/qubes_trigger_sync_appmenus.action
|
install -D -m 0644 misc/qubes_trigger_sync_appmenus.action $RPM_BUILD_ROOT/etc/yum/post-actions/qubes_trigger_sync_appmenus.action
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
|
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
|
||||||
@ -209,7 +212,7 @@ remove_ShowIn () {
|
|||||||
for F in abrt-applet deja-dup-monitor imsettings-start krb5-auth-dialog pulseaudio restorecond sealertauto gnome-power-manager gnome-sound-applet gnome-screensaver orca-autostart; do
|
for F in abrt-applet deja-dup-monitor imsettings-start krb5-auth-dialog pulseaudio restorecond sealertauto gnome-power-manager gnome-sound-applet gnome-screensaver orca-autostart; do
|
||||||
if [ -e /etc/xdg/autostart/$F.desktop ]; then
|
if [ -e /etc/xdg/autostart/$F.desktop ]; then
|
||||||
remove_ShowIn $F
|
remove_ShowIn $F
|
||||||
echo 'NotShowIn=QUBES' >> /etc/xdg/autostart/$F.desktop
|
echo 'NotShowIn=QUBES;' >> /etc/xdg/autostart/$F.desktop
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -217,7 +220,7 @@ done
|
|||||||
for F in gcm-apply ; do
|
for F in gcm-apply ; do
|
||||||
if [ -e /etc/xdg/autostart/$F.desktop ]; then
|
if [ -e /etc/xdg/autostart/$F.desktop ]; then
|
||||||
remove_ShowIn $F
|
remove_ShowIn $F
|
||||||
echo 'NotShowIn=DisposableVM' >> /etc/xdg/autostart/$F.desktop
|
echo 'NotShowIn=DisposableVM;' >> /etc/xdg/autostart/$F.desktop
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -312,6 +315,10 @@ do
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $(basename $f) == "99-qubes_usb.rules" ] ; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $(basename $f) == "90-hal.rules" ] ; then
|
if [ $(basename $f) == "90-hal.rules" ] ; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@ -383,6 +390,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
/etc/udev/rules.d/50-qubes_memory.rules
|
/etc/udev/rules.d/50-qubes_memory.rules
|
||||||
/etc/udev/rules.d/99-qubes_block.rules
|
/etc/udev/rules.d/99-qubes_block.rules
|
||||||
/etc/udev/rules.d/99-qubes_network.rules
|
/etc/udev/rules.d/99-qubes_network.rules
|
||||||
|
/etc/udev/rules.d/99-qubes_usb.rules
|
||||||
/etc/xen/scripts/vif-route-qubes
|
/etc/xen/scripts/vif-route-qubes
|
||||||
/etc/yum.conf.d/qubes-proxy.conf
|
/etc/yum.conf.d/qubes-proxy.conf
|
||||||
/etc/yum.repos.d/qubes.repo
|
/etc/yum.repos.d/qubes.repo
|
||||||
@ -399,6 +407,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
/usr/lib/qubes/block_add_change
|
/usr/lib/qubes/block_add_change
|
||||||
/usr/lib/qubes/block_cleanup
|
/usr/lib/qubes/block_cleanup
|
||||||
/usr/lib/qubes/block_remove
|
/usr/lib/qubes/block_remove
|
||||||
|
/usr/lib/qubes/usb_add_change
|
||||||
|
/usr/lib/qubes/usb_remove
|
||||||
|
/usr/lib/qubes/vusb-ctl.py*
|
||||||
/usr/lib/qubes/dispvm-prerun.sh
|
/usr/lib/qubes/dispvm-prerun.sh
|
||||||
/usr/lib/qubes/sync-ntp-clock
|
/usr/lib/qubes/sync-ntp-clock
|
||||||
/usr/lib/qubes/prepare-suspend
|
/usr/lib/qubes/prepare-suspend
|
||||||
|
50
test/block-001-list-attach-use-detach
Executable file
50
test/block-001-list-attach-use-detach
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tmpf=`mktemp`
|
||||||
|
|
||||||
|
## === List
|
||||||
|
echo 'qvm-block -l'
|
||||||
|
qvm-block -l > $tmpf
|
||||||
|
|
||||||
|
cat <<'END' | diff -u - $tmpf
|
||||||
|
netvm:sda STORAGE_DEVICE () 0 B
|
||||||
|
dom0:sdb1 Cruzer () 3 GiB
|
||||||
|
dom0:sdb Cruzer () 3 GiB
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Attach
|
||||||
|
echo 'qvm-block -a'
|
||||||
|
qvm-block -a work dom0:sdb | diff -u /dev/null -
|
||||||
|
|
||||||
|
## === List again
|
||||||
|
echo 'qvm-block -l'
|
||||||
|
qvm-block -l > $tmpf
|
||||||
|
|
||||||
|
cat <<'END' | diff -u - $tmpf
|
||||||
|
netvm:sda STORAGE_DEVICE () 0 B
|
||||||
|
dom0:sdb1 Cruzer () 3 GiB
|
||||||
|
dom0:sdb Cruzer () 3 GiB (attached to 'work' as 'xvdi')
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Use
|
||||||
|
echo 'qvm-run work fdisk'
|
||||||
|
qvm-run -qp work 'su - root -c "fdisk -l /dev/xvdi"' > $tmpf
|
||||||
|
|
||||||
|
cat <<'END' | diff -u - $tmpf
|
||||||
|
|
||||||
|
Disk /dev/xvdi: 4022 MB, 4022337024 bytes
|
||||||
|
124 heads, 62 sectors/track, 1021 cylinders, total 7856127 sectors
|
||||||
|
Units = sectors of 1 * 512 = 512 bytes
|
||||||
|
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||||
|
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||||
|
Disk identifier: 0x3963a77b
|
||||||
|
|
||||||
|
Device Boot Start End Blocks Id System
|
||||||
|
/dev/xvdi1 * 62 7849447 3924693 c W95 FAT32 (LBA)
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Detach
|
||||||
|
echo 'qvm-block -d'
|
||||||
|
qvm-block -d work dom0:sdb1 | diff -u /dev/null -
|
||||||
|
|
||||||
|
rm $tmpf
|
14
test/pvusb-001-mouse-kbd-attached
Executable file
14
test/pvusb-001-mouse-kbd-attached
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tmpf=`mktemp`
|
||||||
|
|
||||||
|
sudo xenstore-ls -f qubes-usb-devices | sort > $tmpf
|
||||||
|
|
||||||
|
cat << 'END' | diff -u - $tmpf
|
||||||
|
qubes-usb-devices/2-1 = ""
|
||||||
|
qubes-usb-devices/2-1/desc = "046a:0021 046a_0021"
|
||||||
|
qubes-usb-devices/2-2 = ""
|
||||||
|
qubes-usb-devices/2-2/desc = "045e:0745 Microsoft_Microsoft\xc2\xae_Nano_Transceiver_v1.0"
|
||||||
|
END
|
||||||
|
|
||||||
|
rm $tmpf
|
18
test/pvusb-002-mouse-kbd-usbstick-wlan-attached
Executable file
18
test/pvusb-002-mouse-kbd-usbstick-wlan-attached
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tmpf=`mktemp`
|
||||||
|
|
||||||
|
sudo xenstore-ls -f qubes-usb-devices | sort > $tmpf
|
||||||
|
|
||||||
|
cat << 'END' | diff -u - $tmpf
|
||||||
|
qubes-usb-devices/2-1 = ""
|
||||||
|
qubes-usb-devices/2-1/desc = "046a:0021 046a_0021"
|
||||||
|
qubes-usb-devices/2-2 = ""
|
||||||
|
qubes-usb-devices/2-2/desc = "045e:0745 Microsoft_Microsoft\xc2\xae_Nano_Transceiver_v1.0"
|
||||||
|
qubes-usb-devices/7-1 = ""
|
||||||
|
qubes-usb-devices/7-1/desc = "07d1:3c0a Ralink_11n_Adapter_1.0"
|
||||||
|
qubes-usb-devices/7-5 = ""
|
||||||
|
qubes-usb-devices/7-5/desc = "0781:5530 SanDisk_Cruzer_1942531DB09038A6"
|
||||||
|
END
|
||||||
|
|
||||||
|
rm $tmpf
|
67
test/pvusb-003-list-attach-use-detach
Executable file
67
test/pvusb-003-list-attach-use-detach
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tmpf=`mktemp`
|
||||||
|
domu='qdvp'
|
||||||
|
|
||||||
|
## === List
|
||||||
|
echo 'qvm-usb -l'
|
||||||
|
qvm-usb -l | sort > $tmpf
|
||||||
|
|
||||||
|
cat <<'END' | diff -bu - $tmpf
|
||||||
|
dom0:2-1 046a:0021 046a_0021
|
||||||
|
dom0:2-2 045e:0745 Microsoft_Microsoft®_Nano_Transceiver_v1.0
|
||||||
|
dom0:7-1 07d1:3c0a Ralink_11n_Adapter_1.0
|
||||||
|
dom0:7-5 0781:5530 SanDisk_Cruzer_1942531DB09038A6
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Attach
|
||||||
|
echo 'qvm-usb -a'
|
||||||
|
qvm-usb -a $domu dom0:7-5 | diff -bu /dev/null -
|
||||||
|
#echo 'pvusb-script/usb-attach.py'
|
||||||
|
#sudo /home/abb/pvusb-scripts/usb-attach.py 7-5 3 1
|
||||||
|
|
||||||
|
## === List again
|
||||||
|
echo 'qvm-usb -l'
|
||||||
|
qvm-usb -l | sort > $tmpf
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
cat <<'END' | diff -bu - $tmpf
|
||||||
|
dom0:2-1 046a:0021 046a_0021
|
||||||
|
dom0:2-2 045e:0745 Microsoft_Microsoft®_Nano_Transceiver_v1.0
|
||||||
|
dom0:7-1 07d1:3c0a Ralink_11n_Adapter_1.0
|
||||||
|
dom0:7-5 0781:5530 SanDisk_Cruzer_1942531DB09038A6
|
||||||
|
END
|
||||||
|
|
||||||
|
read -p 'Press ENTER to continue'
|
||||||
|
|
||||||
|
## === Use: try ls
|
||||||
|
echo 'qvm-run $domu ls /dev/sda'
|
||||||
|
qvm-run -p $domu 'ls /dev/sda' > $tmpf
|
||||||
|
cat <<'END' | diff -bu - $tmpf
|
||||||
|
/dev/sda
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Use: try fdisk
|
||||||
|
echo 'qvm-run $domu fdisk'
|
||||||
|
qvm-run -p $domu 'su - root -c "fdisk -l /dev/sda"' > $tmpf
|
||||||
|
|
||||||
|
cat <<'END' | diff -bu - $tmpf
|
||||||
|
|
||||||
|
Disk /dev/sda: 4022 MB, 4022337024 bytes
|
||||||
|
124 heads, 62 sectors/track, 1021 cylinders, total 7856127 sectors
|
||||||
|
Units = sectors of 1 * 512 = 512 bytes
|
||||||
|
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||||
|
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||||
|
Disk identifier: 0x3963a77b
|
||||||
|
|
||||||
|
Device Boot Start End Blocks Id System
|
||||||
|
/dev/sda1 * 62 7849447 3924693 c W95 FAT32 (LBA)
|
||||||
|
END
|
||||||
|
|
||||||
|
## === Detach
|
||||||
|
#echo 'qvm-usb -d'
|
||||||
|
#qvm-usb -d $domu:7-5 | diff -bu /dev/null -
|
||||||
|
echo 'pvusb-script/usb-detach.py'
|
||||||
|
sudo /home/abb/pvusb-scripts/usb-detach.py 7-5 4 1
|
||||||
|
|
||||||
|
rm $tmpf
|
@ -31,11 +31,24 @@ static int u2mfn_fd = -1;
|
|||||||
|
|
||||||
static int get_fd()
|
static int get_fd()
|
||||||
{
|
{
|
||||||
if (u2mfn_fd == -1) {
|
if (u2mfn_fd == -1)
|
||||||
u2mfn_fd = open("/proc/u2mfn", O_RDWR);
|
u2mfn_fd = u2mfn_get_fd();
|
||||||
if (u2mfn_fd < 0)
|
if (u2mfn_fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int u2mfn_get_fd()
|
||||||
|
{
|
||||||
|
return open("/proc/u2mfn", O_RDWR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int u2mfn_get_mfn_for_page_with_fd(int fd, long va, int *mfn)
|
||||||
|
{
|
||||||
|
*mfn = ioctl(fd, U2MFN_GET_MFN_FOR_PAGE, va);
|
||||||
|
if (*mfn == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +56,12 @@ int u2mfn_get_mfn_for_page(long va, int *mfn)
|
|||||||
{
|
{
|
||||||
if (get_fd())
|
if (get_fd())
|
||||||
return -1;
|
return -1;
|
||||||
*mfn = ioctl(u2mfn_fd, U2MFN_GET_MFN_FOR_PAGE, va);
|
return u2mfn_get_mfn_for_page_with_fd(u2mfn_fd, va, mfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
int u2mfn_get_last_mfn_with_fd(int fd, int *mfn)
|
||||||
|
{
|
||||||
|
*mfn = ioctl(fd, U2MFN_GET_LAST_MFN, 0);
|
||||||
if (*mfn == -1)
|
if (*mfn == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -54,22 +72,20 @@ int u2mfn_get_last_mfn(int *mfn)
|
|||||||
{
|
{
|
||||||
if (get_fd())
|
if (get_fd())
|
||||||
return -1;
|
return -1;
|
||||||
|
return u2mfn_get_last_mfn_with_fd(u2mfn_fd, mfn);
|
||||||
*mfn = ioctl(u2mfn_fd, U2MFN_GET_LAST_MFN, 0);
|
|
||||||
if (*mfn == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *u2mfn_alloc_kpage_with_fd(int fd)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
ret =
|
||||||
|
mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
char *u2mfn_alloc_kpage()
|
char *u2mfn_alloc_kpage()
|
||||||
{
|
{
|
||||||
char *ret;
|
|
||||||
if (get_fd())
|
if (get_fd())
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
ret =
|
return u2mfn_alloc_kpage_with_fd(u2mfn_fd);
|
||||||
mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, u2mfn_fd, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int u2mfn_get_fd();
|
||||||
int u2mfn_get_mfn_for_page(long va, int *mfn) ;
|
int u2mfn_get_mfn_for_page(long va, int *mfn) ;
|
||||||
|
int u2mfn_get_mfn_for_page_with_fd(int fd, long va, int *mfn) ;
|
||||||
int u2mfn_get_last_mfn(int *mfn) ;
|
int u2mfn_get_last_mfn(int *mfn) ;
|
||||||
char *u2mfn_alloc_kpage(void) ;
|
int u2mfn_get_last_mfn_with_fd(int fd, int *mfn) ;
|
||||||
|
char *u2mfn_alloc_kpage(void);
|
||||||
|
char *u2mfn_alloc_kpage_with_fd(int fd);
|
||||||
|
@ -92,6 +92,7 @@ static int ring_init(struct libvchan *ctrl)
|
|||||||
static int ring_init(struct libvchan *ctrl)
|
static int ring_init(struct libvchan *ctrl)
|
||||||
{
|
{
|
||||||
int mfn;
|
int mfn;
|
||||||
|
int u2mfn_fd;
|
||||||
struct vchan_interface *ring;
|
struct vchan_interface *ring;
|
||||||
#ifdef CONFIG_STUBDOM
|
#ifdef CONFIG_STUBDOM
|
||||||
ring = (struct vchan_interface *) memalign(XC_PAGE_SIZE, sizeof(*ring));
|
ring = (struct vchan_interface *) memalign(XC_PAGE_SIZE, sizeof(*ring));
|
||||||
@ -102,12 +103,15 @@ static int ring_init(struct libvchan *ctrl)
|
|||||||
|
|
||||||
mfn = virtual_to_mfn(ring);
|
mfn = virtual_to_mfn(ring);
|
||||||
#else
|
#else
|
||||||
ring = (struct vchan_interface *) u2mfn_alloc_kpage ();
|
u2mfn_fd = u2mfn_get_fd();
|
||||||
|
if (u2mfn_fd < 0)
|
||||||
|
return -1;
|
||||||
|
ring = (struct vchan_interface *) u2mfn_alloc_kpage_with_fd (u2mfn_fd);
|
||||||
|
|
||||||
if (ring == MAP_FAILED)
|
if (ring == MAP_FAILED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (u2mfn_get_last_mfn (&mfn) < 0)
|
if (u2mfn_get_last_mfn_with_fd (u2mfn_fd, &mfn) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ int libvchan_wait(struct libvchan *ctrl)
|
|||||||
may write less data than requested;
|
may write less data than requested;
|
||||||
returns the amount of data processed, -1 on error or peer close
|
returns the amount of data processed, -1 on error or peer close
|
||||||
*/
|
*/
|
||||||
int libvchan_write(struct libvchan *ctrl, char *data, int size)
|
int libvchan_write(struct libvchan *ctrl, const char *data, int size)
|
||||||
{
|
{
|
||||||
int avail, avail_contig;
|
int avail, avail_contig;
|
||||||
int real_idx;
|
int real_idx;
|
||||||
|
@ -78,7 +78,7 @@ struct libvchan *libvchan_server_init(int devno);
|
|||||||
struct libvchan *libvchan_client_init(int domain, int devno);
|
struct libvchan *libvchan_client_init(int domain, int devno);
|
||||||
|
|
||||||
int libvchan_server_handle_connected(struct libvchan *ctrl);
|
int libvchan_server_handle_connected(struct libvchan *ctrl);
|
||||||
int libvchan_write(struct libvchan *ctrl, char *data, int size);
|
int libvchan_write(struct libvchan *ctrl, const char *data, int size);
|
||||||
int libvchan_read(struct libvchan *ctrl, char *data, int size);
|
int libvchan_read(struct libvchan *ctrl, char *data, int size);
|
||||||
int libvchan_wait(struct libvchan *ctrl);
|
int libvchan_wait(struct libvchan *ctrl);
|
||||||
int libvchan_close(struct libvchan *ctrl);
|
int libvchan_close(struct libvchan *ctrl);
|
||||||
|
@ -1 +1 @@
|
|||||||
2.0.36
|
2.1.1
|
||||||
|
@ -1 +1 @@
|
|||||||
1.7.46
|
2.1.1
|
||||||
|
@ -17,6 +17,8 @@ start()
|
|||||||
|
|
||||||
# Set permissions to /proc/xen/xenbus, so normal user can use xenstore-read
|
# Set permissions to /proc/xen/xenbus, so normal user can use xenstore-read
|
||||||
chmod 666 /proc/xen/xenbus
|
chmod 666 /proc/xen/xenbus
|
||||||
|
# Set permissions to files needed to listen at vchan
|
||||||
|
chmod 666 /proc/u2mfn /dev/xen/evtchn
|
||||||
|
|
||||||
mkdir -p /var/run/xen-hotplug
|
mkdir -p /var/run/xen-hotplug
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ mkdir -p /var/run/xen-hotplug
|
|||||||
|
|
||||||
# Set permissions to /proc/xen/xenbus, so normal user can use xenstore-read
|
# Set permissions to /proc/xen/xenbus, so normal user can use xenstore-read
|
||||||
chmod 666 /proc/xen/xenbus
|
chmod 666 /proc/xen/xenbus
|
||||||
|
# Set permissions to files needed to listen at vchan
|
||||||
|
chmod 666 /proc/u2mfn /dev/xen/evtchn
|
||||||
|
|
||||||
# Set default services depending on VM type
|
# Set default services depending on VM type
|
||||||
TYPE=`$XS_READ qubes_vm_type 2> /dev/null`
|
TYPE=`$XS_READ qubes_vm_type 2> /dev/null`
|
||||||
|
Loading…
Reference in New Issue
Block a user