[SOLVED] PVE 6.4 usb pass through in lxc container

sintei

Member
Jul 29, 2020
10
3
8
46
Hello,

I'm at my wits end.
I want to pass through a USB device (for instance my UPS is connected via USB and I have other devices like z-wave and zigbee as well).

This is what I do (and is according to proxmox manual and all tutorials out there):
Create a LXC container (debian 10 or ubuntu 20 doesnt matter).

In my proxmox shell to see my devices:
# lsusb
Bus 005 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS

and:
# ls -al /dev/bus/usb/005/002
crw-rw-r-- 1 root root 189, 513 Jul 29 19:45 /dev/bus/usb/005/002

I go to my LXC with winscp and edit the file corresponding to my LXC ID:
/etc/pve/nodes/pve/lxc/112.conf

I add the following and save it:
lxc.cgroup.devices.allow: c 189:* rwm
lxc.mount.entry: /dev/bus/usb/005/002 dev/bus/usb/005/002 none bind,optional,create=file

I create a udev rule:
SUBSYSTEM=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", SYMLINK+="ups"

Restart of proxmox.

Start LXC and do lsusb in LXC shell:
Bus 005 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS

I would think that the device is created in /dev/ups in my LXC or /dev/usb.
But there is only:
# ls /dev
bus console core fd full hugepages initctl log lxc mqueue null ptmx pts random shm stderr stdin stdout tty tty1 tty2 urandom zero

If I do this in proxmox shell then I can see usb. But it is empty
ls -l /dev/usb
total 0
crw------- 1 root root 180, 0 Jul 29 20:36 hiddev0

I'm sure it is something simple like permissions or something.
I'm not a Linux user from start.. but I am logged in as root in both proxmox shell as in the LXC.

Any ideas?
 
Last edited:
Hey, my udev rule for a USB device looks like this


SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idProduct}=="7523", ATTRS{idVendor}=="1a86", SYMLINK+="jeelink", MODE="0666", GROUP="dialout"


MODE and GROUP might help

Greetings Marcel
 
Hey, my udev rule for a USB device looks like this


SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idProduct}=="7523", ATTRS{idVendor}=="1a86", SYMLINK+="jeelink", MODE="0666", GROUP="dialout"


MODE and GROUP might help

Greetings Marcel

Thanks for replying.
I tried that (as well) but did it again. I noticed you had SUBSYSTEMS with an S in the end so I thought that would be it.
But unfortunately no.

I can add the usb easily to VMs via "add hardware" but not in LXCs. Its driving me mad!
 
I have tried several things, clean reboot of both the LXC and proxmox.
And now.. it started working.
And I do not know WHY it started working.

For future reference.
my LXC configuration added:
lxc.cgroup.devices.allow: c 166:* rwm
lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file

And my udev rule is:
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="ttyACM0" , MODE="0666", GROUP="dialout"

For the ones that noticed, I have 2 USB devices. This one I'm referencing here is another USB stick.

to be continued!
 
I had the previous post written while I was trying different stuff but not posted it yet. Since it was true at the time I wrote it, I posted it now.

However.. I did not get the other stick to work.
After MANY hours I managed to work things out.
This stick creates in proxmox a folder "usb" and in that folder it creates a hiddev0 file.
In /dev/ it creates a hidraw0 device.

I created a udevrule for it:
SUBSYSTEMS=="usb", KERNEL=="hiddev*", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", SYMLINK+="ups0", MODE="0666", OWNER="root", GROUP="dialout"

And in my LXC container config I added:
lxc.cgroup.devices.allow: c 180:* rwm
lxc.mount.entry: /dev/ups0 dev/ups0 none bind,optional,create=file


