I've been playing around with VirtualBox in 9.3 and decided to get a USB device working in a VirtualBox guest. There doesn't appear to be comprehensive guide to getting USB passthrough working so I've decided to share this guide.
This how-to demonstrates using a USB Printer but this may work for other USB devices.
Note: I assume you already know how to use the shell and basic jail commands such as jls and jexec.
With your vbox jail running open a shell to your vbox jail and edit (or create) /etc/rc.local
This brute force method simply makes all your current USB devices and printers accessable to the VirtualBox user. You may test this by restarting your vbox jail - after startup these paths should be owned by the 'vbox' group and group writable.
After doing this you can open up the phpVirtualBox web console and open the settings on any guest machine that you wish to test USB on.
Open Settings -> USB and Enable USB Controller. Don't enable USB 2.0 - it doesn't appear to work currently.
In USB Device Filters click the [+] and the drop-down list should show your connected USB devices and allow you to add any device to this guest - if the list is empty then something may be wrong with the permissions you set previously. Start your guest, the selected USB Device Filters should now be accessible from within the guest machine.
Now this is all fine for USB devices that remain connected and powered on, but what about devices that are attached or powered on after the vbox jail has started? For this we need to use devd.
USB attach detection
These following instructions were inspired by the (now defunct) nas4free USB-passthrough instructions.
All these commands are run in the FreeNAS root shell, outside of any jails.
List the USB devices
In this example we are going to add detection for this HL-2140 printer connected to ugen1.4
Take note of idVendor and idProduct above.
Make the FreeNAS boot device writable so we can update the config files
Create the following config file with your choice of filename, for example 'usbprinter.conf'. Put in your own codes you got for idVendor and idProduct above.
This will chroot into your jail named 'virtualbox' and modify the USB device permissions any time this specific device is plugged in.
Clean up by mounting the boot device read-only again
You can test this without rebooting FreeNAS by copying the config to the live system and restarting devd:
This how-to demonstrates using a USB Printer but this may work for other USB devices.
Note: I assume you already know how to use the shell and basic jail commands such as jls and jexec.
With your vbox jail running open a shell to your vbox jail and edit (or create) /etc/rc.local
Code:
chmod -R 0770 /dev/usb* chmod -R 0770 /dev/ugen* chmod -R 0770 /dev/unlpt* chmod -R 0770 /dev/ulpt* chown -R :vbox /dev/ugen* chown -R :vbox /dev/usb* chown -R :vbox /dev/unlpt* chown -R :vbox /dev/ulpt*
This brute force method simply makes all your current USB devices and printers accessable to the VirtualBox user. You may test this by restarting your vbox jail - after startup these paths should be owned by the 'vbox' group and group writable.
After doing this you can open up the phpVirtualBox web console and open the settings on any guest machine that you wish to test USB on.
Open Settings -> USB and Enable USB Controller. Don't enable USB 2.0 - it doesn't appear to work currently.
In USB Device Filters click the [+] and the drop-down list should show your connected USB devices and allow you to add any device to this guest - if the list is empty then something may be wrong with the permissions you set previously. Start your guest, the selected USB Device Filters should now be accessible from within the guest machine.
Now this is all fine for USB devices that remain connected and powered on, but what about devices that are attached or powered on after the vbox jail has started? For this we need to use devd.
USB attach detection
These following instructions were inspired by the (now defunct) nas4free USB-passthrough instructions.
All these commands are run in the FreeNAS root shell, outside of any jails.
List the USB devices
Code:
# usbconfig ugen0.1: <EHCI root HUB Intel> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen1.1: <EHCI root HUB Intel> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen0.2: <product 0x8008 vendor 0x8087> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen1.2: <product 0x8000 vendor 0x8087> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen1.4: <HL-2140 series Brother> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (2mA)
In this example we are going to add detection for this HL-2140 printer connected to ugen1.4
Code:
# usbconfig -d ugen1.4 dump_device_desc ugen1.4: <HL-2140 series Brother> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (2mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x0000 bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x04f9 idProduct = 0x0033 bcdDevice = 0x0100 iManufacturer = 0x0001 <Brother> iProduct = 0x0002 <HL-2140 series> iSerialNumber = 0x0003 <L8J158092> bNumConfigurations = 0x0001
Take note of idVendor and idProduct above.
Make the FreeNAS boot device writable so we can update the config files
Code:
# mount -uw /
Create the following config file with your choice of filename, for example 'usbprinter.conf'. Put in your own codes you got for idVendor and idProduct above.
Code:
# vi /conf/base/etc/devd/usbprinter.conf attach 101 { # USB Printer HL-2140 match "vendor" "0x04f9"; match "product" "0x0033"; action "/usr/local/bin/warden chroot virtualbox '/bin/chmod 0770 /dev/usb/'$port'.'$devaddr'.*' && /usr/local/bin/warden chroot virtualbox '/usr/sbin/chown :vbox /dev/usb/'$port'.'$devaddr'.*'"; };
This will chroot into your jail named 'virtualbox' and modify the USB device permissions any time this specific device is plugged in.
Clean up by mounting the boot device read-only again
Code:
# mount -ur /
You can test this without rebooting FreeNAS by copying the config to the live system and restarting devd:
Code:
# cp /conf/base/etc/devd/usbprinter.conf /etc/devd/ # /etc/rc.d/devd restart