5

(systemd version 229)

I have a primary service A, and a secondary service B. The primary A can run by itself. But service B cannot run correctly by itself: it needs A to be running (technically B can run, but this is what I want systemd to prevent). My goal: If A is not running, B should not run. Given that A and B are running, when A stops or dies/crashes, then B should be stopped.

How do I achieve this?

I get close by adding [Unit] items to b.service, using

Requisite=A.service
After=A.service

The result of the above is that

  • B won't start unless A is running (good).
  • B is stopped when A is stopped (good).
  • However, if I kill A, service B continues to run (bad).

How can I fix this last behavior? Neither PartOf nor BindsTo seems to do the trick, but perhaps I don't have the right incantation of combinations of options? Its not clear to me from the man pages what options can be combined.

systemd.unit man page: https://www.freedesktop.org/software/systemd/man/systemd.unit.html Related: Systemctl dependency failure, stop dependent services

Uncle Spook
  • 159
  • 1
  • 3
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. – jww Nov 13 '17 at 02:53
  • Really? Lots of systemd questions have already been answered here in SO. And its related to the development of systems, not only apps are developed. – Jesús Franco Nov 13 '17 at 22:43
  • Instead of the Requisite, have you tried using BindsTo as in the linked question is proposed as solution? – Jesús Franco Nov 13 '17 at 22:46
  • Thanx, I'll move the question to S/E. @Jesus, BindsTo handles the kill B part, but it has the side-effect that when I start B, A is also started. I want B to give a dependency error as it does with Requisite. But I guess BindsTo is the better option of the two. Thanx for suggestion that I look at it again. – Uncle Spook Nov 15 '17 at 02:42
  • 1
    Moved to ServerFault: https://serverfault.com/questions/884211/systemd-service-dependency-if-a-is-not-running-b-should-not-run – Uncle Spook Nov 20 '17 at 01:52

3 Answers3

2

You can use, Requires= or PartOf= or BindTo=

see this article for detail of their usage

Knova Chan
  • 135
  • 8
1

To achieve your 3rd objective make use of PartOf keyword.

In B.service you need to add dependency on A under [Unit] section as below

[Unit]
..
..
PartOf=A.service

With this, whenever A is killed B shall also stop.

DarkKnight
  • 597
  • 3
  • 15
  • Thanx @DarkKnight, but PartOf doesn't quite do it; if I stop A normally then B is stopped (good), but if A dies or is killed, B continues to run (bad). Using BindsTo seems closer, but it has a different issue. Anyway, fwiw, I've move this question to ServerFault. – Uncle Spook Nov 20 '17 at 01:57
1

If you start Service A with Type=notify you may be able to achieve something if you terminate A with SIGINT or SIGTERM, you can actually handle that and send a message on $NOTIFY_FD to systemd, but that option is still not possible with SIGKILL. It's a bit involved but might be able to achieve what you want.

You should also consider making A Restart=always. This will at-least make sure that A will remain available and B won't keep giving out errors. When you kill A (outside systemd), there's no way for systemd to know that A was killed - especially if you do so with kill -9 (SIGKILL cannot be handled). . So one of the best way to handle that will be to make Service A, Restart=always.

gabhijit
  • 3,345
  • 2
  • 23
  • 36