From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 14 Nov 2007 18:49:51 -0000 Subject: [Cluster-devel] cluster/rgmanager/src/resources netfs.sh Message-ID: <20071114184951.5486.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL4 Changes by: lhh at sourceware.org 2007-11-14 18:49:51 Modified files: rgmanager/src/resources: netfs.sh Log message: Apply patch from Marco Ceci to fix #358161 Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/netfs.sh.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.5&r2=1.1.2.6 --- cluster/rgmanager/src/resources/netfs.sh 2007/10/03 17:01:39 1.1.2.5 +++ cluster/rgmanager/src/resources/netfs.sh 2007/11/14 18:49:51 1.1.2.6 @@ -348,6 +348,112 @@ return $NO } +# +# 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 -w -bn 2>/dev/null | \ + grep -w -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 | \ + grep -v PID | \ + sed 's;^'$mp';;' | \ + awk '{print $4,$2,$1}' | \ + sort -u -k 1,3) + fi + done + + return $ret +} # # startNFSFilesystem @@ -498,8 +604,8 @@ # if [ -n "$mp" ]; then case ${OCF_RESKEY_force_unmount} in - $YES_STR) force_umount="-f" ;; - 0) force_umount="-f" ;; + $YES_STR) force_umount="$YES" ;; + 1) force_umount="$YES" ;; *) force_umount="" ;; esac fi @@ -507,6 +613,7 @@ # # Unmount # + while [ ! "$done" ]; do isMounted $fullpath $mp case $? in $NO) @@ -519,27 +626,47 @@ ;; $YES) sync; sync; sync - ocf_log info "unmounting $fullpath ($mp)" + ocf_log info "unmounting $mp" - umount $force_umount $mp + umount $mp if [ $? -eq 0 ]; then - return $SUCCESS + umount_failed= + done=$YES + continue fi umount_failed=yes + if [ "$force_umount" ]; then + killMountProcesses $mp + fi + + if [ $try -ge $max_tries ]; then + done=$YES + else + sleep $sleep_time + let try=try+1 + fi ;; *) return $FAIL ;; esac + if [ $try -ge $max_tries ]; then + done=$YES + else + sleep $sleep_time + let try=try+1 + fi + done # while if [ -n "$umount_failed" ]; then ocf_log err "'umount $fullpath' failed ($mp), error=$ret_val" return $FAIL - fi + else return $SUCCESS + fi }