first commit
This commit is contained in:
152
etc_org/init.d/sendsigs
Executable file
152
etc_org/init.d/sendsigs
Executable file
@@ -0,0 +1,152 @@
|
||||
#! /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() {
|
||||
[ -x /usr/share/apport/unkillable_shutdown ] || return
|
||||
if [ ! -e /etc/default/apport ] || ! grep -q '^enabled[[:space:]]*=[[:space:]]*1' /etc/default/apport; then
|
||||
return
|
||||
fi
|
||||
/usr/share/apport/unkillable_shutdown $OMITPIDS
|
||||
}
|
||||
|
||||
upstart_killed_jobs () {
|
||||
initctl list | grep 'stop/killed'
|
||||
}
|
||||
|
||||
upstart_jobs () {
|
||||
initctl list | grep -E '(start/|stop/killed)' | sed -n -e "/process [0-9]/s/.*process //p"
|
||||
}
|
||||
|
||||
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 $(upstart_jobs); 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=""
|
||||
OMITPIDS0="$OMITPIDS"
|
||||
for seq in 1 2 3 4 5 6 7 8 9 10; do
|
||||
OMITPIDS="$OMITPIDS0"
|
||||
# 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 $(upstart_jobs); do
|
||||
OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
|
||||
done
|
||||
fi
|
||||
if killall5 -18 $OMITPIDS ; then
|
||||
:
|
||||
else
|
||||
alldead=1
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Upstart has a method to set a kill timeout and so the job author
|
||||
# may want us to wait longer than 10 seconds (as in the case of
|
||||
# mysql). (LP: #688541)
|
||||
#
|
||||
# We will wait up to 300 seconds for any jobs in stop/killed state.
|
||||
# Any kill timeout higher than that will be overridden by the need
|
||||
# to shutdown. NOTE the re-use of seq from above, since we already
|
||||
# waited up to 10 seconds for them.
|
||||
while [ -n "$(upstart_killed_jobs)" ] ; do
|
||||
seq=$(($seq+1))
|
||||
if [ $seq -ge 300 ] ; then
|
||||
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
|
||||
|
||||
:
|
||||
Reference in New Issue
Block a user