[systemd-devel] Requires and After

Michael Chapman mike at very.puzzling.org
Wed Jan 2 09:36:30 UTC 2019


On Wed, 2 Jan 2019, Jérémy Rosen wrote:
> So...
> >> Requires = Wants + PartOf
> >> Requires + After = Wants  + PartOf + Requisite + After
> >>
> >> better ?
> >> My goal is to try to clarify that in the documentation at some point...
> > I don't think Requisite= comes into it at all.
> >
> > Requisite= propagates a "start" or "restart" job as a "verify-active" job.
> > In other words, it only checks that the other unit is active, failing the
> > activation of the current unit if necessary.
> >
> > Requires= propagates these as "start" jobs, activating the other unit if
> > it is not already active.
> I'm pretty sure that there is something about Requires making a unit fail if
> it's dependency has already failed when it is scheduled for startup...
> 
> Again I may be wrong...

Let's try it out!

    $ systemctl --user cat a.service
    # /home/mchapman/.config/systemd/user/a.service
    [Unit]
    Requires=b.service

    [Service]
    ExecStart=/bin/true
    RemainAfterExit=true

    $ systemctl --user cat b.service
    # /home/mchapman/.config/systemd/user/b.service
    [Service]
    ExecStart=/bin/false
    RemainAfterExit=true

    $ systemctl --user start b.service

No error here, since a Type=oneshot service is always immediately active. 
But it did fail, as expected:

    $ systemctl --user status b.service
    * b.service
       Loaded: loaded (/home/mchapman/.config/systemd/user/b.service; static; vendor preset: enabled)
       Active: failed (Result: exit-code) since Wed 2019-01-02 20:29:53 AEDT; 7s ago
      Process: 512 ExecStart=/bin/false (code=exited, status=1/FAILURE)
     Main PID: 512 (code=exited, status=1/FAILURE)

    Jan 02 20:29:53 beren.home systemd[2618]: Started b.service.
    Jan 02 20:29:53 beren.home systemd[2618]: b.service: Main process exited, code=exited, status=1/FAILURE
    Jan 02 20:29:53 beren.home systemd[2618]: b.service: Unit entered failed state.
    Jan 02 20:29:53 beren.home systemd[2618]: b.service: Failed with result 'exit-code'.

So what happens if we now try to start a.service?

    $ systemctl --user start a.service
    $ systemctl --user status a.service
    * a.service
      Loaded: loaded (/home/mchapman/.config/systemd/user/a.service; static; vendor preset: enabled)
      Active: active (exited) since Wed 2019-01-02 20:30:08 AEDT; 2s ago
     Process: 544 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
    Main PID: 544 (code=exited, status=0/SUCCESS)

    Jan 02 20:30:08 beren.home systemd[2618]: Started a.service.

It was successful! But you can see that it was unable to start b.service a 
second time:

    $ systemctl --user status b.service
    * b.service
       Loaded: loaded (/home/mchapman/.config/systemd/user/b.service; static; vendor preset: enabled)
       Active: failed (Result: exit-code) since Wed 2019-01-02 20:30:08 AEDT; 4s ago
      Process: 545 ExecStart=/bin/false (code=exited, status=1/FAILURE)
     Main PID: 545 (code=exited, status=1/FAILURE)

    Jan 02 20:30:08 beren.home systemd[2618]: Started b.service.
    Jan 02 20:30:08 beren.home systemd[2618]: b.service: Main process exited, code=exited, status=1/FAILURE
    Jan 02 20:30:08 beren.home systemd[2618]: b.service: Unit entered failed state.
    Jan 02 20:30:08 beren.home systemd[2618]: b.service: Failed with result 'exit-code'.

However, explicitly stopping b.service causes a.service to be stopped:

    $ systemctl stop --user b.service
    [mchapman at beren ~]$ systemctl --user status a.service
    * a.service
       Loaded: loaded (/home/mchapman/.config/systemd/user/a.service; static; vendor preset: enabled)
       Active: inactive (dead)

    Jan 02 20:33:33 beren.home systemd[2618]: Stopped a.service.

Make of that what you will. I was expecting a.service to stop because 
b.service failed, but apparently my understanding of this isn't quite 
right.


More information about the systemd-devel mailing list