| #!/bin/sh |
| |
| # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Timeouts in msec |
| readonly SIGTERM_TIMEOUT=2500 |
| readonly SIGKILL_TIMEOUT=2000 |
| |
| # Send SIGTERM once to all processes that match regex in $1, then wait for |
| # them all to terminate. If processes matching $1 are still running after |
| # SIGTERM_TIMEOUT msec they are all sent SIGKILL once. If processes matching |
| # $1 are still present after SIGKILL_TIMEOUT msec a message is logged. |
| term_process() { |
| local process="$1" |
| |
| pkill "$process" |
| local i=0 |
| while [ $i -lt $SIGTERM_TIMEOUT ]; do |
| pid=$(pgrep "$process") |
| if [ $? -ne 0 ] ; then |
| return |
| fi |
| sleep .1 |
| i=$((i + 100)) |
| done |
| |
| logger -t "term_process($process)" \ |
| "PIDs ["$pid"] did not terminate, sending SIGKILL" |
| |
| pkill -KILL "$process" |
| i=0 |
| while [ $i -lt $SIGKILL_TIMEOUT ]; do |
| pid=$(pgrep "$process") |
| if [ $? -ne 0 ] ; then |
| return |
| fi |
| sleep .1 |
| i=$((i + 100)) |
| done |
| logger -t "term_process($process)" "PIDs ["$pid"] not dead after SIGKILL" |
| } |
| |
| |
| # For a given mountpoint, this will kill all processes with open files |
| # on that mountpoint so that it can be unmounted. It starts off by sending |
| # a TERM and if the process hasn't exited quickly enough it will send KILL. |
| # |
| # Since a typical shutdown should have no processes with open files on a |
| # partition that we care about at this point, we log the set of processes |
| # to /var/log/shutdown_force_kill_processes |
| kill_with_open_files_on() { |
| PIDS=$(lsof -t $@ | sort -n | uniq) |
| if [ -z "$PIDS" ] ; then |
| return # The typical case; no open files at this point. |
| fi |
| |
| # PIDS should have been empty. Since it is not, we log for future inspection. |
| lsof $@ > /var/log/shutdown_force_kill_processes |
| |
| # First try a gentle kill -TERM |
| for i in 1 2 3 4 5 6 7 8 9 10; do |
| for pid in $PIDS ; do |
| ! kill -TERM $pid |
| done |
| PIDS=$(lsof -t $@ | sort -n | uniq) |
| if [ -z "$PIDS" ] ; then |
| return |
| fi |
| sleep .1 |
| done |
| |
| # Now kill -KILL as necessary |
| PIDS=$(lsof -t $@ | sort -n | uniq) |
| for i in 1 2 3 4 5 6 7 8 9 10; do |
| for pid in $PIDS ; do |
| ! kill -KILL $pid |
| done |
| PIDS=$(lsof -t $@ | sort -n | uniq) |
| if [ -z "$PIDS" ] ; then |
| return |
| fi |
| sleep .1 |
| done |
| } |
| |
| |