USB Passthrough is the concept of passing a USB device that is plugged into the host server to a guest. This post will detail how to make the USB device available in an OpenVZ container.
The first step is usually the easiest; take your USB device and plug it into your Proxmox host. Wait a few moments for it to be recognised and then run the below command to identify which bus the device is plugged into.
The below shows an example output of the command.
Bus 002 Device 003: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The device I’m after for this example is on Bus 002 Device 003 which I identified from the name. Yours will more than likely be different
Often the names of the devices mean little and you’ll then need to compare the output of lsusb before and after plugging the device in. For example, run the below command with the device unplugged.
Then plug the device in and run the following command:
Finally compare the two command outputs and identify the difference:
diff /tmp/before /tmp/after
Once you had identified the row in the output of lsusb it’s time to make a note of the usb bus it’s attached to. As above, mine is 002:003, which are the details I’ll need in a moment.
The way Linux accesses most IO devices is through the /dev/ mounts, and USB devices are no different. You can navigate to the USB bus in /dev/bus/ by following the bus address.
As you can see, the above path starts with /dev/bus/usb/ and follows with the bus address in the lsusb command. We’ll need this to pass to our OpenVZ container in just a moment so make a note of it.
One final check we can do to make sure we have the correct bus address is to use the above path with lsusb -D to get a more detailed output of the device. This will usually contain a manufacture ID and other information that may help us identify the device we need. I’ll spare you the output, but an example is below:
lsusb -D /dev/bus/usb/002/003
The next step is to tell the OpenVZ container all about the USB devices bus location. Using vzctl set we can specify the OpenVZ container ID, USB device and access level.
Before continuing, make sure that the container is turned off.
The command to run on the turned off container is below. Make sure to substitute the bracketed values as follows:
- [VMID] is the ID of the openVZ container that the USB device will be passed to.
- [BUS_PATH] is the path to the USB device that we discovered earlier. Be sure to drop the /dev/ prefix.
vzctl set [VMID] --devnode [BUS_PATH]:rw --save
vzctl set 107 --devnode bus/usb/002/003:rw --save
And there it is, turn on the container and point your application to /dev/bus/usb/002/003 and you should be up and running.