Rhel 7 : systemd fails to start a process if background option is given

0

I have a systemd unit file (serv_unit.service):

[Unit]
Description=My service

[Service]
Type=simple
Restart=always
RestartSec=60
StartLimitInterval=400
StartLimitBurst=3
ExecStart=/etc/init.d/myscript start

[Install]
WantedBy=multi-user.target

/etc/init.d/myscript

source /etc/myfile.sh # JAVA_home & other vars are resolved through this file
mode=$1
case "$mode" in
  'start')
    # Start daemon
    daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args &

The problem I am facing is when I run following command:

systemctl start serv_unit.service

I don't see java process. But when I remove the trailing & i.e.:

daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

the java process can be seen (& that java process is not crashing so that rules out the possibility of it crashing in background)

What is the cause?

tryingToLearn

Posted 2019-11-15T04:50:26.230

Reputation: 165

Where does this daemon tool come from? – user1686 – 2019-11-15T06:28:45.740

Answers

1

Aside from the main question, calling init.d scripts from systemd is a bit redundant and generally a bad idea to begin with. This is all you should need:

User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

EnvironmentFile can only be plain KEY=value assignments, but if configuration must come in shell-script syntax, you can also use:

User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"

(You should also set SyslogIdentifier= in both cases, if the service produces stdout messages.)

Service types

Systemd services are expected to follow specific rules. One .service unit can only have one "main" daemon process, and the Type= option tells systemd how that process works.

Type=simple indicates that the initial process (i.e. what's launched from ExecStart=) itself is the service's main process. As soon as the main process exits, the service is considered to have stopped, so any leftovers are cleaned up.

This means that if you're using Type=simple, you're telling systemd that the daemon will not go into 'background'. In fact, you're also telling systemd that the init.d script – not daemon – is the service's main process...

So it would be best if the init.d script not only didn't attempt to put the actual daemon in background, but also started it via exec like this:

case "$mode" in
    'start-foreground')
        # Start daemon in foreground
        exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

On the other hand, Type=forking indicates that the initial process will fork and exit during the startup procedure, and that the main process should be discovered from PIDFile= or heuristically.

Which one to use

With daemons which have built-in 'daemonize' mode, Type=forking has a significant advantage: the systemd service stays in 'Starting' state until the daemon finally tries to go into background, at which point it finally moves to 'Started/Active' state. This helps when configuring dependencies, e.g. service A can declare "After=B.service".

But if backgrounding is done by external means, such as the shell & feature – without anything that would report whether the daemon is ready or not yet – then it's completely useless and you should probably just use Type=simple without any background options.

user1686

Posted 2019-11-15T04:50:26.230

Reputation: 283 655