[SOLVED] Pass USB Device to LXC

xadox

Well-Known Member
Aug 21, 2019
44
3
48
Hello All.
I am on Proxmox V7.3-6. And I want to pass a USB Device on an unprivileged Ubuntu20.04.5 LTS LXC.
The USB device is a USB adapter to read my SmartMeter:

root@proxmox:~# lsusb Bus 003 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge

I followed several instructions on the net. Unfortunately this does not work properly.
The most promising seems to be this tutorial:

https://www.schreiners-it.de/proxmox/usb-geraet-in-lxc-container-unter-proxmox-7-1/

But it starts directly with the fact that no ttyACM0 is created for me. I only have ttyUSB0.
ttyUSB0 is always present regardless of whether the following command is used in one of the LXC configs:

lxc.mount.entry: /dev/bus/usb/003/006 dev/bus/usb/ none bind,optional,create=file

Then sometimes lxc.cgroup2.devices.allow is used and sometimes lxc.cgroup.devices.allow.

Any tips would be greatly appreciated.
 
Hmm, have you tried create=dir instead of create=file already? My gut tells me create=file should be correct, but it's worth a try nevertheless.

Another thing I have noticed: Why is there a trailing / in dev/bus/usb/? Skimming the LXC docs, I can't really find anything regarding the actual path specification, so I'm not sure a trailing slash actually makes a difference or not; but maybe try something like dev/bus/usb/003/006 instead. Just for good measure.

So, the full mount entries I'd suggest you try are:

1.
lxc.mount.entry: /dev/bus/usb/003/006 dev/bus/usb/003/006 none bind,optional,create=file

2.
lxc.mount.entry: /dev/bus/usb/003/006 dev/bus/usb/003/006 none bind,optional,create=dir

Also, make sure your device has the required permissions by doing a chmod a+rw /dev/bus/usd/003/006 beforehand.
 
I have tested a bit more. You are totaly right.
The command should be without the ending "/":

lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/bus/usb/003/002 dev/bus/usb none bind,optional,create=file

The first "/dev/bus/usb/003/002" is the mount point on the host. The Second one "dev/bus/usb" is the mount target on the lxc.
This creates the file "dev/bus/usb" on the lxc.

root@iob:/dev/bus# ls -la crw-rw-rw- 1 nobody nogroup 189, 257 Mar 14 14:51 usb

Thats working. But if I read the tutorials correctly there should be now a ttyACM0 device created on the host.
And for me thats not working. Instead I am using dev/ttyUSB0:

lxc.cgroup2.devices.allow: c 188:* rwm lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file

And with that I am able to use the USB device in the lxc.
 
The Same worked with me.
Unfortunately when I Hotswap the USB Device. I loose the connection an the rights.
I receive: ls -al /dev/ttyUSB0
c--------- 0 nobody nogroup 188, 0 Aug 6 19:58 /dev/ttyUSB0

one I restart the LXC, everything is working again.

Anyone an Idea how to get the permissions Hotswap-compatible?

Rgds
Malte
 
The Same worked with me.
Unfortunately when I Hotswap the USB Device. I loose the connection an the rights.
I receive: ls -al /dev/ttyUSB0
c--------- 0 nobody nogroup 188, 0 Aug 6 19:58 /dev/ttyUSB0

one I restart the LXC, everything is working again.

Anyone an Idea how to get the permissions Hotswap-compatible?

Rgds
Malte
Hi all.
I have the same problem afrter re-plug device (in 8.1.10). Is there any progress? Some settings or workaround?
Thx
 
Work-around: add a udev rule to reboot the container on the USB plug-in event?
I've hit a similar snag (though in my case I don't need to reboot the container, I need to reset the permissions every time the device is plugged back in). Could you point me to guide on how you write such a udev rule? I have that creates a symlink to a permanent name, but I've not had luck finding a writeup on how you would do other commands via the rule.
 
Today I managed to get my USB smart card (ACR39U) to work in an unprivileged LXC container. My lsusb output was:

