/etc/init.d/halt
stops the system from running, so nothing is going to run after that. However, assuming you aren't doing anything else fancy at shutdown (like enabling wake on LAN) it should be safe to switch off the power after /etc/init.d/umountroot
runs. It unmounts the root file system then remounts it read only. This way subsequent scripts can be read and run from disk without risk of corruption.
If you look in /etc/rc0.d
you should see symlinks to files in /etc/init.d
. On my system, I have:
...
/etc/rc0.d/S60umountroot -> /etc/init.d/umountroot
/etc/rc0.d/S90halt -> /etc/init.d/halt
Link your script to /etc/rc0.d/S80gpio_poweroff_signal
and your gpio signal will be sent after the SD card is read only.
Thanks to Nate Powell for his help answering this.
I've now found that the issue was that the service file automatically generated by systemd-sysv-generator lacks an install section with a WantedBy option. I added the following to my generated file at /etc/systemd/system/programexample.service which allowed me to properly enable the service:
[Install]
WantedBy = multi-user.target
After that I ran
systemctl daemon-reload
to ensure my service file was read by systemd.
Now I received a proper notification that my service was actually symlinked somewhere to be "enabled":
[root@centos7-box ~]# systemctl enable programexample.service
Created symlink from /etc/systemd/system/multi-user.target.wants/programexample.service to /etc/systemd/system/programexample.service.
This link helped me better understand the service file.
I am not a fan of the way that systemd-sysv-generator does not include an install section with a WantedBy option by default. If systemd can dynamically read the LSB headers and properly start services at boot, why doesn't it generate the service file accordingly? I suppose some systemd growing pains are to be expected.
Update July 7 2020:
Working with Debian Buster and trying to enable a SysVInit legacy service, I was presented with this wonderful message, which I believe would have saved me some time when I dealt with this issue in 2017:
Synchronizing state of programexample.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable programexample
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template units). This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
Best Answer
With
insserv
virtual boot facilities allow init scripts to depend on widely used functionnalities provided by groups of differents scripts or by various methods accross distributions.Depending on the
$network
target means that a configured network connection is needed. In Debian it means running thenetworking
andifupdown
initscripts, as described ininsserv.conf
.$local_fs
is used for almost every startup script as it means that every local filesystems will be mounted,$remote_fs
is obviously dependant of$network
.The scripts needed to reach this goals are not named the same on every distribution and can change from one OS version to another. As
insserv
can be configured differently to reflect this changes the initscripts depending on this facilities dont need to be changed for each particular case.The idea at the time of the design of this standart by the LSB was to make init scripts less distribution dependant, something which is now provided by
systemd
in most distributions.