1

There are two mechanisms to start/stop my program "abc"

  1. systemctl service file inside /usr/lib/systemd/system/abc.service
  2. /etc/abc init script abc script will invoke all the daemons. But systemctl status is not accurate when I start/stop daemons using /etc/abc

To fix this, I've added Type=forking and added PIDFile directive. It solves the issue of the stop. systemctl status will show inactive when I stop the daemons using the abc init script. So the issue got fixed partially. But it will still be inactive when I start the daemons using abc init script.

How can I solve this issue? I tried to introduce an abc.path file which checks for the existence of a file and then notifies the service. But it isn't helping.

Using systemd 219.

  • What you need to tell people, edited into your question, is what you are not using. You are not using Debian (or a derivative such as Ubuntu) or a RedHat operating system, are you? It will help further still to say what you are using, but my educated guess is that you are not using those. – JdeBP Sep 20 '17 at 8:42
  • @JdeBP, I'm mainly running my apps on CentOS and RHEL. But the problem is systemd specific and I suppose it should work on all distros which use systemd. – nithinj Sep 20 '17 at 9:24
  • systemd calling scripts in /etc/init.d was always designed to be a "legacy fix" as opposed to a "feature" of the system. Is there any reason why you don't just start the services with systemctl? – Raman Sailopal Sep 20 '17 at 10:47
  • @RamanSailopal, Starting with systemctl is always the preferred and recommended method. However, the legacy method (starting via init script) is also valid and wanted to track using systemctl if possible. – nithinj Sep 20 '17 at 10:59
  • systemctl simply calls the script in init.d and utilizes the return statuses. Unless there is a specific reason why calling from init.d is required, I would just call it using systemctl – Raman Sailopal Sep 20 '17 at 11:17
3

Of course it does.

If they weren't started by the service management subsystem, they won't be tracked by the service management subsystem. And they won't be proper dæmons, really.

background on van Smoorenburg rc compatibility mechanisms

further reading: https://unix.stackexchange.com/a/233581/5132

The van Smoorenburg rc compatibility mechanism provided by systemd is a generator. It ensures that there is a generated abc.service service that runs /etc/init.d/abc start at service start and /etc/init.d/abc stop at service stop.

Note, at this point, that the existence of /usr/lib/systemd/system/abc.service completely prevents the generation of an abc.service by systemd's generator.

This is the entire extent of van Smoorenburg rc compatibility in vanilla systemd. The ability for the superuser to directly invoke /etc/init.d/abc in various ways, and have that connect up to systemd is provided as an augmentation to vanilla systemd by the operating system's individual developers.

The Debian and Ubuntu people, for example, provide a hook in their own /lib/lsb/init-functions.d/ subsystem that acts as follows:

  • If the hook detects that the init.d script is being invoked as the ExecStart/ExecStop of a generated systemd service, it does nothing special and just runs the rest of the script as it stands.
  • If the hook detects that the init.d script is being invoked directly, not as part of a generated systemd service, it transforms /etc/init.d/name verb into systemctl verb name and switches to that, not running the rest of the script. (Some verbs it passes through, but you are talking of start and stop, which are handled in the way explained here.)

in the absence of the compatibility mechanisms

Not all operating systems have such a van Smoorenburg rc compatibility mechanism that translates the direct invocation of /etc/init.d/name verb into systemd's way of doing things. Some operating systems (such as the one run by the person at "Why does `init 0` result in "Excess Arguments" on Arch install?", for example) provide no van Smoorenburg rc compatibility at all, not providing a hook like Debian's/Ubuntu's and even outright disabling the compatibility mechanism that comes with vanilla systemd.

On such an operating system, running the van Smoorenburg rc script directly just runs that script as-is.

Such a script does not start a service under service management. It does things such as double-forking and whatnot, in vain and in most cases fruitless attempts to run in the same environment that actual service dæmons run in. (Much of this so-called "dæmonization" stuff does not work and has not worked since the 1980s; this being the reason that proper dæmon management systems were invented in the early 1990s in the first place.) But as far as service management is concerned it is just the superuser in an interactive login session forking stuff.

Indeed, systemd will consider such directly invoked van Smoorenburg rc scripts and all of the vainly "dæmonized" programs that they fork off into the background to be running as part of the user's interactive session scope inside the user's slice, not as services that run outwith user sessions in the system slice.

Worse, it ends up using the highly flawed mechanisms of the van Smoorenburg rc system, such as killing all processes running anywhere that match the service name at service stop, instead of just the specific service processes that the service manager started and is tracking. This is why /etc/init.d/name stop is appearing to work for you. The script is killing all processes that match a name, which just happens to also include the processes that run under the service manager. This indiscriminate killing of everything is a bug, though, not a feature. This is only the appearance of proper functionality, and it will bite you down the road, as it has bitten so many system administrators in the past several decades.

the correct thing to do

If you lack such compatibility mechanisms, then do not invoke van Smoorenburg rc scripts directly. It is as simple as that. Use the service or systemctl commands to communicate with systemd's service management; but do not run /etc/init.d/anything directly for stopping, starting, and obtaining the statuses of services.

A subordinate point is that you should not be mucking around with /usr/lib/systemd/system/abc.service just to try to bodge the van Smoorenburg rc script into sort-of working. Type=forking is almost certainly wrong for your service. (It does not match almost all actual services in the wild.) And if the people who came up with /usr/lib/systemd/system/abc.service managed to get rid of the well-known-to-be-broken PID file mechanism that is wholly unnecessary for true service management, it is outright daft to be putting it back in again.

Further reading

  • Great write-up and references. The third reference doesn't seem to work. Can you update it? I read that it kills all the services that match the service name upon init.d/name stop. But it looks like if I set KillMode=process and Type=Forking, then the systemctl shows the correct status upon killing the process by other means such as kill/pkill (not necessarily using init script). Any idea how does this happen? I could not find any related references. (I'm not using a PIDFile entry in this case) – nithinj Sep 26 '17 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.