Code:
Bus 001 Device 007: ID 072f:b100 Advanced Card Systems, Ltd ACR39U

First I added the device /dev/bus/usb/001/007 to the container in the web UI and everything worked. Unfortunately on reboot/replug the ID changed, so I followed leesteken's suggestion to add a udev rule. I created /etc/udev/rules.d/10-local.rules with the following contents:

C-like:
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="072f", ATTRS{idProduct}=="b100", ENV{DEVNAME}!="", RUN+="/etc/udev/rules.d/smartcard.sh $devnode"

The smartcard.sh script looks like this:

Bash:
#!/bin/bash
cd "$(dirname "$0")"

echo "[$(date)] smart card add" >> smartcard.log

CONTAINER_ID=103
CONFIG_FILE=/etc/pve/lxc/$CONTAINER_ID.conf

# Extract the current path from the config file
CURRENT_PATH=$(grep '^dev0:' "$CONFIG_FILE" | awk -F': ' '{print $2}')

# Compare the extracted path with $DEVNAME
if [ "$CURRENT_PATH" != "$1" ]; then
  # Replace the path in the config file
  sed -i "s|^dev0: .*|dev0: $1|" "$CONFIG_FILE"
  echo "Updated dev0 path in $CONFIG_FILE from $CURRENT_PATH to $1." >> smartcard.log
  CONTAINER_STATE=$(lxc-info --name $CONTAINER_ID --state --no-humanize)
  if [ "$CONTAINER_STATE" != "RUNNING" ]; then
    nohup lxc-start --name $CONTAINER_ID >> smartcard.log 2>&1 &
  else
    nohup lxc-stop --name $CONTAINER_ID --reboot >> smartcard.log 2>&1 &
  fi
else
  echo "The dev0 path is already set to $1" >> smartcard.log
fi

You can reload the rules without reboot using: udevadm control --reload-rules
 
Last edited:
Why not mount the device via serial id? This won't change upon reboot/replug..
ls -l /dev/serial/by-id to get the ID.
 
Why not mount the device via serial id? This won't change upon reboot/replug..
ls -l /dev/serial/by-id to get the ID.
On my Proxmox host this folder does not exist. I tried creating a symbolic link using udev rules and the device showed up in the container when running lsusb. However, the smart card driver did not recognize it and I was unable to connect to it. Passing the /dev/usb/ device worked, so I just powered through and got it to work across reboots and replugs...
 
  • Like
Reactions: martin-g-it
The
Code:
/dev/serial/by-id
solution is the cleanest I think. Can anyone tell me how to configure it properly?
 
Last edited:
1. run
Code:
ls -l /dev/serial/by-id
on the Proxmox host

Output will be something like:
Code:
root@pve101:~# ls -l /dev/serial/by-id
total 0
lrwxrwxrwx 1 root root 13 Sep  9 10:54 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 root root 13 Sep 22 18:46 usb-FTDI_FT230X_Basic_UART_D307ORET-if00-port0 -> ../../ttyUSB1

2. Go via the PVE manager to your LXC setup, choose Resources > Add > Device Passthrough
3. Enter the Device Path like
Code:
/dev/serial/by-id/<device id>
In my example /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 for the first device, /dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_D307ORET-if00-port0 for the second one
 
1. run
Code:
ls -l /dev/serial/by-id
on the Proxmox host

Output will be something like:
Code:
root@pve101:~# ls -l /dev/serial/by-id
total 0
lrwxrwxrwx 1 root root 13 Sep  9 10:54 usb-1a86_USB_Serial-if00-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 root root 13 Sep 22 18:46 usb-FTDI_FT230X_Basic_UART_D307ORET-if00-port0 -> ../../ttyUSB1

2. Go via the PVE manager to your LXC setup, choose Resources > Add > Device Passthrough
3. Enter the Device Path like
Code:
/dev/serial/by-id/<device id>
In my example /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 for the first device, /dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_D307ORET-if00-port0 for the second one
That's how I do it at the moment, but that's not good because as soon as the device is disconnected, the CT no longer starts ;-(
 

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!