[systemd-devel] systemctl status and service unit configuration with startup script that exits
Jonathan de Boyne Pollard
J.deBoynePollard-newsgroups at NTLWorld.com
Wed Dec 21 11:16:05 UTC 2016
Owens, Stephen:
> The start script calls other scripts to start two application
> components and then the start script exits.
>
> One of the application components also spawns a couple of child processes.
>
> There ends up being two pid files, one for each component, describing
> the state of the application.
>
You have two services.
Owens, Stephen:
> Environment=JAVA_HOME=/opt/xxx/jre
>
> ExecStart=/bin/bash -l /opt/xxx/bin/startApp.sh
>
> ExecStop=-/bin/bash -lc "/opt/xxx/bin/stopApp.sh -np"
>
Java, again. Java is for some reason a magnet for this sort of stuff.
* http://jdebp.eu./FGA/systemd-house-of-horror/
Owens, Stephen:
> Is there some way I can have systemd monitor the component pids to
> show ACTIVE status?
You have two services. Make two service units. Forget the nutty
startApp and stopApp scripts. When you look into them you'll almost
certainly find that they are a process supervisor in shell script,
written badly as such things always are. The systemd House of Horror
has examples of running Java programs directly from service units (It
isn't hard.) without the intermediate badly written shell script process
supervisors. Stack Exchange has stuff on this, too, and more besides.
* http://unix.stackexchange.com/a/320319/5132
* http://unix.stackexchange.com/a/245038/5132
* http://unix.stackexchange.com/a/322778/5132
* http://unix.stackexchange.com/a/229525/5132
* http://unix.stackexchange.com/a/324286/5132
* http://unix.stackexchange.com/a/321716/5132
* http://unix.stackexchange.com/a/280399/5132
Owens, Stephen:
> I'm stuck with 3rd party startup scripts.
>
No, you are not. This is just a belief and a self-imposed restriction,
and it is groundless when it comes down to it. Look into it, as other
people have, and you'll find the world is quietly, and finally, coming
around to the daemontools idea, that has been around since 1996, of
letting the service manager do this. The MariaDB world, for example,
has finally officially let go of its wrapper process supervisor shell
scripts and documented how to just run the daemon directly under a
service manager, 13 years after daemontools users asked for this.
* http://jdebp.eu./Softwares/nosh/mariadb-and-mysql.html#Prompt
The irony is that if you actually look at your scripts that start/stop
two services you will probably find that they are wrappers for wrappers,
like the startdb.sh and stopdb.sh that these people wrote:
* http://itdadao.com/articles/c15a369637p0.html
*
https://mohamedazar.com/2015/08/27/oracle-applications-r12-auto-start-on-linux/
Even if you hang on to the incorrect belief that these wrapper scripts
are set in stone, there's a glaringly obvious decomposition into two
parts in such cases. You have two services.
Whenever you see the patterns ...
> ExecStart=/opt/example/bin/something.sh start
> ExecStop=/opt/example/bin/something.sh stop
or
> ExecStart=/opt/example/bin/startSomething.sh
> ExecStop=/opt/example/bin/stopSomething.sh
... the Oracle camelCase and the "stop"/"start" arguments are strong
indicators that in fact those scripts will turn out to be process
supervisors written badly in shell script, grepping the process tree,
using PID files, doing their own service restarts with while loops and
wait, creating private log files that only ever expand indefinitely, and
running the actual service processes as a grandchild or even a
great-grandchild of the main process. (Some of the most stupid cases
are when one strips away one unnecessary shell script badly written
process supervisor, only to find that the process that it is supervising
is itself *another* shell script badly written process supervisor.)
Another giveaway is the "I had to add RemainAfterExit=yes because
otherwise it didn't work." as exemplified in the ridiculous edifice
(that clearly hasn't been tested otherwise the invalid attempts at
redirection would have been spotted, like they were in three of the
Stack Exchange questions mentioned earlier) recommended by Oracle
consultant Tim Hall here:
*
https://oracle-base.com/articles/linux/linux-services-systemd#creating-linux-services
M. Hall had to add RemainAfterExit=yes because xe is running shell
scripts that in turn fork and execute programs such as "lsnrctl" and
"sqlplus", some of which in turn fork and execute further processes and
exit the parent processes. The shell scripts aren't necessary at all.
Xe actually has two services, just like you. In contrast: this person
has, at least (the "something start/stop" layer that forks still being
there), decomposed having two services into having two service definitions:
* https://server-world.info/en/note?os=CentOS_7&p=oracle12c&f=6
If one has to add RemainAfterExit=yes in order to bodge things, then its
quite likely that one has built such a ridiculous edifice, too. The
shell scripts are forking subprocesses to run non-builtin commands,
which are in turn probably *more* shell scripts that *also* fork, and
exiting the parent process. None of this is actually necessary, and it
is just cargo-cult design that gets one into this state.
You do not need reams and multiple levels of intermediary shell scripts
between a (proper) service manager and a Java program. Really, you
don't. It is not a rule. Java is not as incompetent as this is making
it out to be.
More information about the systemd-devel
mailing list