0

This seems like it should be a really simple question but I have had no luck in figuring it out. I have a service 'Alice':

[Unit]
Description=Alice
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5
StartLimitInterval=0
ExecStart=sleep 30d

[Install]
WantedBy=multi-user.target

I would like to write a second service Bob such that:

  • Bob starts when Alice has started successfully
  • Bob starts because, and only because, Alice has started successfully (not triggered by system startup or other activity)
  • Bob stops when Alice stops

I would like to achieve this without modifying Alice. Alice may be at times started with the system (via systemctl enable alice.service) and in other situations only started manually. In practice there will be N-many additional services (Carol, Dave, Eve, ..) with their own unit files that all need to be started when Alice starts, and N may become a fairly large number.

I have experimented with various Unit settings, like PartOf, BoundTo, Requires, After, and no combination I've tried so far achieves the desired result of starting Bob by starting Alice. I've also found that invoking systemctl show bob.service shows the expected settings after running systemctl daemon-reload, but the reverse settings (ConsistsOf, BoundBy, RequiredBy) do not show up in systemctl show alice.service, in apparent violation of the documentation.

I see no errors in the system log when invoking daemon-reload, or when starting Alice which would explain why Bob does not start.

Is it possible to do what I want to do? If so how do I troubleshoot such a problem? FWIW I am doing these experiments on RHEL 8.7 and systemd 239.

  • I haven't rechecked everything so I'm not making an answer of this but your second point looks like a deal breaker – Ginnungagap Apr 15 '23 at 16:39
  • Does this answer your question? [systemd not restarting a process that depends on another process being up](https://serverfault.com/questions/1011834/systemd-not-restarting-a-process-that-depends-on-another-process-being-up) – Gerald Schneider Apr 15 '23 at 17:12
  • @GeraldSchneider Just tried, unfortunately not. It seems like systemd knows about these settings as applied to Bob (after `systemctl daemon-reload`), but as `systemctl show alice.service` demonstrates, it does not apply them to Alice as the documentation claims it should. I see no resulting `RequiredBy` or `ConsistsOf` settings for Alice. (I don't know that this detail is actually related to the problem, but it seems pertinent.) – Chris Robison Apr 15 '23 at 17:34

1 Answers1

1

A possible answer.

It appears so far that there's nothing I can configure for Bob alone that will result in Bob starting when Alice starts. So if that's true I can't really do this without modifying Alice at all, but it looks like I can at least do it without modifying alice.service. This may be a sufficient solution in my case.

Bob's Unit section:

[Unit]
Description=Bob
After=network.target
After=alice.service
PartOf=alice.service

I then modify Alice via drop-in, creating a symlink alice.service.requires/bob.service pointing to bob.service.

So far this appears to be doing exactly what I want -- if there are reasons to avoid this approach I haven't discovered them yet. While PartOf doesn't cause Alice to start Bob without the Requires symlink, it does cause Bob to stop when Alice is stopped (that doesn't happen without the PartOf=alice.service setting).

So ultimately the installer routine for Bob (a software component I'm working on) would add this step to create the symlink at the end (as would Carol etc).

EDIT: I just realized that systemd provides exactly this functionality, though I may or may not use it. From bob.service I remove WantedBy=multi-user.target from the [Install] section, and replace it with Alice:

[Install]
RequiredBy=alice.service

Subsequently, I can use systemctl enable bob.service since it will not cause Bob to start on boot but rather only when Alice starts. It creates the symlink described above under /etc. (My installer may do it manually anyway under /usr/lib rather than use this mechanism.)