I have two systemd services A
(takes a few minutes) and B
(only very few seconds):
A
has a high priority and must run under all circumstances.B
cannot be started whenA
runs, but there is no problem to startA
whenB
still runs. It is even desired to startA
even whenB
still runs, asA
must run under all circumstances.B
shouldn't be killed whenConflicts=
stops the service, instead it should still finish running.
The systemd man tells me:
Configures negative requirement dependencies. If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa.
I thought using Conflicts=A.service
might be the solution. The man tells me that starting A
will stop B
, but also what I don't want is B
will stop A
.
Is there a way to have Conflicts=
just unidirectional?
Best Answer
The
Conflict=
directive is not really what you want, not only because it works in both directions, but also because you don't want to stop the currently runningB.service
(if one is running) whenA.service
starts.The way I'd recommend you implement this is by adding an additional script to
B.service
that would check whetherA.service
is running and then preventB.service
from starting in that case.You can do that by adding an
ExecStartPre=
toB.service
that exits with a non-zero status, which will prevent it from going further in its startup.My suggestion would be to add something like this to your existing
/etc/systemd/system/B.service
:This uses
systemctl is-active
to check whether serviceA.service
is currently running.If it doesn't, it echoes a message (which will end up in the journal and, more importantly, shown whenver you check
systemctl status B.service
.) Additionally, it will exit with a non-zero status. I picked exit code 75 since systemd will show that asEX_TEMPFAIL
which means "Temporary failure; user is invited to retry." See here for how systemd interprets/names process exit codes.Line wrapping is optional too, you can simply write everyting in a single line, just omitting the trailing
\
used to wrap them.