-
Notifications
You must be signed in to change notification settings - Fork 16
TIPS: Using a USB Printer with a KVM hosted Virtual Machine like QEMU KVM (Linux)
NOTE: This guide is being retained as a historical reference, but will no longer be updated. It has been superseded by the device and application-agnostic guide Rootless Write Access to USB Devices with udev Rules.
This guide has been verified with QEMU 4.2.1 on Linux 5.8.13 on 2020-10-15
There are benefits to using Virtual Machines (VMs) during the development cycle of captdriver when time-critical debugging and analysis operations are not involved. For example, preliminary testing can be performed quickly over multiple operating systems or new releases of CUPS to verify that the drivers are likely to work on the host. VMs support quick and safe operation of snapshots to quickly and completely undo changes and their effects on a virtualised operating system.
USB printers can be used with VMs hosted by KVM in Linux, but attempts to run the VM without root privileges may result in restricted functionality of the device, leading to mysterious errors and loss of device function in the VM.
These problems are caused by the system blocking write access to USB devices. For printers, this means being unable to use the device at all, a side-effect of a security policy intended to prevent rogue actors from exploiting weaknesses which may be found in USB devices.
Such problems are usually accompanied by system errors that are reported to a
terminal that is receiving messages from stderr
, such as a terminal session
that is running qemu-kvm
from a shell command line:
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/008: Permission denied
...
The message would be repeated ad nauseum.
To enable rootless write access a USB devices, a rule has to be established
under udev
. This is done by creating a plain text file in the
/etc/udev/rules.d/
directory, and filling it with rules which are written in
a declarative language.
Files must have a name that end with .rules
to be considered by udev
,
and should be prefixed with a number followed by a single hyphen, to aid
with sorting, which ultimately determines the precedence of the rules.
A rules file named 69-hp-laserjet.rules
has precedence over 99-canon-lbp.rules
In this example, a rule for a USB printer has been added to a file,
/etc/udev/rules.d/99-lbp3k-qemu-rootless.rules
, with only a single entry:
ACTION=="add",SUBSYSTEMS=="usb",ATTRS{idVendor}=="04a9",ATTRS{idProduct}=="1337",MODE="0666"
PROTIP: Please pay attention to the single equal between
MODE
and"0666"
. Under theudev
rule language,MODE
is a variable-setting operation, while the others are in fact lookup operations.
PROTIP: If the system seems to ignore the
rules
file, it may be because the number at the beginning of its name is too low. Try numbers from60
and69
inclusive.
This effectively opens up a USB device with a vendor-product ID of
04a9:1337
to write access by all users on the system. Replugging or
power-cycling the USB device may be necessary for the new rule to take
effect.
The product-vendor ID of a USB device may be obtained by running lsusb
,
as seen in the example below:
$: lsusb
...
Bus 001 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 008: ID 04a9:1337 Canon, Inc. CAPT Device
The MODE
setting in this example directly controls the permissions
of the device's file. Recall that the printer was connected on Bus 001,
as Device 008. This makes the device's corresponding file /dev/bus/usb/001/008
.
Also recall that we have set the device permission to "0666"
in udev
,
which means read and write for all users. Verify that fact by listing the
device file:
$ ls -l /dev/bus/usb/001/008
crw-rw-rw-. 1 root lp 007, 20 Mar 20 00:00 /dev/bus/usb/001/008
When the rule is removed, by commenting it out in the rules file or deleting it outright, the permissions revert to their defaults after the device is reconnected. On many recent Linux systems, this means a read-only lockdown against unprivileged users:
$ ls -l /dev/bus/usb/001/008
crw-rw-r--. 1 root lp 007, 20 Mar 20 00:00 /dev/bus/usb/001/008
PROTIP: This corresponds with a mode of 664
With root privileges, one can subvert this using chmod
, at least until the
device is reconnected...
Greg Kroah-Hartman, Kay Sievers, Dan Stekloff, et. al. udev: Linux Dynamic Device Management. Accessed 2020-03-20.
Linux Gazette. udev rules ca't [sic] auto mount my pen drive. Accessed 2020-10-15.
This 2009 letter published on The Linux Gazette offers a good explanation on how the number prefixes on names of the
rules
files should be used. The unfortunate typo in the title may prevent it from appearing in search engine results, depending on the search terms used.
Mike Szczys. How To Write Udev Rules. Accessed 2020-10-15.
Content in this wiki is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Any errors, omissions or suggestions? File an issue and apply the wiki
label.
Bookmarks
Unofficial Introduction to CAPT (Executive Summary)
Rootless Write Access To USB Devices
Other Canon Printer-Related Projects
SPECS: 0xA1A1
Command and Response Format
Search for pages starting with
-
SPECS
for notes on the operation of the CAPT data formats and communications protocol -
TESTING
for guidelines on testing Captdriver -
TIPS
for potentially helpful information on studying the project or the CAPT format-protocol