[systemd-devel] boot-complete.target dependencies issue
Lennart Poettering
lennart at poettering.net
Sat Sep 17 16:44:53 UTC 2022
On Fr, 16.09.22 10:10, Antonio Murdaca (runcom at redhat.com) wrote:
> Hi, following
> https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/#how-to-adapt-this-scheme-to-other-setups
> I've been experimenting on a fedora system
> with systemd-boot-check-no-failures.service and the ability to have
> services run "after" boot-complete.target. The basic use case would just to
> have something that checks services are up and running, reach boot-complete
> if they are, and start other services afterwards.
> I've taken from that blog this piece specifically:
> ```
> To support additional components that shall only run on boot success,
> simply wrap them in a unit and order them after boot-complete.target,
> pulling it in.
> ```
> So I've done the following with an example service and by enabling :
>
> # cat /etc/systemd/system/test.service
> [Unit]
> Description="Order after boot-complete.target, pulling it in"
> After=boot-complete.target
> Requires=boot-complete.target
>
> [Service]
> Type=oneshot
> ExecStart=/usr/bin/echo "Additional component that shall only run on boot
> success"
> RemainAfterExit=yes
>
> [Install]
> WantedBy=default.target
>
> # systemctl enable test.service systemd-boot-check-no-failures.service
> Created symlink /etc/systemd/system/default.target.wants/test.service →
> /etc/systemd/system/test.service.
> Created symlink
> /etc/systemd/system/boot-complete.target.requires/systemd-boot-check-no-failures.service
> → /usr/lib/systemd/system/systemd-boot-check-no-failures.service.
>
> # systemctl reboot
>
> Unfortunately, the above results in:
>
> systemd[1]: multi-user.target: Found ordering cycle on test.service/start
> systemd[1]: multi-user.target: Found dependency on
> boot-complete.target/start
> systemd[1]: multi-user.target: Found dependency on
> systemd-boot-check-no-failures.service/start
> systemd[1]: multi-user.target: Found dependency on multi-user.target/start
> systemd[1]: multi-user.target: Job test.service/start deleted to break
> ordering cycle starting with multi-user.target/start
>
> so what's the correct way to perform the mentioned "order [units] after
> boot-complete.target", if they cannot be pulled in through the usual
> default/multi-user targets? If I add DefaultDependencies=no to test.service
> it now appears to work w/o the dependency cycle.
It should suffice adding After=multi-user.target to your service.
The things is that systemd-boot-check-no-failures.service runs late,
after the startup transaction is done to check if everything
succeeded. But now you want to run something more, so by default
s-b-c-n-f.s would also want to run after that, to know if it
succeeded. But htat of course makes little sense: the output of
your service cannot be part of the input of s-b-c-n-f.s if your
service should run after s-b-c-n-f.s!
So, my recommended fix: add After=multi-user.target to your
service. Note that systemd handling of .wants/ works like this:
1. add Wants= type dep
2. if no After=/Before= dep is set, then also add Before=
This means, that just adding an explicit After=multi-user.target to
your service means rule #2 won't take effect anymore.
With that in place things should just work (untested, but afaics), as
it means s-b-c-n-f.s can run after multi-user.target, and then
boot-complete.target after that, and then finally your service.
Does that make sense?
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list