I have a series of mutually exclusive systemd services that are started and stopped by users as needed. Each of the services requires exclusive use of some hardware, so many of the services conflict with each other. (But not all services conflict with all other services)

To manage this I've used Conflicts=, which almost works perfectly, however the ExecStart of the starting service seems to run while the ExecStop script of the conflicting service is still running running, which causes the starting service to fail as the hardware resources are not yet available.

If I have the start scripts sleep for some safe amount of time, like 30 seconds, they function perfectly, but I'd much rather them start as soon as the conflicting service stops.

After= doesn't seem to work as the services can be stopped and started repeatedly, in arbitrary order, and After= causes a cyclical dependency.

Is there a way to do this in systemd without resorting to checking if a conflict is running inside the ExecStart scripts?

3 Answers 3


The manual page systemd.unit(5) has this to say about Conflicts=:

Note that this setting does not imply an ordering dependency, similarly to the Wants= and Requires= dependencies described above. This means that to ensure that the conflicting unit is stopped before the other unit is started, an After= or Before= dependency must be declared. It doesn't matter which of the two ordering dependencies is used, because stop jobs are always ordered before start jobs, see the discussion in Before=/After= below.

In other words, just declare an ordering dependency.


My guess is that your ExecStop= command is issuing an async operation, like sending a termination signal to a process, and then exiting immediately before the process has finished shutting down.

Make sure your ExecStop= command is a synchronous operation that does not exit until the service is completely shutdown.

  • That was how I expected it to work, so the ExecStop command uses a do while to wait until the service is stopped before it returns, and I have confirmed that the the units don't get marked as stopped until after the ExecStop script finishes freeing up the resources. The ExecStart is definitely running while the ExecStops are still waiting, and the service failed to start messages appear in the journal before the service stopped messages.
    – millow
    Commented Aug 30, 2018 at 16:31
  • I would search the systemd issue tracker for bug reports about this and if there is not already one, file a new one. (Assuming you are using the latest version of systemd or nearly-so). Your experience seems to be in conflict with documentation for ExecStop=, which I based my answer on. Commented Sep 4, 2018 at 15:09

If your process is of Type=exec, you can use the following to wait for it to terminate after it is requested to terminate: https://github.com/systemd/systemd/issues/13284#issuecomment-784556633

# Type must be set correctly for $MAINPID detection to work
ExecStop=/usr/bin/sh -c 'while kill -0 $MAINPID 2>/dev/null; do sleep 1; done'
  • As an alternative to a shell loop with a sleep in the middle, you can use /usr/bin/tail --pid $MAINPID -f /dev/null. tail will exit as soon as the specified PID has terminated.
    – me_and
    Commented Mar 22, 2023 at 11:47

You must log in to answer this question.

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