From: Lon Hohberger <lhh@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH] rgmanager: Kill processes correctly w/ force_unmount
Date: Thu, 15 Apr 2010 14:50:48 -0400 [thread overview]
Message-ID: <1271357448-32336-1-git-send-email-lhh@redhat.com> (raw)
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
reply other threads:[~2010-04-15 18:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1271357448-32336-1-git-send-email-lhh@redhat.com \
--to=lhh@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).