Mounting Pluggable USB Device in Docker

Hello,

I’m not sure if this question was already asked, if so please point me to the answer. A quick search did not provide any meaningful answers on my side.

This question is about Torizon OS / the concept of developing embedded software in containers.
Let’s assume the requirement is that the user can plug in a printer in the end-device or leave the printer away. The application, on Torizon running inside a docker-container does only see the printer if it was plugged in on boot. If the container is started and the printer is plugged in after start it never appears in docker container.

I tried mounting the whole /dev as a volume as well as a specific device (docker run -d and -v)

Solutions I was thinking of:

  1. privileged
  • With that it works, but for obvious reasons we don’t want to go with this solution.
  1. udev to the rescue
  • Use a udev rule and restart the container when the printer is plugged in.
  • The application would be killed ungraceful and restarted.
  • This needs to sit in the torizon-core base OS (mixing application/hardware/kernel-stuff).
  1. device-cgroup-rule
  • I found this hint on your “How to Use GPIO on Torizon OS” article
  • On docker documentation they talk about having a udev rule with executing ‘mknod’ inside the container
  • docker run | Docker Docs
  • Having still the need for udev for ‘mknod’ means still a workaround to me.

So back to the question: What way do you recomment of mounting a pluggable USB device into a container. I want to be able to handle it from my application if it is there or not, so that I don’t have to mix application development with the base Torizon OS.

Thanks in advnace for your answer!
Philippe

Edit: We tried out 3. and it worked! However: Is there really no simpler solution? Especially one that does not need udev to be involved :see_no_evil:. Maybe podman would have a solution :slight_smile: ?

We added in docker-compose.yml:

device_cgroup_rules:
      - 'c 180:* rwm'

Then after connecting the USB printer:

docker exec torizon-climateprodtestapp-debug-1 mkdir /dev/usb
docker exec torizon-climateprodtestapp-debug-1 mknod /dev/usb/lp0 c 180 0
docker exec torizon-climateprodtestapp-debug-1 chown root:lp /dev/usb/lp0
docker exec torizon-climateprodtestapp-debug-1 chmod 660 /dev/usb/lp0

Greetings @philschenker,

Alright, just to make sure I understand. In generic terms you have a USB device that may or may not be attached when the container starts. Either way you’d want it to be recognized in the container. Furthermore, this USB device can be removed or attached at any time, is that more or less correct?

One thing you could try is setting up a volume/bind-mount with the “bind-propagation” property as described here: Configuring docker dynamic USB memory access with --mount option in VS Code Torizon Extension

More info on this property from Docker: Bind mounts | Docker Docs

I’ve used this before with a USB drive and it allowed me to access the contents of my USB drive even when plugging it in, after my container has started. Perhaps it would help similarly for USB devices in general.

Best Regards,
Jeremias

Hi Jeremias,

You understood exactly what I meant. Your hint with the bind-mount is very good! thank you!
We now went with the tedious udev workaround as we needed something that works.

I will for sure try this out and if I don’t forget report back if it worked and how.

Best Regards,
Philippe

Glad I was able to provide a hint. If you get a chance to try this let me know the results. As I said before I only really used this method with mountable USB drives before, so I’m unsure if it’s generally applicable to all USB devices.

Best Regards,
Jeremias