55

Is there any difference between Requires vs Wants in target files?

[Unit]
Description=Graphical Interface 
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service

Thanks

1
  • 8
    See man systemd.unit
    – heemayl
    Commented Aug 27, 2017 at 5:36

3 Answers 3

48

As heemayl noted in the comment, the man page answers your question. From the web:

Wants=

A weaker version of Requires=. Units listed in this option will be started if the configuring unit is. However, if the listed units fail to start or cannot be added to the transaction, this has no impact on the validity of the transaction as a whole. This is the recommended way to hook start-up of one unit to the start-up of another unit.

And

Requires=

Configures requirement dependencies on other units. If this unit gets activated, the units listed here will be activated as well. If one of the other units gets deactivated or its activation fails, this unit will be deactivated. This option may be specified more than once or multiple space-separated units may be specified in one option in which case requirement dependencies for all listed names will be created. Note that requirement dependencies do not influence the order in which services are started or stopped. This has to be configured independently with the After= or Before= options. If a unit foo.service requires a unit bar.service as configured with Requires= and no ordering is configured with After= or Before=, then both units will be started simultaneously and without any delay between them if foo.service is activated. Often, it is a better choice to use Wants= instead of Requires= in order to achieve a system that is more robust when dealing with failing services.

Note that this dependency type does not imply that the other unit always has to be in active state when this unit is running. Specifically: failing condition checks (such as ConditionPathExists=, ConditionPathExists=, … — see below) do not cause the start job of a unit with a Requires= dependency on it to fail. Also, some unit types may deactivate on their own (for example, a service process may decide to exit cleanly, or a device may be unplugged by the user), which is not propagated to units having a Requires= dependency. Use the BindsTo= dependency type together with After= to ensure that a unit may never be in active state without a specific other unit also in active state (see below).

From the freedesktop.org page

Your service will only start if the multi-user.target has been reached (I don't know what happens if you try to add it to that target?), and systemd will try to start the display-manager.service together with your service. If display-manager.service fails for whatever reason, your service will still be started (so if you really need the display-manager, use Requires= for that). If the multi-user.target is not reached however, your service will not be launched.

What is your service? Is it a kiosk system? Intuitively I'd suppose you want to add your service to the multi-user.target (so its launched at startup), and have it strictly depend on the display-manager.service via Requires=display-manager.service. But that's just wild guessing now.

4

Our server deployment uses LDAP containing all user IDs and automount maps. User home directories are NFS mounted, and the users typically create @reboot cronjobs with the executable code in their home directories. We also use sssd for cache. Needless to say, we have a high reliance on being able to provide a deterministic boot order for this configuration to work. We have developed a very succinct systemd configuration, and have discovered an obscure nuance between the "wants" and "requires" section options.

If you have a failure of a service during boot, and there is another service dependent with "requires" on that service with "restart=always" set as a service option, that dependent service will not restart. If, however, you have "wants" as an option, the dependent service will restart, as expected.

2

Ref link: https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html

I did few tests, may be it will be helpful to understand the practical results of how "Requires=", "After=" and "Wants=" works. "Requires=": used for tight coupling. If require unit fails at startup or in between, current unit will also stop/crash/fails. "After=" : used for loose coupling and decides order. If require unit fails in between, current unit has no impact on this.

Defining UnitBasic.service, which need UnitChecker to be started first. Sample Test cases:

#File: UnitBasic.service
  Wants=UnitChecker.service
        Result: 
         ip: stop UnitChecker
             stop UnitBasic
             start UnitBasic
         op: UnitChecker gets start
             UnitBasic gets start             => both active, first UnitBasic(pid:1) then UnitChecker(pid:2)
         ip: stop UnitChecker
         op: UnitChecker gets stop
             UnitBasic remains active         => Only dependent unit: UnitChecker getting inactive

         ip: stop UnitChecker
             stop UnitBasic
             start UnitBasic
         op: UnitChecker gets start
             UnitBasic gets start             => both active, first UnitBasic(pid:1) then UnitChecker(pid:2)
         ip: stop UnitBasic
             UnitBasic gets stop
             UnitChecker remains active        => no impact on UnitChecker

   Again ip: stop UnitChecker
             stop UnitBasic
             start UnitBasic
         op: UnitChecker gets start
             UnitBasic gets start        => both active, first UnitBasic(pid:1) then UnitChecker(pid:2)
         ip: stop UnitChecker
         op: UnitChecker gets inactive
             UnitBasic remains active    => no impact on UnitBasic, So here UnitBasic don't have dependency on UnitChecker.


Requires= tight coupling, if dep service stops, this service will also get stop.
            If dep service is not started, it will start the service mentioned in "Requires"
#File: UnitBasic.service
   Requires=UnitChecker.service

    systemctl daemon-reload
    Result: 
         ip: stop UnitBasic
             stop UnitChecker
             systemctl start UnitBasic
         op: UnitBasic starts
             UnitChecker starts                => both starts, first UnitBasic(pid:1) then start(pid:2)

         ip: stop UnitChecker
         op: UnitChecker gets stop
             UnitBasic gets stop            => both inactive

         ip: stop UnitBasic
             stop UnitChecker
             systemctl start UnitBasic
         op: UnitBasic starts
             UnitChecker starts                => both starts, first UnitBasic(pid:1) then start(pid:2)

         ip: stop UnitBasic
         op: UnitBasic gets stop
             UnitChecker remains active
    Conclusion: dependent unit is not having any dependency on the unit, which is using it(UnitBasic).

#File: UnitBasic.service
    Wants=UnitChecker.service
    Requires=UnitChecker.service
        Result:
         ip: stop UnitChecker
             stop UnitBasic
             systemctl start UnitBasic
         op: UnitChecker gets start
             UnitBasic gets start             => both active, first UnitBasic(pid:1) then UnitChecker(pid:2)

         ip: stop UnitBasic
         op: UnitChecker gets stop
             UnitBasic gets stop            => both inactive

         ip: stop UnitChecker
             stop UnitBasic
             systemctl start UnitBasic
         op: UnitChecker gets start
             UnitBasic gets start             => both active, first UnitBasic(pid:1) then UnitChecker(pid:2)

         ip: stop UnitChecker
         op: UnitChecker gets stop
             UnitBasic gets stop            => both inactive
    Conclusion: If any service fails, both fails.

We can use "After=" with "Wants=", if we want the specific order that dependent service(UnitChecker) should start first then using service (UnitBasic). With no tight coupling. So, if any one of the service gets stop, then other will be keep running in this case.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .