[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [PATCH] rgmanager: Kill processes correctly w/ force_unmount



The killMountProcesses function was written about 10 years ago.
It was designed to work with lsof or fuser, and to log messages
for each process killed.  This is not a bad idea.  The problem
is that parsing the output of either is and error-prone,
particularly when mountpoints are similar to other directories
on the system.

A far less error-prone method to cleaning up a mount point is to
use 'fuser -kvm' on it.  Not only is this less error-prone, it's
a good bit faster at doing its job than iterating through output
in a shell script.

This patch makes force_unmount very reliable at killing the correct
processes, but we lose the logging functionality.  It is a fair
trade-off because there have been several bugs in the
killMountProcesses function over the years which have caused several
problems.

Resolves: bz555901 bz582574

Signed-off-by: Lon Hohberger <lhh redhat com>
---
 rgmanager/src/resources/fs.sh.in |  121 ++------------------------------------
 1 files changed, 5 insertions(+), 116 deletions(-)

diff --git a/rgmanager/src/resources/fs.sh.in b/rgmanager/src/resources/fs.sh.in
index 1454295..a7dd7dd 100644
--- a/rgmanager/src/resources/fs.sh.in
+++ b/rgmanager/src/resources/fs.sh.in
@@ -680,114 +680,6 @@ isAlive()
 
 
 #
-# killMountProcesses mount_point
-#
-# Using lsof or fuser try to unmount the mount by killing of the processes
-# that might be keeping it busy.
-#
-killMountProcesses()
-{
-	typeset -i ret=$SUCCESS
-	typeset have_lsof=""
-	typeset have_fuser=""
-	typeset try
-
-	if [ $# -ne 1 ]; then
-		ocf_log err \
-			"Usage: killMountProcesses mount_point"
-		return $FAIL
-	fi
-
-	typeset mp=$1
-
-	ocf_log notice "Forcefully unmounting $mp"
-
-	#
-	# Not all distributions have lsof.  If not use fuser.  If it
-	# does, try both.
-  	#
-	file=$(which lsof 2>/dev/null)
-	if [ -f "$file" ]; then
-		have_lsof=$YES
-	fi
-
-	file=$(which fuser 2>/dev/null)
-	if [ -f "$file" ]; then
-		have_fuser=$YES
-	fi             
-
-	if [ -z "$have_lsof" -a -z "$have_fuser" ]; then
-		ocf_log warn \
-	"Cannot forcefully unmount $mp; cannot find lsof or fuser commands"
-		return $FAIL
-	fi
-
-	for try in 1 2 3; do
-		if [ -n "$have_lsof" ]; then
-			#
-			# Use lsof to free up mount point
-			#
-	    		while read command pid user
-			do
-				if [ -z "$pid" ]; then
-					continue
-				fi
-
-				if [ $try -eq 1 ]; then
-					ocf_log warn \
-			 	  "killing process $pid ($user $command $mp)"
-				elif [ $try -eq 3 ]; then
-					ocf_log crit \
-		    		  "Could not clean up mountpoint $mp"
-				ret=$FAIL
-				fi
-
-				if [ $try -gt 1 ]; then
-					kill -9 $pid
-				else
-					kill -TERM $pid
-				fi
-			done < <(lsof -bn 2>/dev/null | \
-			    grep -E " $mp(/| |$)" | \
-			    awk '{print $1,$2,$3}' | \
-			    sort -u -k 1,3)
-		elif [ -n "$have_fuser" ]; then
-			#
-			# Use fuser to free up mount point
-			#
-			while read command pid user
-			do
-				if [ -z "$pid" ]; then
-					continue
-				fi
-
-				if [ $try -eq 1 ]; then
-					ocf_log warn \
-			 	  "killing process $pid ($user $command $mp)"
-				elif [ $try -eq 3 ]; then
-					ocf_log crit \
-				    "Could not clean up mount point $mp"
-					ret=$FAIL
-				fi
-
-				if [ $try -gt 1 ]; then
-					kill -9 $pid
-				else
-					kill -TERM $pid
-				fi
-			done < <(fuser -vm $mp 2>&1 | \
-			    grep -v PID | \
-			    sed 's;^'$mp:';;' | \
-			    awk '{print $4,$2,$1}' | \
-			    sort -u -k 1,3)
-		fi
-	done
-
-	return $ret
-}
-
-
-#
 # Decide which quota options are enabled and return a string 
 # which we can pass to quotaon
 #
@@ -1188,8 +1080,9 @@ stop: Could not match $OCF_RESKEY_device with a real device"
 			umount_failed=yes
 
 			if [ "$force_umount" ]; then
-				killMountProcesses $mp
 				if [ $try -eq 1 ]; then
+				  fuser -TERM -kvm $mp
+
 	        		  if [ "$OCF_RESKEY_nfslock" = "yes" ] || \
 				     [ "$OCF_RESKEY_nfslock" = "1" ]; then
 				    ocf_log warning \
@@ -1201,15 +1094,11 @@ stop: Could not match $OCF_RESKEY_device with a real device"
 				    notify_list_store $mp/.clumanager/statd
 				    nfslock_reclaim=1
 				  fi
+				else
+				  fuser -kvm $mp
 				fi
 			fi
 
-			if [ $try -ge $max_tries ]; then
-				done=$YES
-			else
-				sleep $sleep_time
-				let try=try+1
-			fi
 			;;
 		*)
 			return $FAIL
@@ -1218,7 +1107,7 @@ stop: Could not match $OCF_RESKEY_device with a real device"
 
 		if [ $try -ge $max_tries ]; then
 			done=$YES
-		elif [ "$done" -ne "$YES" ]; then
+		elif [ "$done" != "$YES" ]; then
 			sleep $sleep_time
 			let try=try+1
 		fi
-- 
1.6.2.5


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]