127 lines
3.1 KiB
Bash
Executable File
127 lines
3.1 KiB
Bash
Executable File
#! /bin/sh
|
|
### BEGIN INIT INFO
|
|
# Provides: sendsigs
|
|
# Required-Start:
|
|
# Required-Stop: umountnfs
|
|
# Default-Start:
|
|
# Default-Stop: 0 6
|
|
# Short-Description: Kill all remaining processes.
|
|
# Description:
|
|
### END INIT INFO
|
|
|
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|
|
|
. /lib/lsb/init-functions
|
|
|
|
# Make it possible to see who the misbehaving processes are
|
|
report_unkillable() {
|
|
if [ -x /usr/bin/pstree ] ; then
|
|
echo "Currently running processes (pstree):"
|
|
pstree
|
|
elif [ -x /bin/ps ] ; then
|
|
echo "Currently running processes (ps):"
|
|
ps -ef
|
|
fi
|
|
}
|
|
|
|
do_stop () {
|
|
OMITPIDS=
|
|
|
|
for omitfile in /run/sendsigs.omit; do
|
|
if [ -e $omitfile ]; then
|
|
for pid in $(cat $omitfile); do
|
|
OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
|
|
done
|
|
fi
|
|
done
|
|
|
|
# Load sendsigs.omit.d/packagename files too, to make it
|
|
# possible for scripts that need to modify the list of pids at
|
|
# run time without race conditions.
|
|
for omitdir in /run/sendsigs.omit.d; do
|
|
if [ -d "${omitdir}" ]; then
|
|
for pidfile in "${omitdir}/"*; do
|
|
[ -f "$pidfile" ] || continue
|
|
for pid in $(cat $pidfile); do
|
|
OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
|
|
done
|
|
done
|
|
fi
|
|
done
|
|
|
|
# Upstart jobs have their own "stop on" clauses that sends
|
|
# SIGTERM/SIGKILL just like this, so if they're still running,
|
|
# they're supposed to be
|
|
if [ -x /sbin/initctl ]; then
|
|
for pid in $(initctl list | sed -n -e "/process [0-9]/s/.*process //p"); do
|
|
OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
|
|
done
|
|
fi
|
|
|
|
# Flush the kernel I/O buffer before we start to kill
|
|
# processes, to make sure the IO of already stopped services to
|
|
# not slow down the remaining processes to a point where they
|
|
# are accidentily killed with SIGKILL because they did not
|
|
# manage to shut down in time.
|
|
sync
|
|
|
|
# Kill all processes.
|
|
log_action_begin_msg "Asking all remaining processes to terminate"
|
|
killall5 -15 $OMITPIDS # SIGTERM
|
|
log_action_end_msg 0
|
|
alldead=""
|
|
for seq in 1 2 3 4 5 6 7 8 9 10; do
|
|
# use SIGCONT/signal 18 to check if there are
|
|
# processes left. No need to check the exit code
|
|
# value, because either killall5 work and it make
|
|
# sense to wait for processes to die, or it fail and
|
|
# there is nothing to wait for.
|
|
|
|
# did an upstart job start since we last polled initctl? check
|
|
# again on each loop and add any new jobs (e.g., plymouth) to
|
|
# the list. If we did miss one starting up, this beats waiting
|
|
# 10 seconds before shutting down.
|
|
if [ -x /sbin/initctl ]; then
|
|
for pid in $(initctl list | sed -n -e "/process [0-9]/s/.*process //p"); do
|
|
OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
|
|
done
|
|
fi
|
|
if killall5 -18 $OMITPIDS ; then
|
|
:
|
|
else
|
|
alldead=1
|
|
break
|
|
fi
|
|
|
|
sleep 1
|
|
done
|
|
if [ -z "$alldead" ] ; then
|
|
report_unkillable
|
|
log_action_begin_msg "Killing all remaining processes"
|
|
killall5 -9 $OMITPIDS # SIGKILL
|
|
log_action_end_msg 1
|
|
else
|
|
log_action_begin_msg "All processes ended within $seq seconds"
|
|
log_action_end_msg 0
|
|
fi
|
|
}
|
|
|
|
case "$1" in
|
|
start|status)
|
|
# No-op
|
|
;;
|
|
restart|reload|force-reload)
|
|
echo "Error: argument '$1' not supported" >&2
|
|
exit 3
|
|
;;
|
|
stop)
|
|
do_stop
|
|
;;
|
|
*)
|
|
echo "Usage: $0 start|stop" >&2
|
|
exit 3
|
|
;;
|
|
esac
|
|
|
|
:
|