mirror of https://github.com/dirtbags/moth.git
70 lines
1.7 KiB
Plaintext
70 lines
1.7 KiB
Plaintext
|
#! /bin/sh
|
||
|
|
||
|
##
|
||
|
## Signal handler for runit
|
||
|
##
|
||
|
|
||
|
if [ $PPID != 1 ]; then
|
||
|
echo "This program should only be invoked by PID 1."
|
||
|
# The reason is that killall5 won't kill anything in the same
|
||
|
# process group. That means it won't kill your invoking shell,
|
||
|
# getty, or svrun. That in turn prevents filesystems from
|
||
|
# unmounting, or even being remounted ro, since svrun (at least) has
|
||
|
# a FIFO open for writes. And if we reboot without unmounting
|
||
|
# filesystems, that's bad.
|
||
|
|
||
|
echo "Feel free to read $0 to learn why :)"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
waitall () {
|
||
|
for i in $(seq 50); do
|
||
|
# If all processes are in group 0, we're done
|
||
|
awk '($5){exit 1;}' /proc/[0-9]*/stat && return 0
|
||
|
usleep 200000
|
||
|
done
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
cleanup () {
|
||
|
echo "Stopping services..."
|
||
|
sv stop /service/*
|
||
|
echo "Asking processes to exit..."
|
||
|
killall5 -HUP
|
||
|
killall5 -TERM
|
||
|
if waitall; then
|
||
|
echo "Forcing processes to exit..."
|
||
|
killall5 -KILL
|
||
|
waitall
|
||
|
fi
|
||
|
echo "Unmounting file systems..."
|
||
|
umount -a -r
|
||
|
|
||
|
# Sometimes when we reach here we still haven't been able to umount
|
||
|
# everything. Not much more we can do about that, other than flush
|
||
|
# write buffers and hope for the best.
|
||
|
sync
|
||
|
}
|
||
|
|
||
|
case $1 in
|
||
|
1) # SIGHUP
|
||
|
;;
|
||
|
15) # SIGTERM: reboot
|
||
|
cleanup
|
||
|
echo "Rebooting..."
|
||
|
reboot -f
|
||
|
;;
|
||
|
10) # SIGUSR1: halt
|
||
|
cleanup
|
||
|
echo "Halting..."
|
||
|
halt -f
|
||
|
;;
|
||
|
12) # SIGUSR2: power
|
||
|
cleanup
|
||
|
echo "Shutting down..."
|
||
|
poweroff -f
|
||
|
;;
|
||
|
*) # Everything else
|
||
|
;;
|
||
|
esac
|