Systemd Services – How Does Systemd Determine Service is Stopped?

init.dsystemd

Our application uses an init.d script to start and stop the application as a service. Under CentOS 7, /sbin/init is symlinked to systemd, so I can start my application using either:

service myapp start

or

systemctl start myapp

The issue I am having is that running stop on the service using either service or systemctl will not stop my application. The output of systemctl status:

[root@nec04 ~]# systemctl status myapp
myapp.service - SYSV: Service script to start/stop my application
   Loaded: loaded (/etc/rc.d/init.d/myapp)
   Active: inactive (dead) since Mon 2015-10-05 15:17:41 CEST; 22h ago
  Process: 31850 ExecStop=/etc/rc.d/init.d/myapp stop (code=exited, status=0/SUCCESS)
  Process: 21054 ExecStart=/etc/rc.d/init.d/myapp start (code=exited, status=0/SUCCESS)

Using the service command:

[root@nec04 ~]# service myapp status
Local database at :3307 is started
Watchdog is running
Application is running

Why does systemctl think my application is not running? Could it be that systemctl is not calling the stop function because it thinks my application is already stopped?

Best Answer

Why does systemctl think my application is not running?

Because, as Tom Hunt says, it isn't running.

Could it be that systemctl is not calling the stop function because it thinks my application is already stopped?

No. It very clearly did call the stop function, and ran it as process #31850.

There are two possibilities here, neither of which are systemd problems:

  • At some point, you started your service programs directly, not as a systemd service. That's what's still running. Of course systemd won't know about it.
  • The status functionality of your init.d script is faulty. It wouldn't be the first such faulty init.d script in the history of the world.

myapp.service - SYSV: Service script to start/stop my application

That "SYSV:" there is a giveaway that your init.d script is poor. It doesn't even have the LSB header block.

As Tom Hunt says, write some service units. Or remember the first rule for migration to systemd and just go and pinch the ones that have already been written. By the looks of it, you actually have three interdependent but distinct services, and should be writing multiple service units with those interdependencies expressed. If one of them is a database server listening on port 3307, then the first rule almost certainly applies.

Further reading