thortex / rpi3-webiopi

WebIOPi for Raspberry Pi 1, 2, 3, and zero
https://thortex.github.io/rpi3-webiopi/
Apache License 2.0
60 stars 20 forks source link

systemctl stop fails on non-debugging mode #52

Open thortex opened 6 years ago

thortex commented 6 years ago
 $ sudo systemctl stop webiopi
 $ # takes a while...
 $ sudo systemctl status webiopi
   systemd[1]: webiopi.service: State 'stop-sigterm' timed out. Killing.
   systemd[1]: webiopi.service: Killing Process 12035 (python3) with signal SIGKILL.
   systemd[1]: webiopi.service: Main process exited, code=killed, status=9/KILL.
   systemd[1]: webiopi.service: Unit entered failed state.
   systemd[1]: webiopi.service: Failed with result 'timeout'.
MichaIng commented 3 years ago

We face the same. I tried it on different Debian Stretch, Buster and Bullseye systems with different Python 2 and 3 versions, with and without debug flag -d, SIGTERM leads to infinite 100% CPU usage without ever stopping. systemd SIGKILLs the process after 90 seconds timeout, manually this works as well of course.

python3 -m webiopi -d is the easiest way to reproduce this without any systemd and config impact.

Important to note that we use this fork, but I also saw it on the original (unpatched) v0.7.1.

I tried strace python3 -m webiopi -d, but SIGTERM works there without any additional output. It seems strace itself kills the process successfully or probably invokes it in a way there the issue does not appear.

Not sure whether this fork is actively used/developed, but I'm open to help debug and test the underlying issue, if someone with more insights and Python knowledge can point me into the right direction or suggest debug steps I can do.

MichaIng commented 3 years ago

The HTTP server is the culprit, or how it is handled/threaded. Disabling it, respectively adding http_enabled = False in webiopi/server/__init__.py solves the issue.

self.http_server.stop() is definitely called and I see added debug output after that call.

There self.server_close() in the HTTPServer as well is called. Checking the docs about the http.server class: https://docs.python.org/3/library/http.server.html

Solution

PR up: #57