[teilweise gelöst] Docker, Homegear-nightly: gpio-Zugriff verweigert und Thread-Probleme

Hallo allerseits,

ich hab’ da mal 2 Fragen an die, die Homegear auf Raspi in Docker verwenden, denn ich komme einfach nicht mehr weiter. Ich will nämlich meine etliche Jahre alte Installation auf den aktuellen Stand bringen.

Was ich nutze:

  • Raspi 3 B,
  • frisches und neues Raspios (Bullseye lite server image, 32bit),
  • aktuelle Version von Docker (20.10.21),
  • angetackert an die Stiftleise ein CC1101-Module (läuft seit etlichen Jahren zuverlässig),
  • Homegear-Konfiguration neu aufgesetzt und bisher nur minimal definiert, was für Homematic-BidCOS nötig ist.

Die Fehler bei Start des Homegear-Containers:
Thread-Fehler:

11/04/22 16:18:59.448 Critical: Can't start more threads. Thread limit reached (218 threads).
11/04/22 16:18:59.448 Critical: Can't start more threads. Thread limit reached (218 threads).

gpio-Zugriffsfehler:

11/04/22 16:19:21.134 Could not write to direction file (/sys/class/gpio/gpio25/direction) of GPIO with index 1: Permission denied
11/04/22 16:19:21.134 Could not write to edge file (/sys/class/gpio/gpio25/edge) of GPIO with index 1: Permission denied
11/04/22 16:19:21.135 Module HomeMatic BidCoS: TI CC110X "My-CC1101": Error in file PhysicalInterfaces/TICC1100.cpp line 849 in function void BidCoS::TICC1100::initDevice(): Failed to open GPIO value file "/sys/class/gpio/gpio25/value": Permission denied

Ich habe alles Mögliche zu (beiden) Fehlern in den Foren gelesen und ausprobiert, bisher ohne jeden Erfolg.

Hier sind die wichtigsten Raspi-Konfigurationen, die eine Rolle spielen können:

/etc/passwd (auf dem docker-Host):
homegear:x:114:114::/home/homegear:/usr/sbin/nologin

/etc/group (auf dem docker-Host):

spi:x:999:pi,homegear
gpio:x:997:pi,homegear
homegear:x:114:

Von den Konfigurationsdateien, die zu Homegear gehören, wurden nur die .conf-Dateien in /etc/homegear/families angepasst, und zwar wurden zunächst alle Family-Module ausgeschaltet, die ich nicht brauche. Dann bleibt noch übrig:

/etc/homegear/families/homematicbidcos.conf (Pfad innerhalb des Containers):

## The device family this interface is for
[TI CC1101 Module]

id = My-CC1101
default = true
deviceType = cc1100
device = /dev/spidev0.0
responseDelay = 100
interruptPin = 2
gpio1 = 25

(Das ist auch genau die Konfig, die ich schon lange auf dem “alten” Raspi verwende, auf dem Homegear direkt installiert ist.)

Schließlich ist hier noch der Aufruf zum Starten des Containers:

docker \
    run --rm -d \
    -v /docker/homegear-data/etc:/etc/homegear:Z \
    -v /docker/homegear-data/lib:/var/lib/homegear:Z \
    -v /docker/homegear-data/log:/var/log/homegear:Z \
    -v /sys:/sys:rw \
    --device=/dev/spidev0.0 \
    --device /dev/gpiomem \
    --privileged \
    -e TZ=Europe/Berlin \
    -e HOST_USER_ID=$(id -u homegear) -e HOST_USER_GID=$(id -g homegear) \
    -p 18080:80 -p 18443:443 -p 2001:2001 -p 2002:2002 -p 2003:2003 \
    --hostname homegear \
    --name homegear \
    homegear/homegear:nightly

Der Container läuft dann auch (wie es sein soll) unter homegear:homegear.

Ich habe in /boot/cmdline.txt auch mal versucht,
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
einzuschalten, was aber am Verhalten nichts geändert hat. Diese Konfig-Zeile scheint ja optional zu sein.

So, das wäre das Problem… Jede Hilfe ist sehr willkommen! Wobei das Thread-Problem ggf. auch durch Heruntersetzen der Thread-Zahlen in der Homegear-main.conf zu beseitigen wäre (ich verwende weder Skripte, noch Node-Blue, sondern OpenHAB für Logik und UI). Aber was ist das Problem beim Zugriff auf die gpio-Pins???

'n spannenden Abend noch,
HomeSweetHome

Bei mir hat das Auskommentieren der gpio Line geholfen: 5. Configuration — Homegear HomeMatic BidCoS Manual 0.8 documentation

Ja, das habe ich auch gemacht – bei der direkten Installation von Homegear auf dem Host. Bei einem Docker-Container ist das eine weniger gute Idee, weil man damit Sicherheitseinschränkungen umgeht, denn damit würden auch andere Container-Apps (möglicherweise unnötig) Zugriff auf die gpio Pins erhalten.

Außerdem ist das eigentlich kein Fix des zugrunde liegenden Problems, sondern mehr eine Umgehung.

