14

My config thus far is:

foo.path

[Path] 
PathExists=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

foo.service

[Unit]
Description=Matt Test
BindsTo=foo.path

[Service]
ExecStart=/bin/sh /home/mpekar/bin/foo.sh 
PIDFile=/run/foo.pid

This works fine when starting up but foo.service won't be killed when /tmp/foo.path is removed. Is there some way to make systemd do this or is it just not the appropriate tool for the job?

1

2 Answers 2

7

I would try this. Create an additional service using PathChanged:

foo-stop.path

[Path] 
PathChanged=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

Then create: foo-stop.service

Have it's "ExecStart" script check to see if /tmp/foo.path was deleted (since PathChanged could fire on other changes as well). If the path has been removed, have the script call /bin/systemctl stop foo.

1
  • 2
    I'm gonna go ahead and accept this till such a time that systemd offers an explicit option for doing the same.
    – mpr
    Commented Jun 22, 2016 at 17:27
0

If you are able to kill the process bound to the PIDFile (/run/foo.pid) when /tmp/foo.path is removed (for example, both as actions inside the service shutdown script), then yes.

I achieved it on a Tomcat running over <= RHEL-7.7 with a forking service including an ExecStartPost action that notes down the content of the application pidfile (catalina.pid) into the service PIDFile path. A "PathExists" in the corresponding .path file tracks down the appearing on this catalina.pid in order to hook the systemd service when the user (in my case, unprivileged) invokes the startup script. When the user launches the shutdown, the application pidfile is removed, the PID (also unprivileged) dies gracefully, and systemd stops the service as a systemd pid supervising consequence.

poc.service:

[nouser@nohost system]# cat poc.service
# . . .
[Unit]
After=network.target
After=%p.path
Wants=%p.path
# . . . 
[Service]
Type=forking
Environment="%p_APPLICATION_PID_FILE=/opt/%p/logs/catalina.pid"
PIDFile=/var/run/%p.pid
ExecStart=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen start'
ExecStartPost=/bin/sh -c 'cat ${%p_APPLICATION_PID_FILE} > $(systemctl show %n -p PIDFile|cut -f2- -d"=")'
ExecStop=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen stop'
# . . .

poc.path:

[nouser@nohost system]# cat poc.path
# . . .
[Path]
PathExists=/opt/%p/logs/catalina.pid
# . . .

This way also served to me for Spring Boot applications. But as they born hanging on a bash process, I had to immediate kill that parent process in order to force PID 1 to be the application parent. If not, journalctl shows a message "*.service: Supervising process XXXXX which is not our child. We'll most likely not notice when it exits.", and at the end the systemd service does not stop at the user shutdown action.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .