USB re-connect fails from container

The USB is recognised at startup. But when un-plugged and re-plugged, then the USB is no longer recognised.

Whenever I run the my_service locally, then USB unplug / re-plug works perfectly fine. (I am using the usb-detection library as well as the Serialport.io library. And it can do port recognition after un-plug / re-plug just fine.

It is only inside its own docker container under balenaOS that the USB can never re-connect. Why is that ?

I followed all hints from this earlier post, but without success.

My docker-compose.yml looks like this:

version: "2.1"
services:
    my_service:
        build: my_service_folder
        restart: always
        privileged: true
    my_main_application:
        build: .
        shm_size: "1gb"
        labels:
            io.balena.features.dbus: "1"
        restart: always
        privileged: true
        environment:
            - DISPLAY=:0
            - CURSOR=false
            - PULSE_SERVER=tcp:audio:4317
            - PULSE_SINK=alsa_output.hda-intel.hdmi-stereo
            - DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

I had also tried with the following change - but without success…

    my_service:
        build: my_service_folder
        restart: always
        privileged: true
        environment:
            - UDEV=1
        devices:
            - '/dev:/dev'

Inside the Dockerfile.template of my_service, I placed:

 ENV UDEV=1

But unfortunately, the USB re-plug does not work.

What am I missing ??

I am using an AMD64

FROM balenalib/%%BALENA_MACHINE_NAME%%-node:16

Here is the entire Dockerfile.template of my_service container:

FROM balenalib/%%BALENA_MACHINE_NAME%%-node:16

# installing preconditions to build usb-detection from source
RUN sudo apt-get update -y
RUN sudo apt-get install -y python3
RUN sudo apt-get install -y build-essential
RUN sudo apt-get install -y libudev-dev

# Defines our working directory in container
WORKDIR /usr/src/app

# Copies the package.json first for better cache on later pushes
COPY package.json yarn.lock ./

# This will copy all files in our root to the working directory in the container
COPY . ./

RUN JOBS=MAX yarn install --frozen-lockfile

# Build dist
RUN yarn run build

# Enable udevd so that plugged dynamic hardware devices show up in our container.
ENV UDEV=1

# Increase to 2 GB
RUN export NODE_OPTIONS="--max-old-space-size=2048"

# server.js will run when container starts up on the device
CMD ["yarn", "start"]

At first glance this looks all correct. Does the lsusb command show you a change in the USB devices after hot-plugging your USB stick?

If lsusb can show the hot-plugged USB device, then the actual reconnection works fine.
In that case the problem might lie with the library you are using to monitor USB devices - maybe similar to the issue I’m having with libudev for monitoring devices: libudev cannot monitor udev events inside container

1 Like

Sorry for my long response-time and thank you very much for your helpful hint.

The cmd lsusb in the service-container terminal indeed always brought me the correct USB-devices. And therefore, for a long time, I also suspected the usb-detection library to be the root cause of non-working.

However, it turned out that the library is just fine and that the following brought the solution:

Next to privileged: true and environment: - UDEV=1, also make sure to set the network_mode: host inside the docker-compose.yml file of your service-definition.

From the Balena documentation we learn network_mode: host does the following:

Setting network_mode to host allows the container to share the same network namespace as the host OS.

When this is set, any ports exposed on the container will be exposed locally on the device.

This is necessary for features such as bluetooth.

And turns out, not only for bluetooth but also for services that need USB-detection.

Remains the question how to achieve a working usb-detection without network_mode: host setting on the multicontainer service - especially for those projects that are not able to set their services in the same namespace as host ???

As long as I run the bridge-network mode, then the privileged: true and environment: - UDEV=1 is definitively not enough ! Any idea what to do in order to recognize usb-hotplug events ??? (after months, pretty desperate about this)

The solution is described here.

You have to restart the UDEV as bversluijs describes in his solution.

1 Like