Aber inzwischen habe ich die eigentliche Ursache des Problems herausgefunden, mehr dazu in einem eigenenen Post demnächst.

HomeSweetHome

1 Like

Hallo allerseits,

hier ist die angekündigte Analyse des Problems gpio-Zugriffsfehler innerhalb des Docker-Containers:

Das Problem liegt in der Datei /etc/group innerhalb des Docker-Containers! Diese sieht nämlich so aus:

root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:homegear
fax:x:21:
voice:x:22:
cdrom:x:24:
floppy:x:25:
tape:x:26:
sudo:x:27:
audio:x:29:
dip:x:30:
www-data:x:33:
backup:x:34:
operator:x:37:
list:x:38:
irc:x:39:
src:x:40:
gnats:x:41:
shadow:x:42:
utmp:x:43:
video:x:44:
sasl:x:45:
plugdev:x:46:
staff:x:50:
games:x:60:
users:x:100:
nogroup:x:65534:
messagebus:x:101:
homegear:x:114:

…und zwar, nachdem im Container-Start-Skript start.sh bereits die User-ID und die Group-ID für den User “homegear” korrekt gesetzt hat.

Es fehlen die Gruppen, die für den (unprivilierten) Zugriff auf die gpio- und SPI-devices benötigt werden UND die in der /etc/group auf dem Host-System definiert sind. Diese werden also nicht an den Docker-Container weitergereicht. Es fehlen (in der “frischen” Standard-Installation von RaspiOS):

Ich denke, man wird dann auch das --privileged beim Container-Start los (habe ich bisher nicht getestet).

Lösungsmöglichkeiten:

  • Man “überschreibe” die /etc/group im Container durch eine Version des Hosts beim Starten des Containers etwa so: -v /etc/group:/etc/group. Halte ich aber einen nicht so schönen Hack, weil das auch schlechte Nebeneffekte geben kann.
  • Man reiche die Gruppen-Definitionen per Environement-Variablen an den Container weiter, der “seine” /etc/group-Datei im Start-Skript entsprechend ergänzt. Halte ich für eine sinnvolle Methode, aber man muss start.sh im Container anpassen… Wäre auch geeignet, um weitere evtl. benötigte Gruppen durchzureichen.
  • Oder man “fixt” die im Container enthaltene /etc/group-Datei (wo und wie wird die eigentlich zusammengebaut? Und wieso fehlen diese Gruppen denn überhaupt?).
  • Oder fällt jemandem noch was Besseres ein??

Vielleicht gibt es dazu auch eine Idee/Meinung von @sathya.

So, jetzt muss ich nur noch verstehen, wie ich diese blöden Thread-Meldungen weg bekomme… Das reine Heruntersetzen der gestarteten Threads in der main.conf auf die früheren Default-Werte hat bisher nicht ausgereicht.

Hoffe, das Ganze hilft denjenigen, die eigene Installationen betreiben…

'n fröhlichen Herbst noch, winter is coming :cold_face:
HomeSweetHome

Ich bin ja noch die “Bestätigung” für den Fix des gpio-Zugriffsfehlers schuldig:

Mit dieser Modifikation des im Docker-Image enthaltenen Scriptes start.sh klappt es (und ja, es ist ein “dirty quick fix”):

## fix gpio- and spi-groups for Raspi, set priority limit...
echo "spi:x:999:homegear" >> /etc/group
echo "gpio:x:997:homegear" >> /etc/group
ulimit -r 100

Das kann man irgendwo am Anfang des Scriptes einfügen, ich habe das nach USER- und USER_GID-Feststellung gemacht.
Beim Starten des Containers kann dann das --privileged entfallen. Und man muss natürlich dem Container das neue Start-Script bekannt geben, was so geht:

docker \
   run --rm -d \
    -v /docker/homegear-data/etc:/etc/homegear:Z\
    -v /docker/homegear-data/lib:/var/lib/homegear:Z\
    -v /docker/homegear-data/log:/var/log/homegear:Z\
    -v /sys:/sys:rw\
    --entrypoint /bin/bash\
    --device=/dev/spidev0.0\
    --device /dev/gpiomem\
    -e TZ=Europe/Berlin\
    -e HOST_USER_ID=$(id -u homegear)\
    -e HOST_USER_GID=$(id -g homegear)\
    -p 18080:80 -p 18443:443 -p 2001:2001 -p 2002:2002 -p 2003:2003\
    --hostname homegear\
    --name homegear homegear/homegear:nightly\
    -c /etc/homegear/start.sh

Wichtig: Entrypoint ist eine bash-Shell und eben NICHT das Start-Script selbst! Das Start-Skript wird als Parameter der Bash übergeben und muss der LETZTE Parameter des Docker-Aufrufs sein!

Das war es für diesen Teil, das Thread-Problem kann ich bei meiner Installation umgehen, in dem ich die Thread-Anzahlen dramatisch heruntergesetzt habe, wo ich keine brauche… Gibt es eine bessere Lösung??

Fröhlichen 3. Advent,
HomeSweetHome