10

I have an old-school daemon that I want to control using systemd. When its configuration file changes, it needs to be killed and restarted. In other words, after editing the config file, systemctl reload MYSERVICE should kill the process and restart it.

Attempt 1: Try the defaults. This tells systemd how to start the daemon, but not how to reload it.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

As a result, start and restart work, but reload gives this error:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Attempt 2: Tell it how to kill the process. This kills the process but systemd doesn't restart it for me.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...followed by...

# systemctl daemon-reload
# systemctl reload MYSERVICE

...kills the process but it is not restarted automatically.

Attempt 3: Use ExecReload to restart the process too. This fails for a few reasons:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

...the error message I get...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

I would expect there to be a ReloadType=kill_and_restart or something but no such luck.

How to tell systemd to kill and restart a daemon on reload?

  • Does this really need to be shoehorned into reload, where it doesn't quite exactly fit? Can you not make the daemon behave sensibly? – Michael Hampton Mar 31 '16 at 18:24
  • Thanks @MichaelHampton, but this isn't a situation where I can rewrite the program. I appreciate your helpful suggestion. That said, i'm sure this is a common systemd use-case and a canonical answer might help a lot of people. – TomOnTime Mar 31 '16 at 22:33
  • 1
    I'm sure an answer might help someone, so I did upvote the question. I'm just not sure that this is a common use case. Having used systemd for five years or so, almost from the day it was unleashed upon the world, this is the first time I can recall hearing about anyone attempting this sort of scenario. It's possible I am misunderstanding something because of missing details. – Michael Hampton Mar 31 '16 at 22:44
14

The answer is, "you don't"! But we have good news.

systemd's philosophy is that reload is optional and should be left undefined if there is no true reload functionality. I'd define "true reload functionality" as a reload that does not kill and restart the service, or make the service change its PID. In other words, systemd only wants to reflect what features exists.

Instead, you should use systemctl reload-or-restart which will do a reload if it exists, and a restart if it does not.

From the man page...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Therefore: (1) leave ExecReload blank, (2) use systemctl reload-or-restart MYSERVICE and, (3) you should be all set.

If you do try to use ExecReload to define a way to kill and restart the service, it will have a new PID and systemd would be confused.

2

systemd's philosophy is that reload is optional and the user of systemd should know, for every service, whether it should call reload or fake it by calling restart.

Therefore, the answer to your question is, "It doesn't work, and it shouldn't. Please solve this at the next higher layer."

In other words, systemd wants you to only implement "reload" if the underlying service supports a true reload functionality... i.e. a reload that does not kill and restart the service, or make the service change its PID. In other words, systemd only wants to reflect what features exists.

You may be asking yourself: But wouldn't it be easier if I could implement a "fake" reload by allowing ExecReload to kill and restart the service? Then I could use systemctl reload FOO for all my services and I wouldn't have to remember which ones support it and which ones didn't?

Yes, that would be easier, but that wouldn't be systemd's way. Systemd wants the caller to be the thing that knows if reload exists for the service. Systemd wants to be a common interface to the features that exist, it doesn't want to be responsible for filling in the gaps.

For example, puppet assumes that a systemd-driven service has no reload and defaults to killing and restarting the process. If the Service[] type added a way to specify that reload exists, and that it should be used on notification, it will need to learn which services have or do not have a native reload. Chef and all other systems would also have to learn the same thing because systemd wants it solved at that layer. (MiniRant: for starting a process systemd seems to be the all-knowing, all-mounting, all-namespace-customizing i-do-everything-at-my-layer system. Therefore I can't tell you why it doesn't extend this philosophy to reloading. Maybe one of the authors can chime in here.)

  • 1
    There is systemctl reload-or-restart, which will reload the service if it supports it, and restart it if it doesn't. No idea why Puppet makes this assumption. – Michael Hampton Apr 3 '16 at 19:21

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.