2

I have a daemon I've created which fires up a bunch of subcomponent threads. If I use the "systemctl stop" command I catch the SIGTERM and usually have everything closed down cleanly in 2-6 seconds (my threads need to be closed sequentially mostly).

However if the daemon is shutdown as a result of a "shutdown" or "reboot" command I see in my log that it appears that it's getting killed (SIGKILL?) within a second or two of the SIGTERM. I tried adding "TimeoutStopSec=20" to my ".service" file as well as uncommenting "DefaultTimeoutStopSec=90s" in the "system.conf" file with no change in behavior (which makes sense since it seems 90s is the default anyway).

Here is the current ".service" file -

[Unit]
Description=XXXXXX XXXXXXX
After=network-online.target
Requires=network-online.target
After=bluetooth.service
Requires=bluetooth.service

[Service]
Type=forking
KillSignal=SIGTERM
KillMode=process
PIDFile=/var/run/XXXXXXXXXX.pid
ExecStart=/usr/local/bin/XXXXXXXXXX

The app itself does the normal daemon stuff, i.e. fork, set up sigterm handling, close inherited file descriptors, and write a pid file.

I'm running Stretch 9.9 Lite from a month or so ago. So is there some other setting that controls the shutdown/reboot process? I'm just not finding anything else that clearly states how the shutdown process would be different from the systemctl stop process (if it is).

Update - I've tried adding "SendSIGKILL=no" into the "Service" section of my .service file as well as "RequiresMountsFor=/var/log" into the "Unit" section. No difference unfortunately. The log my daemon creates get's halfway thought it's normal shutdown process and stops writing.

Update - I changed the "After=" and "Requires=" to point to multi-user.target and it now stops cleanly. I assume that implies that something my application needed was being closed/shutdown before I was fully stopped. Not sure if that's an okay thing to do (can't find many examples of people doing it via google) but my daemon runs in the background with no user intervention so I assume it's okay? Obviously I'd prefer to know exactly what the issue was but I can't really think of anything other than network/sockets, bluetooth, and the mount I mention above...

  • This sounds like a good question, but I suspect this is not the right forum. Perhaps the main site? – joan May 7 '18 at 23:08
  • Sounds more like a problem with your code. – Milliways May 7 '18 at 23:58
  • Thanks, yeah maybe more of general linux question but then from what I'd read in general it should work so I was wondering if it was a raspbian thing only possibly. As far as it being my code I'm completely open to that but I do catch the sigterm signal and start the process of shutting down all my subcomponents. Just halfway through the process it seems to just die (which virtually never happens when shutdown via systemctl stop)... Anyway, thanks for the replies! – Chrisby May 8 '18 at 0:37
  • Can you carry out a crosscheck on a vanilla Debian Stretch to figure out it's Raspbian only? Can you add your script and how you run it? – Fabian May 8 '18 at 5:53
  • I don't have a machine this week to set up a vanilla Debian Stretch install but can later next week. As for the script, I just have the ".service" file below. In looking back at that I'm wondering if possibly the file system could be being unmounted before my app is shutdown (would also explain my log stopping in the middle of it's own shutdown sequence)? Other than that the app just does the normal "daemon" stuff, fork, set up sigterm handling, close inherited file descriptors, and write a pid file. – Chrisby May 8 '18 at 21:51
0

I see in my log that it appears that it's getting killed (SIGKILL?) within a second or two of the SIGTERM

Yes.

From man systemd.kill:

Processes will first be terminated via SIGTERM (unless the signal to send is changed via KillSignal=). Optionally, this is immediately followed by a SIGHUP (if enabled with SendSIGHUP=). If then, after a delay (configured via the TimeoutStopSec= option), processes still remain, the termination request is repeated with the SIGKILL signal (unless this is disabled via the SendSIGKILL= option).

Which makes it a bit mysterious why setting the timeout doesn't work, but you could still try the "unless" clause:

SendSIGKILL=

Specifies whether to send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the service around. Takes a boolean value. Defaults to "yes".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.