First, with SysV init in mind, a K
script in rc0.d
makes little sense. At shutdown, you do not exit runlevel 0 (which is the "poweroff" runlevel); you enter runlevel 0, thus starting services that are in rc0.d
, not stopping them.
The only services that would be killed would be those in your previous runlevel, usually 2 or 5 (you could use the runlevel
command to check the runlevel), i.e. shutdown means rc5.d/K*
followed by rc0.d/S*
.
But your version of CentOS does not use the SysV init system; it uses systemd, which doesn't process /etc/rc*.d links in the same way as SysV init at all. Instead it performs a best-effort conversion of SysV init scripts to systemd units, generating a kill-agents.service
unit from /etc/init.d, with the rc*.d
links only being used as dependency hints. (The primary source of dependencies, however, is the LSB headers inside your init.d script – systemd does not pay attention to the link order.)
The automatic SysV conversion does not look at K*
links at, only S*
, as shutdown is automatic – systemd has service status tracking built in, and will only "stop" those services that are currently started. For the same reason, it also does not look at any links in the "shutdown" runlevels rc0.d
or rc6.d
, making your link doubly ignored.
You should write a native systemd unit for your task. (Preferably, the "agents" themselves should be a systemd service, which could then be stopped at the correct point.) See Fedora documentation on doing that.
If it's impossible to manage the "agents" as regular services and if you really need a "simple command" script that needs to do something on shutdown, the service definition would start off as:
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=/usr/local/bin/mytask.sh
That is, it would "start" on boot (doing nothing) and remain in the 'started' state until shutdown; at that point, systemd will automatically stop it and trigger the ExecStop action.
(The rest, including [Install]
, is the same as normal "start on boot" services, starting as part of multi-user.target or similar.)
It is also possible to create a simpler-looking "shutdown" service without RemainOnExit=, which hooks into shutdown.target instead of multi-user.target, but if done that way it'll be difficult to order it against the various services that are stopping on shutdown.
Also will this be triggered first before instance termination or will it be triggered after /etc/systemd services termination.
All systemd services are stopped as early as their dependencies allow, in parallel if possible. (For example, if a service is ordered Before=foo.service
, then it will be started before foo.service, and will be stopped after foo.service has finished stopping.) When two services have no ordering or dependencies against each other, they may be started and stopped in parallel.
So if you have a "one-shot" service with ExecStop, as in the above example, and if you want it to perform the "stop" action before service XYZ has been stopped, you'll need to define the opposite start dependency, i.e. After=XYZ.service
. (That is, pretend for a moment that the action is performed on startup.)
For SysV scripts, systemd reads dependencies from init.d script LSB headers but does not pay any attention to the S
or K
link order.
LSB
header in the script, and useupdate-rc.d
to do the appropriate links for you