I have been trying to set up a systemd service to only run when I power off my machine. The service is to run a script that runs a Curl command to shut down the NAS device on the network.
I have got the set up described in Example1 to work correctly except that the NAS is shut down on any system shut down (e.g. reboot) rather than only on power off. I have tried to resolve this by the set up described in Example2 but the Curl script does not appear to complete. The initial “NAS request to shutdown started” message is stored in the journal and this only happens on power off but the NAS does not shut down and the second journal message does not get logged. I am wondering if the system is completely shutting down before the Curl command completes.
Does anyone have any suggestions how I can modify the service file to work as required?
Example1
The script is as follows with file path: /etc/systemd/system/shutdown-nas
The service file is as follows with the file path: /etc/systemd/system/shutdown-nas.service
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Automatically shutdown the NAS when the system shuts down
ConditionFileIsExecutable=/etc/systemd/system/shutdown-nas
After=network-online.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/etc/systemd/system/shutdown-nas
TimeoutSec=20
[Install]
WantedBy=multi-user.target
Example2
The same bash script is used from Example1 but the service file is modified as follows:
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Automatically shutdown the NAS when the system shuts down
ConditionFileIsExecutable=/etc/systemd/system/shutdown-nas
After=network-online.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/etc/systemd/system/shutdown-nas
TimeoutSec=20
[Install]
WantedBy=poweroff.target
I don’t know if things have changed relatively recently (<4 years?),
When I was looking into doing the same thing years ago, the real problem was that even after systemd was first implemented, not all Desktops, apps and commands necessarily did a system shutdown the same way. So, for instance commonly invoking the “shutdown” binary bypasses/bypassed any systemd procedure. And, at that time KDE had its own shutdown procedure different than everyone else.
I haven’t looked into this since.
But be aware that any shutdown method you create should be carefully evaluated whether it can and would execute reliably depending on how your systems are shut down.
Also, if you create a systemd sequence of events, recommend you review the <many> types of “kill” and shut down options (eg power off is different).
By default every service gets Conflicts dependency on shutdown.target, which means it will always be stopped during any type of shutdown. So you will need to
add DefaultDependencies=false to make systemd skip adding this conflict implicitly
make your service to explicitly Conflict with poweroff.target only.
You may need to add other default dependencies in this case. See “man systemd.service” for list of default dependencies and “man bootup” for diagram of key targets systemd is using for boot and shutdown. You also likely need After dependency on network.target, because as I understand your script needs network up to contact NAS, so it should run before network is stopped on shutdown.
Thanks for the replies. The suggestion worked perfectly so the service file now looks like the following (also in case its of use to anyone the Curl command in the script file is shutting down a Netgear ReadyNas Duo):
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Automatically shutdown the NAS when the system shuts down
ConditionFileIsExecutable=/etc/systemd/system/shutdown-nas
After=network-online.target
Conflicts=poweroff.target
DefaultDependencies=false
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/etc/systemd/system/shutdown-nas
TimeoutSec=20
[Install]
WantedBy=multi-user.target
Note that network-online.target is by design optional; and you do not really need it on startup anyway. So using network.target is more appropriate here.
I assume “any type of shutdown” to mean any of the systemd shutdown options.
It’s still my impression that if you execute for example the following, everything is killed immediately ungracefully which can be handy if something is hanging other shutdown methods