Assuming this isn't just a problem with some sort of watchdog device, you can try hijacking the kexec
target for systemd. That's ordinarily used for loading a kdump kernel to dump memory, but you can really set up that target to do anything.
I created a systemd unit called kexec-sleep
and put it into /etc/systemd/system/kexec-sleep.service
(I'm not sure if these Requires
/After
/Before
lines are quite right, but they worked for me in a virtual machine):
[Unit]
Description=Sleep forever at kexec
DefaultDependencies=no
Requires=umount.target
After=umount.target
Before=final.target
[Service]
Type=oneshot
ExecStart=/sbin/kexec-sleep
KillMode=none
[Install]
WantedBy=kexec.target
That will call /sbin/kexec-sleep
, which is just a shell script (shown below). It attempts to remount the root filesystem read-only, so it should stay in a clean state until the device powers down. I have some sleep
s in there that are probably longer than what you need, plus a prompt at the end that will let you reboot without needing to pull the power cord.
#!/bin/sh
stty sane < /dev/console # enable automatic CRLF output on console
exec < /dev/console > /dev/console 2>&1 # redirect stdio to/from console
echo "Sleeping several seconds for processes to terminate..."
sleep 10
# kill some expected processes
killall dhclient
# sleep again...
sleep 5
echo "Processes still running:"
/bin/ps --ppid 2 -p 2 --deselect # list non-kernel processes
echo "Attempting to remount root filesystem read-only..."
sync; sync; sync
mount -o remount,ro /
grep /dev/sda /proc/mounts
while true; do
echo "System paused. Type 'reboot' to reboot"
read -p '> ' entry
if [ "$entry" = "reboot" ]; then
/sbin/reboot -f
fi
done
After creating those files, run chmod +x /sbin/kexec-sleep
and systemctl enable kexec-sleep
.
To trigger this instead of a normal shutdown, run systemctl kexec
.