Note/instructions to whomever finds this post!
Remove the USB stick
In Proxmox shell write:
ls -al /dev
You will compare this result to a similar one so copy the result to for instance excel and format it text to columns
Connect your USB stick
ls -al /dev
Copy paste into excel (if that is your choice)
Now compare and see what is new.
if you have a new hidraw row and also maybe a USB folder then continue. Otherwise see previous post
write the bellow if you have a new usb folder with a hiddev file. Change the below with your number (mine was 0)
udevadm info --attribute-walk --name=/dev/usb/hiddev0
You will now see Product ID, Vendor etc.
go to /etc/udec/rules.d
Create a rule file (for example mine is named "50-myusb.rules")
In that rule file, add the below but change according to the output you got above:
SUBSYSTEMS=="usb", KERNEL=="hiddev*", ATTRS{idVendor}=="0764", ATTRS{idProduct}=="0501", SYMLINK+="ups0", MODE="0666", OWNER="root", GROUP="dialout"
Now issue this command to restart and trigger udev rule:
udevadm control --reload-rules && udevadm trigger
Within a minute or so, you should now see the symlink ups0 with the owner and group correct if you type
ls -al /dev
If not, restart pproxmox

Go to your container and edit the config which is located in (change the *** to the ID of your container:
(Note: I think the container has to be privileged, not sure and I'm to tired to test now)
/etc/pve/nodes/pve/lxc/***.conf
Add the below:
lxc.cgroup.devices.allow: c 180:* rwm
lxc.mount.entry: /dev/ups0 dev/ups0 none bind,optional,create=file

The number 180 I got from writing in proxmox shell:
ls -al /dev/usb.
It is the "MAJOR" of the USB

In the udevfile i created a symlink called ups0, you can create with other name, for instance zwave0 etc.
But if you change it, you have to change the container config to match.

This has been an experience I'd rather be without. But luckily google fu + some basic knowledge made it happen.
 
thanks, this is very helpful, but is there also an way to bind the usb by ID, like: /dev/serial/by-id?
 
thanks, this is very helpful, but is there also an way to bind the usb by ID, like: /dev/serial/by-id?
I'm uncertain that I understand what you mean. If it is a USB unit, the IDs will be under USB. And from there you assign it by Product ID or Vendor ID (or off your own choosing).
 
the Bus and Device can change when the USB device installed in another usb port or another usb device is changed.
The id does not change.
So if i use the bus and device together with product ID and Vendor and the bus and/or device changes i need to change the
Code:
lxc.mount.entry: /dev/bus/usb/005/002 dev/bus/usb/005/002 none bind,optional,create=file
part in the .conf file. Or am I missing something?
 
the Bus and Device can change when the USB device installed in another usb port or another usb device is changed.
The id does not change.
So if i use the bus and device together with product ID and Vendor and the bus and/or device changes i need to change the
Code:
lxc.mount.entry: /dev/bus/usb/005/002 dev/bus/usb/005/002 none bind,optional,create=file
part in the .conf file. Or am I missing something?
In the "ID of container".conf file, you add I think to whatever you want. But you can add the "highest" folder to allow all the below ones.
And in Proxmox rules, you assign then the USB according to product ID etc.
This way it doesn't matter if you change port.
But if you have more that one of the same USB things, you will have to differentiate with something else.

I do not know if I answer your question.
I'm also very new to this so maybe someone else can chime in if they know the answer.
Maybe post a new thread as it could attract more attention if you describe what you have done and what you need to be done.
Good luck!
 
For future ref:
It looks like the config in the lxc conf file should be:
lxc.cgroup2.devices.allow ...
(so not cgroup, but cgroup2)
 
Thank you for the clarification! Im still using 6.4. Will see if I can change the topic to reflect 6.4.
Use cgroup2 when using PVE 7.0 or later/higher and use cgroup if you are on a version before 7.0.
If you want to passthrough a device to a unprivileged container, you probably want to map the group inside the container to the same group on the host (like map video inside the container to video on the host), which usually have different numeric IDs. Most likely, you don't want to pass the /dev/usb/... path but the /dev/dvb/ for a TV-tuner, /dev/drm/ for a GPU, etc. The container usually won't create such dev-nodes itself, but instead use the dev-nodes that you pass using cgroup(2).
 
  • Like
Reactions: sintei

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!