I have two systemd services a
and b
, where b
is "After" and "BindsTo" a
, and b
is a short command that is launched every minute with a systemd timer.
Heres my config:
$ cat /systemd/a.service
[Unit]
After=foo
BindsTo=foo
[Service]
ExecStart=/opt/a/bin/a
Group=lev
User=lev
Restart=Always
WorkingDirectory=/opt/a
$ cat /systemd/b.service
[Unit]
After=a
BindsTo=a
[Service]
ExecStart=/opt/b/bin/b
Group=lev
User=lev
WorkingDirectory=/opt/b
$ cat /systemd/b.timer
[Unit]
[Timer]
OnCalendar=*:0/1:00
When I run sudo systemctl stop a
, service a
is indeed stopped, but then it is started back up at the top of the next minute when the timer for service b
runs b
The systemd documentation states that BindsTo
declares that if the unit bound to is stopped, this unit will be stopped too.
(https://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=)
I expect that by stopping a
, b
will also be stopped, and the timer disabled. This is not the case. Can you help explain why the b
timer restarts not only b
(which should fail), but also a
?
Can you also help me edit these services such that:
sudo systemctl stop a
, b
's timer does not runsudo systemctl start a
, b
's timer begins running againThanks in advance!
Here are the simplest units that meet your constraints:
test-a.service
[Service]
ExecStart=sleep 3600 # long-running command
test-b.service
[Service]
ExecStart=date # short command
test-b.timer
[Unit]
After=test-a.service
BindsTo=test-a.service # makes test-b.timer stop when test-a.service stops
[Timer]
OnCalendar=* *-*-* *:*:00
[Install]
WantedBy=test-a.service # makes test-b.timer start when test-a.service starts
Don't forget to
systemctl daemon-reload
systemctl disable test-b.timer
systemctl enable test-b.timer
To apply the changes in the [Install]
section.Explanations:
a.service
with b.timer
, not b.service
b.service
is only a short command, and systemctl start b.service
will only run the command, not start the associated timersystemctl start b.timer
will start the timerWantedBy
tells systemd to start test-b.timer
when test-a.service
startsBindsTo
tells test-b.timer
to stop when test-a.service stopsAfter
only ensures that test-b.timer
is not started at the same time than test-a.service
: it will force systemd to start test-b.timer
after test-a.service
has finished starting.About the behaviour you observed:
a.service
, the b.timer
was still active and it tried starting b.service
to run its short command. Since your b.service
specified BindsTo=a.service
, systemd thought that b.service
required a.service
to be started also, and effectively restarted a.service
for b.service
to run correctly.