From afd785be622433615a7b057c9d9aefd8bd4ef7de Mon Sep 17 00:00:00 2001 From: Anathema Date: Tue, 16 Aug 2011 02:43:15 +0200 Subject: [PATCH 1/4] fixed issue #20: created slam_tomb() that take cares about killing and checking pids --- src/tomb | 78 +++++++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/tomb b/src/tomb index b82a96d..27fb31a 100755 --- a/src/tomb +++ b/src/tomb @@ -757,6 +757,18 @@ exec_safe_post_hooks() { fi } +slam_tomb() { + # $1 = tomb mount point + local pidk p + pidk=`lsof -t "$1"` + if [[ ! -z "$pidk" ]]; then + for p in "$pidk"; do + func "killing PID $p..." + kill -9 $p + done + fi +} + umount_tomb() { local tombs how_many_tombs local pathmap mapper tombname tombmount loopdev @@ -798,26 +810,20 @@ umount_tomb() { pathmap=`dirname "$1"` if [ "${pathmap}" = "/dev/mapper" ]; then - - mapper="$1" # argument is the mapper (or none which autofills mapper) - tombname="`print $mapper | cut -d. -f2`" - tombmount=`mount -l | \ + mapper="$1" # argument is the mapper (or none which autofills mapper) + tombname="`print $mapper | cut -d. -f2`" + tombmount=`mount -l | \ awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $3 } '` - elif [ "$pathmap" = "." ]; then - - tombname="$1" # argument is the name - mapper=`mount -l | \ + tombname="$1" # argument is the name + mapper=`mount -l | \ awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $1 } '` - tombmount=`mount -l | \ + tombmount=`mount -l | \ awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $3 } '` - else - - tombmount="$1" # argument should be the mount + tombmount="$1" # argument should be the mount mapper=`mount | awk -vmnt="$tombmount" '/^\/dev\/mapper\/tomb/ { if($3==mnt) print $1 }'` - tombname="`print $mapper | cut -d. -f2`" - + tombname="`print $mapper | cut -d. -f2`" fi # avoid block when the same tomb is mounted, take only the first @@ -835,45 +841,35 @@ umount_tomb() { fi if [ $SLAM ]; then - notice "Slamming tomb $tombname mounted on $tombmount" - act "Kill all processes busy inside the tomb" - pidk=`lsof -t "$tombmount"` - for p in "$pidk"; do - pname=`pidof $p` - func "killing PID $p of $pname..." - kill -9 $p - done + notice "Slamming tomb $tombname mounted on $tombmount" + act "Kill all processes busy inside the tomb" + slam_tomb "$tombmount" else - notice "Closing tomb $tombname mounted on $tombmount" + notice "Closing tomb $tombname mounted on $tombmount" fi # check if there are binded dirs and close them tombmount_esc=`sed 's:\/:\\\/:g' <<< $tombmount ` unbind=`mount | awk "/^$tombmount_esc.*bind/"' { print $3 }'` for b in ${(f)unbind}; do - hook="`basename $b`" - act "closing tomb hook: $hook" - umount $b - if ! [ $? = 0 ]; then - if [ $SLAM ]; then - notice "Slamming tomb: killing all processes using this hook" - pidk=`lsof -t $b` - for p in "$pidk"; do - pname=`pidof $p` - notice "Killing PID $p of $pname..." - kill -9 $p - done - umount $b - else - error "Tomb hook is busy, cannot close tomb." - return 1 + hook="`basename $b`" + act "closing tomb hook: $hook" + umount $b + if ! [ $? = 0 ]; then + if [ $SLAM ]; then + notice "Slamming tomb: killing all processes using this hook" + slam_tomb "$b" + umount $b + else + error "Tomb hook is busy, cannot close tomb." + return 1 + fi fi - fi done # Execute post-hooks for eventual cleanup if ! [ $NOBIND ]; then - exec_safe_post_hooks ${tombmount%%/} close + exec_safe_post_hooks ${tombmount%%/} close fi if [ $tombmount ]; then # tomb is actively mounted From 20c1097281f99352c4e0324b8a121d4a2617b310 Mon Sep 17 00:00:00 2001 From: Anathema Date: Tue, 16 Aug 2011 02:52:01 +0200 Subject: [PATCH 2/4] feature request #21, now slam_tomb() tries to kill 3 times the pids holding the tomb, workflow: 1- kill -SIGUSR1 2- if there are remaining pids, wait 3 secs to get harder 3- kill -SIGTERM 4- if there are remaining pids, wait 3 secs to kill 'em all 5- kill -SIGKILL --- src/tomb | 109 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 30 deletions(-) diff --git a/src/tomb b/src/tomb index 27fb31a..e8ff1f3 100755 --- a/src/tomb +++ b/src/tomb @@ -757,16 +757,57 @@ exec_safe_post_hooks() { fi } +kill_tomb() { + # $1 = pids to kill + # $2 = type of kill + for p in "$1"; do + func "killing PID $p..." + if [[ "$2" == "soft" ]]; then + kill -USR1 $p + elif [[ "$2" == "hard" ]]; then + kill -TERM $p + elif [[ "$2" == "must die" ]]; then + kill -9 $p + fi + done +} + slam_tomb() { # $1 = tomb mount point - local pidk p + local pidk + pidk=`lsof -t "$1"` if [[ ! -z "$pidk" ]]; then - for p in "$pidk"; do - func "killing PID $p..." - kill -9 $p - done + kill_tomb "$pidk" "soft" + else + return 0 fi + + # if there are remaining pids + # we need to play hard + pidk=`lsof -t "$1"` + if [[ -z "$pidk" ]]; then + return 0 + fi + + sleep 3 + kill_tomb "$pidk" "hard" + pidk=`lsof -t "$1"` + if [[ -z "$pidk" ]]; then + return 0 + fi + + # if there are still some pids around + # we have to kill 'em all + sleep 3 + kill_tomb "$pidk" "must die" + pidk=`lsof -t "$1"` + if [[ -z "$pidk" ]]; then + return 0 + fi + + # what PITA! + return 1 } umount_tomb() { @@ -775,34 +816,34 @@ umount_tomb() { local ans pidk pname if ! [ $1 ]; then - tombs=`find /dev/mapper -name 'tomb.*'` - how_many_tombs=`wc -w <<< "$tombs"` - if [ "$how_many_tombs" = "0" ]; then - error "There is no open tomb to be closed" - return 1 - elif [ "$how_many_tombs" = "1" ]; then - #mapper=`find /dev/mapper -name 'tomb.*'` - func "closing mapper $tombs" - umount_tomb ${tombs} - return 1 - else - error "Too many tombs mounted, please specify which to unmount:" - ls /dev/mapper/tomb.* - error "or issue the command 'tomb close all' to clos'em all." - return 1 - fi + tombs=`find /dev/mapper -name 'tomb.*'` + how_many_tombs=`wc -w <<< "$tombs"` + if [[ "$how_many_tombs" == "0" ]]; then + error "There is no open tomb to be closed" + return 1 + elif [[ "$how_many_tombs" == "1" ]]; then + #mapper=`find /dev/mapper -name 'tomb.*'` + func "closing mapper $tombs" + umount_tomb ${tombs} + return 1 + else + error "Too many tombs mounted, please specify which to unmount:" + ls /dev/mapper/tomb.* + error "or issue the command 'tomb close all' to clos'em all." + return 1 + fi fi if [ "$1" = "all" ]; then - tombs=`find /dev/mapper -name 'tomb.*'` - if ! [ $tombs ]; then - notice "Tombs are all closed, cemetery is quiet." + tombs=`find /dev/mapper -name 'tomb.*'` + if ! [ $tombs ]; then + notice "Tombs are all closed, cemetery is quiet." + return 0 + fi + for t in ${(f)tombs}; do + umount_tomb ${t} + done return 0 - fi - for t in ${(f)tombs}; do - umount_tomb ${t} - done - return 0 fi @@ -844,6 +885,10 @@ umount_tomb() { notice "Slamming tomb $tombname mounted on $tombmount" act "Kill all processes busy inside the tomb" slam_tomb "$tombmount" + if [[ $? == 1 ]]; then + error "Cannot slam the tomb $tombname" + return 1 + fi else notice "Closing tomb $tombname mounted on $tombmount" fi @@ -855,10 +900,14 @@ umount_tomb() { hook="`basename $b`" act "closing tomb hook: $hook" umount $b - if ! [ $? = 0 ]; then + if [[ $? != 0 ]]; then if [ $SLAM ]; then notice "Slamming tomb: killing all processes using this hook" slam_tomb "$b" + if [[ $? == 1 ]]; then + error "Cannot slam the tomb $b" + return 1 + fi umount $b else error "Tomb hook is busy, cannot close tomb." From a5807344d5a18de9c038d5a778b865dbeb133808 Mon Sep 17 00:00:00 2001 From: Anathema Date: Thu, 18 Aug 2011 00:16:00 +0200 Subject: [PATCH 3/4] fix invalid kill with multiple pids --- src/tomb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tomb b/src/tomb index e8ff1f3..dde2611 100755 --- a/src/tomb +++ b/src/tomb @@ -760,14 +760,21 @@ exec_safe_post_hooks() { kill_tomb() { # $1 = pids to kill # $2 = type of kill - for p in "$1"; do + local e p + # substitute the \n with space + e=${1//$'\n'/ } + # split the string at space delim + # so we can get a for loop honestly + e=(${(s: :)e}) + for p in $e; do + echo "p $p" func "killing PID $p..." if [[ "$2" == "soft" ]]; then kill -USR1 $p elif [[ "$2" == "hard" ]]; then kill -TERM $p elif [[ "$2" == "must die" ]]; then - kill -9 $p + kill -KILL $p fi done } From 7584dc72e7bb4d42fa8452a1d897765a61c5b1d2 Mon Sep 17 00:00:00 2001 From: Anathema Date: Thu, 18 Aug 2011 11:01:17 +0200 Subject: [PATCH 4/4] added support for the --force option, which cause slam_tomb() to not wait 3 secs between kills --- src/tomb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tomb b/src/tomb index dde2611..fccbd14 100755 --- a/src/tomb +++ b/src/tomb @@ -767,7 +767,6 @@ kill_tomb() { # so we can get a for loop honestly e=(${(s: :)e}) for p in $e; do - echo "p $p" func "killing PID $p..." if [[ "$2" == "soft" ]]; then kill -USR1 $p @@ -797,7 +796,9 @@ slam_tomb() { return 0 fi - sleep 3 + # if we set the -f (force) option + # don't wait, just kill + option_is_set -f || sleep 3 kill_tomb "$pidk" "hard" pidk=`lsof -t "$1"` if [[ -z "$pidk" ]]; then @@ -806,7 +807,7 @@ slam_tomb() { # if there are still some pids around # we have to kill 'em all - sleep 3 + option_is_set -f || sleep 3 kill_tomb "$pidk" "must die" pidk=`lsof -t "$1"` if [[ -z "$pidk" ]]; then