Linux – How to stop systemd services in specific order

linuxsystemd

How do I ensure a particular order is followed when a specific systemd service is stopped? I have several systemd services/units that I have running but use resources on various mounted partitions. These partitions are mounted and unmounted using a custom service. The running services (e.g. ProgramA.service & ProgramB.service) need to be stopped in a specific order BEFORE the custom mounting program is stopped.

Setting up startup dependencies is fairly simple but I haven't been able to figure out how to make sure that the services are stopped before my mounting service is stopped.

mountCustomPartitions.service

[Unit]
Description=My Custom Partition Mounting Service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/mountCustomPartitions.sh mount
ExecStop=/usr/bin/mountCustomPartitions.sh unmount

[Install]
WantedBy=multi-user.target

ProgramA.service

[Unit]
Description=My Generic Program A Service
Wants=mountCustomPartitions.service
After=mountCustomPartitions.service

[Service]
Type=simple
ExecStart=/usr/bin/ProgramA

[Install]
WantedBy=multi-user.target

ProgramB.service

[Unit]
Description=My Generic Program B Service
Requires=ProgramA.service
Wants=mountCustomPartitions.service
After=mountCustomPartitions.service ProgramA.service

[Service]
Type=simple
ExecStart=/usr/bin/ProgramB

[Install]
WantedBy=multi-user.target

In my scenario above, mountCustomPartitions.service must start before the program services but must also stop after them. If mountCustomPartitions.service is explicitly stopped, then it should cause the others to stop as well (but must wait for them to be stopped). I also need to make sure that ProgramB is started after ProgramA but also stopped before ProgramA. Hopefully, this isn't too confusing.

The only solution that I can think of would be to have each service have a ExecStop line that executes a systemctl stop [service] command for the particular service that must be stopped before it stops. The problem I have with that is I actually currently have six services that use the mounted partitions and must be stopped before attempting an unmount. Of those six, some need to be stopped in a particular order. As this is being used in a commercial product, I was hoping that there was a cleaner solution.

Best Answer

You control the shutdown order by specifying Before= and After= in the unit files to describe the startup order. The inverse order is applied when shutting down.

Here's what the official docs have to say about it:

...when two units with an ordering dependency between them are shut down, the inverse of the start-up order is applied. i.e. if a unit is configured with After= on another unit, the former is stopped before the latter if both are shut down...