Why don't my systemd shutdown scripts run?

Hi

Are you trying to run a command or scripts when your instance or server shuts down?  Is your server or instance using the new systemd process for its startup and init?  (Fedora 15 onwards use it).  If so, you may be finding, like I was, that your script just doesn't get executed.  This proved to be very frustrating for me - I lost my Sunday trying to fit systemd in my brain.  Systemd is complicated and its documentation isn't what I would call user friendly!  To save you hours of pain, here's what I found to be the issue: -

Systemd has special services "reboot.service", "poweroff.service", and "halt.service" which get defined in /lib/systemd/system (on Fedora 16 anyway).  These service files call systemctl with a --force option, and this tells it to go down hard and not to run any of the shutdown targets.  Here's an example of the poweroff.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 General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.

[Unit]
Description=Power-Off
DefaultDependencies=no
Requires=shutdown.target umount.target final.target
After=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/bin/systemctl --force poweroff

Configuring a proper systemd service for your script and putting it the shutdown.wants etc (as I did) is great and will run if you do a regular shutdown but it will not run if you like to stop your instances with "init 0", "poweroff" or "reboot" etc.   I've found the best way to catch these events and run my script is to patch the service files for these services.  We can add a 'ExecCommandPre=' service line which tells systemd to run this command before it runs the 'ExecStart=' one.  E.g. :-

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.

[Unit]
Description=Power-Off
DefaultDependencies=no
Requires=shutdown.target umount.target final.target
After=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c /usr/local/bin/myscript.sh
ExecStart=/bin/systemctl --force poweroff

If you are running a script then you should call bash (see above) and tell it to execute your script, and systemd does not provide an environment, so use full paths. Also, make sure your script has time to do what it needs before continuing - the next thing will be a hard shutdown!  Lastly, copy the services to /etc/systemd/system and modify them there (instead of /lib/systemd/system) so that they do not get reverted next time you do a yum update and the systemd rpms are updated.  Anything in /etc/systemd overrides settings in /lib/systemd.

I hope you find this useful and it saves you some time!  Whilst this may not be very elegant, it does still allow the system to do a hard shutdown after your command has run (and I found my instances did not poweroff automatically in EC2 when I removed the --force option).

regards

Dave