0

I have a systemd startup script for a forking service (let's call it foo) based on YAJSW (Yet Another Java Service Wrapper). The relevant part of the .service file looks like this:

ExecStart=/opt/foo/startup.sh
ExecStop=/opt/foo/shutdown.sh
Restart=always    
Type=forking
PIDFile=/opt/foo/wrapper.pid

The startup.sh script is responsible for starting the YAJSW wrapper. The YAJSW configuration file is set so that its PID is written to a file during startup:

 wrapper.pidfile = /opt/foo/wrapper.pid

This way if the wrapper process dies (for any reason), systemd should bring it up, which is the desired behaviour. I have verified that this configuration works correctly, yet a strange line shows in journalctl:

foo.service: PID file /opt/foo/wrapper.pid not readable (yet?) after start: No such file or directory

Strangely, the systemctl status foo shows the main PID correctly:

foo.service
...
Main PID: 12313 (java)

Am I doing something wrong or is this a bug in one of the software components? I am running Ubuntu 16.04.3 LTS, kernel version 4.4.0, systemd version 229.4. Any help will be appreciated.

JdeBP
  • 68,745
Paweł
  • 101

2 Answers2

2

a forking service […] YAJSW (Yet Another Java Service Wrapper) […] ExecStart=/opt/foo/startup.sh […] ExecStop=/opt/foo/shutdown.sh […] PID is written to a file […]

This sort of stuff is endemic with Java, and indeed seemingly with Oracle systems in general; but also completely unnecessary. You don't need Poor Man's Service Managers, written in either shell script or Java, run underneath an actual service manager. PID files are an outright dangerous and rickety mechanism. You don't need startup.sh and shutdown.sh scripts and they end up pushing the actual service process down the process tree to no good end. You don't need an additional YAJSW configuration file. You don't need a complex and idiosyncratic logging mechanism based upon buffering standard output in memory.

Your service process should be directly managed by actual service management, and won't be using the systemd forking readiness protocol because almost nothing in the wild actually uses it. Do not use wrapper shell scripts to run Poor Man's Service Managers. Do not use PID files. Any shell script wrappers should chain load, not fork. Your configuration file is the systemd service unit file, not some other configuration file. Your logging mechanism is the one that comes with service management, which captures standard output and standard error and writes their data to file.

Further reading

JdeBP
  • 68,745
0

I wouldn't say it's a bug so much as a complexity issue. You currently have this chain, just to start and manager your app:

systemd -> startup.sh -> YAJSW -> actual app

I don't know exactly what startup.sh and YAJSW are doing, but it would be desirable to attempt to simplify the management to do:

systemd -> actual app

Then if there's a problem with the management, it will be much easier to reason about what's happen.

I recommend simplifying the situation by maximizing the use of systemd for management and minimizing or eliminating what your scripts and YAJSW are doing.