0

Environment:

I have a python server which forks into 3 children.

For the parent:

  • SIGTERM is supposed to kill all children and SIGHUP is just supposed to log and exist

For the child:

  • Both SIGTERM and SIGHUP maps to SIG_DFL

Problem:

When I start the script through command line python <script.py>, and send SIGHUP to parent kill -1 <pid-of-parent> it behaves well. The parent exits and busy children exit only after completing their I/Os.

But if the same script is started with systemd script, when I send SIGHUP to parent, the children which are still busy receive a SIGTERM and result in disrupted I/O.

Any explanation/solutions for this ? Is it some misconfiguration ?

mittal
  • 915
  • 10
  • 29

1 Answers1

0

Seems like you need to set KillMode for systemd service to process.

KillMode ... Specifies how processes of this unit shall be killed. ... If set to control-group, all remaining processes in the control group of this unit will be killed on unit stop ... If set to process, only the main process itself is killed ... Defaults to control-group

More info: https://www.freedesktop.org/software/systemd/man/systemd.kill.html#

Another approach is to set creationflags to subprocess.CREATE_NEW_PROCESS_GROUP in subprocess.Popen call if you spawn processes in that way.

Grief
  • 1,839
  • 1
  • 21
  • 40
  • From the documentation `KillMode` would be effective only if service is stopped using `service stop` command. In my case I am sending SIGHUP directly. A quick test using that parameter also shows the same. – mittal Mar 15 '16 at 17:19
  • You might want to try setting `SendSIGKILL=no` as well – Grief Mar 15 '16 at 17:22
  • I think all those parameters would make sense only if the service is managed using service command alone. If SIGHUP is sent directly, those will not come into picture – mittal Mar 15 '16 at 17:24
  • I'd try first if you provided MCVE (http://stackoverflow.com/help/mcve), but according to your question, the are no differences other than running by systemd, so I assume that it kills children processes. – Grief Mar 15 '16 at 17:26
  • Yes, I have been trying that. After removing lot of custom code, the following script runs an `eventlet wsgi` server http://pastebin.com/8TtN7KZ0 And this is the corresponding .service file `# cat /usr/lib/systemd/system/junk.service [Unit] Description=Junk service for testing purpose [Service] Type=simple ExecStart=/tmp/junk.py [Install] WantedBy=multi-user.target` **Note** The server requires python-eventlet package to run – mittal Mar 18 '16 at 11:59
  • Here is my [mcve] :) Using this script, you can see what I meant. If I start the service using `service junk start`, then do `kill -1 `, the children get killed too. If instead I do `python junk.py` and then kill the parent process, children are owned by 1(init) which is what I want. – mittal Mar 19 '16 at 08:02
  • @mittal: I already answered: you have to add `KillMode=process` into `[Unit]` section of a `service`, why didn't you even try that? – Grief Mar 19 '16 at 10:37
  • I did give it a try when I wrote in my first comment 'a quick test...'. But I'll retry it. Thanks – mittal Mar 21 '16 at 05:19
  • After repeating the tests on my actual application server, it seems to be working :) Still trying to figure out why it didn't work earlier. **Big thanks** – mittal Mar 21 '16 at 06:55