Reputation: 808
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!
Upvotes: 3
Views: 2003
Reputation: 1391
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.Upvotes: 1
Reputation: 1
I could be mistaken, but I believe that the "Restart=Always" option is the reason that the service named a is started and hence why the service named b is not subsequently stopped.
The man page for systemd.service states if this option is set to always
the service will be restarted regardless of whether it exited cleanly or not, got terminated abnormally by a signal, or hit a timeout.
https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=
So even though you are stopping the service, this option is starting it again.
You can test this by running the following commands. Since you have service "b" on a one minute timer, I would run the stop command at 10 seconds after the top of the minute (i.e. 10:00:10). Then I would run the status command 20 seconds later and see if the service has been restarted.
sudo systemctl stop a sudo systemctl status a b
Upvotes: -1