systemd progressed the Linux PID 1 situation adding many feature and capabilities. But, as always, with features and capabilities, comes complexity. One thing I and many co-workers have found difficult is getting startup order right, especially with custom targets. First lets define some systemd concepts:
- unit: a configuration file that describes a service, a socket, a device, a mount point, or other entities that systemd can manage.
- target: a special kind of unit that groups together other units that need to be started or stopped together in a coordinated fashion.
- Targets are similar to runlevels in traditional SysV init systems, but are more flexible and can be used to group together any kind of unit, not just services.
- service: a type of systemd unit that describes a process that systemd should manage
In this blog post, we are going to focused on systemd service units, using After=
, Before=
and the soft and hard depdency directives, Wants=
and Requires=
(respectively).
Note: Some AI was used to ask systemd questions to get answers, so please question any inaccuracies. I did try to lab all in a VM to ensure it somewhat seemed correct.
Requires (hard) vs. Wants (soft)
If you use Wants
, the service is pulled in with other dependencies, but its failure will not lead to other services failing. When you use Before
or After
with Wants
, it is ensured that the service is started in the right order, but it won't prevent other services from starting if the service fails.
On the other hand, if you use Requires
, the service is considered a "hard" dependency, meaning that if it fails, the system will try to restart it and no other dependent services will start until the service has been started successfully.
So, Wants
is best for dependencies that aren't critical for the functioning of the system, while Requires
should be used for critical dependencies that are necessary for the proper functioning of the system.
Do we always need After= or Before= with Requires= / Wants=
Not necessarily!
While it's common to use Before
and After
in conjunction with Requires
or Wants
to ensure that the services start in the correct order, it's not always necessary. You can use Before
and After
without Requires
or Wants
. In fact, Before
and After
are used to specify ordering dependencies between units, regardless of whether there is a dependency relationship. However, if you only use Before
and After
, without also specifying Requires
or Wants
, the start-up of the two units will not be coordinated, and the order may change in future versions of systemd.
For example, if you have a service that depends on another service that is started early in the boot process and has no dependencies of its own, you might not need to use Before
or After
at all. However, if your service has complex dependencies, or if you have other services that depend on it, it's usually a good idea to use Before
and After
to ensure that everything starts up in the correct order.
So, while it's possible to use Before
and After
without Requires
or Wants
, it's generally not recommended.
Requires side effects
When you use Requires
to declare a dependency in systemd, it means that the dependent unit is required for the service to function properly. If the dependent unit fails, the system will try to restart it until it succeeds.
However, this can have some side effects. For example, if you have a service that depends on another service that takes a lot of time to start, the dependent service might not start in a reasonable amount of time and may fail.
Moreover, since Requires creates a hard dependency, other dependent services will not start until the service has been started successfully. This can slow down the overall boot process of the system.
So, it's important to carefully consider whether you actually need a hard dependency before using Requires, and if you do, make sure that the dependent unit starts in a reasonable amount of time.