1

In my computers /lib/systemd/system directory I see a file multiuser.target - that file contains:

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

The line: Requires: basic.target which I assume means "run" the basic.target file.
But in that same /lib/systemd/system directory there is also a multi-user.target.wants/ sub-directory. It contains a bunch more unit files:

/lib/systemd/system $tree multi-user.target.wants/
multi-user.target.wants/
├── dbus.service -> ../dbus.service
├── getty.target -> ../getty.target
├── systemd-ask-password-wall.path -> ../systemd-ask-password-wall.path
├── systemd-logind.service -> ../systemd-logind.service
├── systemd-update-utmp-runlevel.service -> ../systemd-update-utmp-runlevel.service
└── systemd-user-sessions.service -> ../systemd-user-sessions.service

which of these units, i.e. file: basic.target or all of the units in sub-directory multi-user.wants.target is run when multi-user.target is the default boot target? is it all of the above? if so, what is the order?

  • "if so, what is the order?" Everything at once. That's the whole point of systemd. – Ignacio Vazquez-Abrams Apr 26 '18 at 2:55
  • @IgnacioVazquez-Abrams are you poking fun at systemd, or are you saying - yes all these "units" are run, the basic.target and all the units in multi-user.targer.wants and they are all launched asynchronously? – the_velour_fog Apr 26 '18 at 3:02
  • All units in a set of wants are launched asynchronously. Then, once all units in a set of wants have been launched, the wanting unit is launched. – Ignacio Vazquez-Abrams Apr 26 '18 at 3:04
2

There's a difference between Before/After and Wants/Requires/Requisite: the first group indicates the timing of unit starts, and the latter group indicates the dependencies. Often, there's little difference between the two, but sometimes it's important. Reading the documentation is useful for more details, as I've left out stuff that you don't see as often.

As an example, let's pretend that you have some services with dependencies:

a.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sleep 5;/bin/false'
RemainAfterExit=yes

b.service

[Unit]
After=a.service

[Service]
Type=oneshot
ExecStart=/bin/echo B
RemainAfterExit=yes

c.service

[Unit]
Requires=a.service

[Service]
Type=oneshot
ExecStart=/bin/echo C
RemainAfterExit=yes

d.service

[Unit]
After=a.service
Requires=a.service

[Service]
Type=oneshot
ExecStart=/bin/echo D
RemainAfterExit=yes

What is loaded (and in which order) changes drastically depending on what you start:

  • a: a
  • b: b
  • c (or a+c): a and c at the same time (c stays running even if a fails)
  • d (or a+d): a->c (if a started successfully)
  • a+b: a->b (regardless of whether a started)

Why all this complexity? It's to speed up unit loading. If services don't have a Before or After referring to each other, then they can be started at the same time (assuming no other units need them!)

Where do the .target files come in? They put units into functional groups, so that as the system is started (or stopped, etc.), the units that are needed for that phase can be started together, and units can indicate that they want to wait for another phase to be started. For example, a unit can include After=network.target to make sure that the network had a chance to initialize before starting, even though it's installed as part of multi-user.target.

If you want to view the order that units depend on each other, you can run systemctl list-dependencies (it won't tell you the order that they loaded, though, as that's somewhat random outside of Before/After settings.)

  • thanks. that explains the Wants, Requires really well and explains the dependencies directly specified in the multiuser.target file. Do you know how the multi-user.target.wants directory and all the unit files within - come into the picture? – the_velour_fog Apr 26 '18 at 6:15
  • @the_velour_fog Those are auto-generated by systemctl when you enable a unit: it reads the [Install] section (specifically, WantedBy and RequiredBy) to determine which target should have a link added to the service. All of the files in those directories should just be links to the appropriate unit file (or /dev/null if the service has been disabled by the admin); you shouldn't have to touch them normally. – ErikF Apr 26 '18 at 7:08

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.