Background:
I have a C# program that I run under Mono on Linux (specifically Raspbian). I am working on a Python script that starts that program, monitors it, and gracefully kills it. I use subprocess.Popen
to run the C# program under mono. When I run the Python normally, I am able to send a SIGINT
to the process and I can see it receive it and clean itself up nicely before exiting.
Problem:
I want to be able to run the script as a SystemD service, so I created a simple SystemD service file. Now, the C# no longer gracefully exits, instead terminating immediately almost like a SIGKILL
was sent instead of a SIGINT
.
Here is my current simple testing code for working through this problem:
import os
import signal
import time
import subprocess
call = ['mono', '/home/user/test.exe'] # (not the actual name of the program, changed for this post)
print('starting')
process = subprocess.Popen(call)
time.sleep(20)
print('sending term')
process.send_signal(signal.SIGINT)
print('term sent')
And here is my SystemD service file (changed my actual username to 'user'):
[Unit]
Description=Test
After=multi-user.target
[Service]
User=user
Group=user
WorkingDirectory=/home/user/testcode
Type=simple
ExecStart=/home/user/testcode/.venv/bin/python /home/user/testcode/test.py
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=testcode
[Install]
WantedBy=multi-user.target
I've tried watching HTOP to see if there is anything weird going on with what the PID and GID are of the Mono processes, but everything looks more or less the same between the direct launch and SystemD launched Python script.
Unfortunately the Mono program is a bit of a black box to me so I have minimal insight into what is going on in it. I do have access to the source code, but I have no experience with C# and wouldn't know where to start to look for clues. I am able to tell if it quits gracefully as it generates a log file that I can tail
and prints out a couple lines when it is exiting properly. Those lines do not get printed when it is forcefully terminated.
What I've Tried
I've mostly experimented with different methods of launching the program using Popen.
- Using
shell=True
causes the C# program to not be stopped at all when launched normally, but when launched via SystemD, it exhibits the same non-graceful quit behavior as withoutshell=True
. - I tried some suggestions from this thread, namely using
preexec_fn=os.setsid
andos.killpg(os.getpgid(pro.pid), signal.SIGTERM)
from the first answer with and withoutshell=True
with no luck. Both normal launch and SystemD launch exhibit non-graceful quits. - I added
time.sleep(5)
to the end of the script to give the C# time to exit before the script exits. No change. My thought was that SystemD sees the Python script exit, and cleans up all other processes it spawned before they have a chance to exit gracefully.