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
Before= and the soft and hard depdency directives,
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
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.
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=
While it's common to use
After in conjunction with
Wants to ensure that the services start in the correct order, it's not always necessary. You can use
Wants. In fact,
After are used to specify ordering dependencies between units, regardless of whether there is a dependency relationship. However, if you only use
After, without also specifying
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
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
After to ensure that everything starts up in the correct order.
So, while it's possible to use
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.