Using GPIO add_event_detect() in non-priviledged mode

Hi - has anyone been able to use the RPi.GPIO edge detect when not running in privileged mode?

I was able to use the GPIO fine with the following settings:

    devices:
      - "/dev/gpiomem:/dev/gpiomem"
    cap_add:
      - SYS_RAWIO

Trying to use the above with GPIO.add_event_detect fails with RuntimeError: Failed to add edge detection.

I’ve had to go to privileged mode for this to work.

hey @mhazley,
According to the source code for RPi.GPIO, adding edge detection would start a thread. You can look here

The error seems related to permissions and I believe you need to add more capabilities to the docker-compose file. Perhaps this this will help.

Let us know if it works for you,
Cheers :slight_smile:

1 Like

Thanks for the links, checked out the source and seems it fails either calling:

epoll_create
epoll_ctl
or
pthread_create

Coming up a bit blank with the capabilities required… pthread_create says:

The new thread inherits copies of the calling thread’s capability sets

So perhaps theres a capability for creating threads… I will keep reading, thanks for the sign-posts!

@mhazley,
Perhaps you could also try adding
/dev/mem:/dev/mem to devices ?

Thanks - same error.

I will release as privileged for now and then work to optimise. I’ll report back here when I work it out!

Thanks. Very grateful if you could do that. Would be helpful for other community members too.

Cheers!

As a side note,
When working with interface and running in unprivileged containers , the io.balena.features.sysfs can be a good option. It is available as from supervisor v10.8.0.

Thanks, I’ll try that, I am running 10.6.27 currently so will upgrade and try.

I have the same issue with the add_event_detect, I tried to add :

    devices:
      - "/dev/gpiomem:/dev/gpiomem"
    cap_add:
      - SYS_RAWIO

OR

    devices:
      - "/dev/gpiomem:/dev/gpiomem"
    cap_add:
      - ALL

but i have the same error : RuntimeError: Failed to add edge detection.

I will leave it as privileged mode for now… but it’s not the best.

I did some more test using strace.

When you mount

/dev/gpiomem

In strace you have a Read-only file system to /sys/class/gpio/gpio17/direction even if I should have the access.

openat(AT_FDCWD, "/sys/class/gpio/gpio17/direction", O_WRONLY) = -1 EROFS (Read-only file system)

If I try with a user that dont have the access on /sys/class/gpio/gpio17/direction I have a permission denied error.

openat(AT_FDCWD, "/sys/class/gpio/gpio17/direction", O_WRONLY) = -1 EACCES (Permission denied)

I did some research and also /sys/firmware/ seems to be empty which seems to be required by the gpio.

Not sure if a different distribution that contains the missing file /sys/firmware/ will fix the issue but I was using Ubuntu 22.04 Docker distribution.

I also tried to mount /sys/ or /sys/firmware/ but it is a docker limitation to block the mounting to /sys/firmware/ so it’s always stay empty unless you have privileged mode.