I would like to have several systemd
targets, call them TargetA
, TargetB
, and TargetC
, that control a set of services, call them Service01
through Service7
. The configuration would look something like this:
TargetA
Service1
Service2
Service3
TargetB
wantsService3
Service4
Service5
TargetC
wantsService5
Service6
Service7
Goals:
- Only one target should be allowed to be enabled at a time
- The system administrator should be able to manually start and services at will
My initial setup involved:
- Each target conflicted with the other two targets
- Every service had
StopWhenUnneeded=true
enabled
This met the first requirement. Starting TargetX
stopped the other two targets. Unfortunately, this setup restricted the sysadmin. If the sysadmin ran sudo systemctl start ServiceX
the service would launch and then immediately die because it wasn't needed.
My second setup involved:
- Every target conflicted with the other two targets
- Every target also conflicted with the services that it didn't need
- No service has
StopWhenUnneeded=true
For example:
TargetA
- Wants
Service1
Service2
Service3
- Conflicts
Service4
Service5
Service6
Service7
TargetB
TargetC
- Wants
This doesn't have the desired effect.
If I run:
sudo systemctl start TargetA.target
followed by:
sudo systemctl start TargetB.target
then TargetA.target
is stopped (yay!) but Service1
and Service2
are still running.
What am I not getting? How can I get the systemd
behavior that I'm looking for?
Best Answer
Suggested approach:
systemctl isolate
to start each of the 3 targets. As documented inman systemctl
, this is a powerful command: "The isolate command will immediately stop processes that are not enabled in the new unit, possibly including the graphical environment or terminal you are currently using." Structure your target dependencies carefully! Possibly includemulti-user.target
as dependency./bin/systemctl is-active your.target
to quickly check if it returns "active" or not.