[Cluster-devel] [PATCH] rgmanager: Clean up filesystem agents

Lon Hohberger lhh at redhat.com
Mon Apr 26 20:09:09 UTC 2010


- Make mountpoints with spaces work universally
- Eliminate duplicate code
- Use fuser -kvm in all agents
- Make quotas work

Resolves: rhbz#581533 rhbz#582753 rhbz#582754

Signed-off-by: Lon Hohberger <lhh at redhat.com>
---
 rgmanager/src/resources/clusterfs.sh    |  608 +-------------------
 rgmanager/src/resources/fs.sh.in        |  795 +-------------------------
 rgmanager/src/resources/netfs.sh        |  355 ++-----------
 rgmanager/src/resources/utils/fs-lib.sh |  941 +++++++++++++++++++++++++++++++
 4 files changed, 1019 insertions(+), 1680 deletions(-)
 create mode 100644 rgmanager/src/resources/utils/fs-lib.sh

diff --git a/rgmanager/src/resources/clusterfs.sh b/rgmanager/src/resources/clusterfs.sh
index f90f865..06214d5 100644
--- a/rgmanager/src/resources/clusterfs.sh
+++ b/rgmanager/src/resources/clusterfs.sh
@@ -1,37 +1,12 @@
 #!/bin/bash
 
 #
-# File system (normal) mount/umount/fsck/etc. agent
+# Cluster File System mount/umount/fsck/etc. agent
 #
 
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
 
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-
-# Grab nfs lock tricks if available
-export NFS_TRICKS=1
-if [ -f "$(dirname $0)/svclib_nfslock" ]; then
-	. $(dirname $0)/svclib_nfslock
-	NFS_TRICKS=0
-else
-	unset OCF_RESKEY_nfslock
-fi
-
-
-. $(dirname $0)/ocf-shellfuncs
-
-
-meta_data()
+do_metadata()
 {
 	cat <<EOT
 <?xml version="1.0" ?>
@@ -182,86 +157,6 @@ EOT
 }
 
 
-verify_name()
-{
-	[ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS
-}
-
-
-verify_mountpoint()
-{
-	if [ -z "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log err "No mount point specified."
-		return $OCF_ERR_ARGS
-	fi
-
-	if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "
-			     "created at mount time."
-		return 0
-	fi
-
-	[ -d "$OCF_RESKEY_mountpoint" ] && return 0
-
-	ocf_log err "$OCF_RESKEY_mountpoint is not a directory"
-	return $OCF_ERR_ARGS
-}
-
-
-real_device()
-{
-	declare dev=$1
-	declare realdev
-
-	[ -z "$dev" ] && return 1
-
-	if [ -h "$dev" ]; then 
-		realdev=$(readlink -f $dev)
-		if [ $? -ne 0 ]; then
-			return 1
-		fi
-		echo $realdev
-		return 0
-	fi
-
-	if [ -b "$dev" ]; then
-		echo $dev
-	       	return 0
-	fi
-		
-	realdev=$(findfs $dev 2> /dev/null) 
-	if [ -n "$realdev" ] && [ -b "$realdev" ]; then
-		echo $realdev
-		return 0
-	fi
-
-	return 1
-}
-
-
-verify_device()
-{
-	declare realdev
-
-	if [ -z "$OCF_RESKEY_device" ]; then
-	       ocf_log err "No device or label specified."
-	       return $OCF_ERR_ARGS
-	fi
-
-	realdev=$(real_device $OCF_RESKEY_device)
-	if [ -n "$realdev" ]; then
-		if [ "$realdev" != "$OCF_RESKEY_device" ]; then
-			echo "Specified $OCF_RESKEY_device maps to $realdev"
-		fi
-		return $OCF_SUCCESS
-	fi
-
-	ocf_log "Device or label \"$OCF_RESKEY_device\" not valid"
-
-	return $OCF_ERR_ARGS
-}
-
-
 verify_fstype()
 {
 	# Auto detect?
@@ -328,7 +223,7 @@ verify_options()
 }
 
 
-verify_all()
+do_verify()
 {
 	verify_name || return $OCF_ERR_ARGS
 	verify_fstype || return $OCF_ERR_ARGS
@@ -338,361 +233,7 @@ verify_all()
 }
 
 
-#
-# mountInUse device mount_point
-#
-# Check to see if either the device or mount point are in use anywhere on
-# the system.  It is not required that the device be mounted on the named
-# moint point, just if either are in use.
-#
-mountInUse () {
-	typeset mp tmp_mp
-	typeset dev tmp_dev
-	typeset junk
-
-	if [ $# -ne 2 ]; then
-		ocf_log err "Usage: mountInUse device mount_point".
-		return $FAIL
-	fi
-
-	dev=$1
-	mp=$2
-
-	while read tmp_dev tmp_mp junk; do
-		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
-			return $YES
-		fi
-		
-		if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
-			return $YES
-		fi
-	done < <(mount | awk '{print $1,$3}')
-
-	return $NO
-}
-
-
-#
-# isMounted device mount_point
-#
-# Check to see if the device is mounted.  Print a warning if its not
-# mounted on the directory we expect it to be mounted on.
-#
-isMounted () {
-
-	typeset mp tmp_mp
-	typeset dev tmp_dev
-
-	if [ $# -ne 2 ]; then
-		ocf_log err "Usage: isMounted device mount_point"
-		return $FAIL
-	fi
-
-	dev=$(real_device $1)
-	if [ -z "$dev" ]; then
-		ocf_log err "isMounted: Could not match $1 with a real device"
-		return $FAIL
-	fi
-	mp=$(readlink -f $2)
-	
-	while read tmp_dev tmp_mp
-	do
-		#echo "spec=$1 dev=$dev  tmp_dev=$tmp_dev"
-		tmp_dev=$(real_device $tmp_dev)
-
-		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
-			#
-			# Check to see if its mounted in the right
-			# place
-			#
-			if [ -n "$tmp_mp"  -a "$tmp_mp"  != "$mp" ]; then
-				ocf_log warn "\
-Device $dev is mounted on $tmp_mp instead of $mp"
-			fi
-			return $YES
-		fi
-	done < <(mount | awk '{print $1,$3}')
-
-	return $NO
-}
-
-
-# 
-# isAlive mount_point
-# 
-# Check to see if mount_point is alive (testing read/write)
-# 
-isAlive()
-{
-	declare errcode
-	declare mount_point
-	declare file=".writable_test.$(hostname)"
-	declare rw
-	
-	if [ $# -ne 1 ]; then
-	        ocf_log err "Usage: isAlive mount_point"
-		return $FAIL
-	fi
-	mount_point=$1
-	
-	test -d $mount_point
-	if [ $? -ne 0 ]; then
-		ocf_log err "$mount_point is not a directory"
-		return $FAIL
-	fi
-	
-	[ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
-	
-	# depth 10 test (read test)
-	ls $mount_point > /dev/null 2> /dev/null
-	errcode=$?
-	if [ $errcode -ne 0 ]; then
-		ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode"
-		return $NO
-	fi
-	
-	[ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
-	
-	# depth 20 check (write test)
-	rw=$YES
-	for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
-                if [ "$o" = "ro" ]; then
-		        rw=$NO
-                fi
-	done
-	if [ $rw -eq $YES ]; then
-	        file=$mount_point/$file
-		while true; do
-			if [ -e "$file" ]; then
-				file=${file}_tmp
-				continue
-			else
-			        break
-			fi
-		done
-		touch $file > /dev/null 2> /dev/null
-		errcode=$?
-		if [ $errcode -ne 0 ]; then
-			ocf_log err "clusterfs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode"
-			return $NO
-		fi
-		rm -f $file > /dev/null 2> /dev/null
-	fi
-	
-	return $YES
-}
-
-
-#
-# startFilesystem
-#
-startFilesystem() {
-	typeset -i ret_val=$SUCCESS
-	typeset mp=""			# mount point
-	typeset dev=""			# device
-	typeset fstype=""
-	typeset opts=""
-	typeset device_in_use=""
-	typeset mount_options=""
-
-	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $FAIL
-	    	;;
-	esac
-	
-	#
-	# Get the device
-	#
-	dev=$(real_device $OCF_RESKEY_device)
-	if [ -z "$dev" ]; then
-			ocf_log err "\
-startFilesystem: Could not match $OCF_RESKEY_device with a real device"
-			return $FAIL
-	fi
-
-	#
-	# Ensure we've got a valid directory
-	#
-	if [ -e "$mp" ]; then
-		if ! [ -d "$mp" ]; then
-			ocf_log err "\
-startFilesystem: Mount point $mp exists but is not a directory"
-			return $FAIL
-		fi
-	else
-		ocf_log info "\
-startFilesystem: Creating mount point $mp for device $dev"
-		mkdir -p "$mp"
-		ret_val=$?
-		if [ $ret_val -ne 0 ]; then
-			ocf_log err "\
-startFilesystem: Unable to create $mp.  Error code: $ret_val"
-			return $OCF_ERR_GENERIC
-		fi
-	fi
-
-	#
-	# Get the filesystem type, if specified.
-	#
-	fstype_option=""
-	fstype=${OCF_RESKEY_fstype}
-       	case "$fstype" in 
-	""|"[ 	]*")
-		fstype=""
-		;;
-	*)	# found it
-		fstype_option="-t $fstype"
-		;;
-	esac
-
-	#
-	# See if the device is already mounted.
-	# 
-	isMounted $dev $mp
-	case $? in
-	$YES)		# already mounted
-		ocf_log debug "$dev already mounted"
-		return $SUCCESS
-		;;
-	$NO)		# not mounted, continue
-		;;
-	$FAIL)
-		return $FAIL
-		;;
-	esac
-
-
-	#
-	# Make sure that neither the device nor the mount point are mounted
-	# (i.e. they may be mounted in a different location).  The'mountInUse'
-	# function checks to see if either the device or mount point are in
-	# use somewhere else on the system.
-	#
-	mountInUse $dev $mp
-	case $? in
-	$YES)		# uh oh, someone is using the device or mount point
-		ocf_log err "\
-Cannot mount $dev on $mp, the device or mount point is already in use!"
-		return $FAIL
-		;;
-	$NO)		# good, no one else is using it
-		;;
-	$FAIL)
-		return $FAIL
-		;;
-	*)
-		ocf_log err "Unknown return from mountInUse"
-		return $FAIL
-		;;
-	esac
-
-	#
-	# Get the mount options, if they exist.
-	#
-	mount_options=""
-	opts=${OCF_RESKEY_options}
-	case "$opts" in 
-	""|"[ 	]*")
-		opts=""
-		;;
-	*)	# found it
-		mount_options="-o $opts"
-		;;
-	esac
-
-	#
-	# Mount the device
-	#
-	ocf_log debug "mount $fstype_option $mount_options $dev $mp"
-	mount $fstype_option $mount_options $dev $mp
-	ret_val=$?
-	if [ $ret_val -ne 0 ]; then
-		ocf_log err "\
-'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val"
-		return $FAIL
-	fi
-	
-	return $SUCCESS
-}
-
-
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopFilesystem() {
-	typeset -i ret_val=0
-	typeset -i try=1
-	typeset -i max_tries=3		# how many times to try umount
-	typeset -i sleep_time=2		# time between each umount failure
-	typeset -i refs=0
-	typeset done=""
-	typeset umount_failed=""
-	typeset force_umount=""
-	typeset self_fence=""
-	typeset fstype=""
-
-
-	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"stopFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $FAIL
-	    	;;
-	esac
-	
-	#
-	# Get the device
-	#
-	dev=$(real_device $OCF_RESKEY_device)
-	if [ -z "$dev" ]; then
-			ocf_log err "\
-stop: Could not match $OCF_RESKEY_device with a real device"
-			return $FAIL
-	fi
-
-
-	#
-	# Get the force unmount setting if there is a mount point.
-	#
-	if [ -n "$mp" ]; then
-		case ${OCF_RESKEY_force_unmount} in
-	        $YES_STR)	force_umount=$YES ;;
-		1)		force_umount=$YES ;;
-	        *)		force_umount="" ;;
-		esac
-	fi
-
-	if [ -n "$mp" ]; then
-		case ${OCF_RESKEY_self_fence} in
-	        $YES_STR)	self_fence=$YES ;;
-		1)		self_fence=$YES ;;
-	        *)		self_fence="" ;;
-		esac
-	fi
-
+do_pre_unmount() {
 	#
 	# Check the rgmanager-supplied reference count if one exists.
 	# If the reference count is <= 1, we can safely proceed
@@ -701,10 +242,15 @@ stop: Could not match $OCF_RESKEY_device with a real device"
 		refs=$OCF_RESKEY_RGMANAGER_meta_refcnt
 		if [ $refs -gt 0 ]; then
 			ocf_log debug "Not unmounting $OCF_RESOURCE_INSTANCE - still in use by $refs other service(s)"
-			return $OCF_SUCCESS
+			return 2
 		fi
 	fi
 
+	if [ -z "$force_umount" ]; then
+		ocf_log debug "Not umounting $dev (clustered file system)"
+		return 2
+	fi
+
 	#
 	# Always do this hackery on clustered file systems.
 	#
@@ -723,135 +269,7 @@ stop: Could not match $OCF_RESKEY_device with a real device"
 	# Always invalidate buffers on clusterfs resources
 	clubufflush -f $dev
 
-	if [ -z "$force_umount" ]; then
-		ocf_log debug "Not umounting $dev (clustered file system)"
-		return $SUCCESS
-	fi
-
-	#
-	# Unmount the device.  
-	#
-	while [ ! "$done" ]; do
-		isMounted $dev $mp
-		case $? in
-		$NO)
-			ocf_log info "$dev is not mounted"
-			umount_failed=
-			done=$YES
-			;;
-		$FAIL)
-			return $FAIL
-			;;
-		$YES)
-			sync; sync; sync
-			ocf_log info "unmounting $dev ($mp)"
-
-			umount $mp
-			if  [ $? -eq 0 ]; then
-				umount_failed=
-				done=$YES
-				continue
-			fi
-
-			umount_failed=yes
-
-			if [ "$force_umount" ]; then
-				if [ $try -eq 1 ]; then
-					fuser -TERM -kvm "$mp"
-				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
-			;;
-		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 $mp' failed, error=$ret_val"
-
-		if [ "$self_fence" ]; then
-			ocf_log alert "umount failed - REBOOTING"
-			sync
-			reboot -fn
-		fi
-		return $FAIL
-	fi
-
-	return $SUCCESS
+	return 0
 }
 
-
-case $1 in
-start)
-	declare tries=0
-	declare rv
-
-	while [ $tries -lt 3 ]; do
-		startFilesystem
-		rv=$?
-		if [ $rv -eq 0 ]; then
-			exit 0
-		fi
-
-		((tries++))
-		sleep 3
-	done
-	exit $rv
-	;;
-stop)
-	stopFilesystem
-	exit $?
-	;;
-status|monitor)
-  	isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint}
- 	[ $? -ne $YES ] && exit $OCF_ERR_GENERIC
-
- 	isAlive ${OCF_RESKEY_mountpoint}
- 	[ $? -ne $YES ] && exit $OCF_ERR_GENERIC
- 	
-	exit 0
-	;;
-restart)
-	stopFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	startFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	exit 0
-	;;
-meta-data)
-	meta_data
-	exit 0
-	;;
-validate-all)
-	verify_all
-	;;
-*)
-	echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
-	exit $OCF_ERR_UNIMPLEMENTED
-	;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/fs.sh.in b/rgmanager/src/resources/fs.sh.in
index ffa721f..77714f0 100644
--- a/rgmanager/src/resources/fs.sh.in
+++ b/rgmanager/src/resources/fs.sh.in
@@ -4,75 +4,9 @@
 # File system (normal) mount/umount/fsck/etc. agent
 #
 
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
 
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-INVALIDATEBUFFERS="/bin/true"
-
-#
-# Using a global to contain the return value saves
-# clone() operations.  This is important to reduce
-# resource consumption during status checks.
-#
-# There is no way to return a string from a function
-# in bash without cloning the process, which is exactly
-# what we are trying to avoid.  So, we have to resort
-# to using a dedicated global variable.  This one is
-# for the real_device() function below.
-#
-declare REAL_DEVICE
-
-#
-# Stub ocf_log function for when we are using 
-# quick_status, since ocf_log generally forks (and
-# sourcing ocf-shellfuncs forks -a lot-).
-#
-ocf_log()
-{
-	echo $*
-}
-
-#
-# Assume NFS_TRICKS are not available until we are
-# proved otherwise.
-#
-export NFS_TRICKS=1
-
-#
-# Quick status doesn't fork() or clone() when using
-# device files directly.  (i.e. not symlinks, LABEL= or
-# UUID=
-#
-if [ "$1" = "status" -o "$1" = "monitor" ] &&
-   [ "$OCF_RESKEY_quick_status" = "1" ]; then
-	echo Using Quick Status
-
-	# XXX maybe we can make ocf-shellfuncs have a 'quick' mode too?
-	export OCF_SUCCESS=0
-	export OCF_ERR_GENERIC=1
-else
-	#
-	# Grab nfs lock tricks if available
-	#
-	if [ -f "$(dirname $0)/svclib_nfslock" ]; then
-		. $(dirname $0)/svclib_nfslock
-		NFS_TRICKS=0
-	fi
-
-	. $(dirname $0)/ocf-shellfuncs
-fi
-
-meta_data()
+do_metadata()
 {
 	cat <<EOT
 <?xml version="1.0" encoding="ISO-8859-1" ?>
@@ -254,109 +188,6 @@ meta_data()
 EOT
 }
 
-verify_name()
-{
-	if [ -z "$OCF_RESKEY_name" ]; then
-		ocf_log err "No file system name specified."
-		return $OCF_ERR_ARGS
-	fi
-	return $OCF_SUCCESS
-}
-
-
-verify_mountpoint()
-{
-	if [ -z "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log err "No mount point specified."
-		return $OCF_ERR_ARGS
-	fi
-
-	if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\
-				"created at mount time."
-		return $OCF_SUCCESS
-	fi
-
-	[ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS
-
-	ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory."
-	
-	return $OCF_ERR_ARGS
-}
-
-
-#
-# This used to be called using $(...), but doing this causes bash
-# to set up a pipe and clone().  So, the output of this function is
-# stored in the global variable REAL_DEVICE, declared previously.
-#
-real_device()
-{
-	declare dev=$1
-	declare realdev
-
-	REAL_DEVICE=""
-
-	[ -z "$dev" ] && return $OCF_ERR_ARGS
-
-	# If our provided blockdev is a device, we are done
-	if [ -b "$dev" ]; then
-		REAL_DEVICE="$dev"
-	       	return $OCF_SUCCESS
-	fi
-
-	# Oops, we have a link.  Sorry, this is going to fork.
-	if [ -h "$dev" ]; then 
-		realdev=$(readlink -f $dev)
-		if [ $? -ne 0 ]; then
-			return $OCF_ERR_ARGS
-		fi
-		REAL_DEVICE="$realdev"
-		return $OCF_SUCCESS
-	fi
-
-	# It's not a link, it's not a block device.  If it also
-	# does not match UUID= or LABEL=, then findfs is not 
-	# going to find anything useful, so we should quit now.
-	if [ "${dev/UUID=/}" = "$dev" ] &&
-	   [ "${dev/LABEL=/}" = "$dev" ]; then
-		return $OCF_ERR_GENERIC
-	fi
-	
-	# When using LABEL= or UUID=, we can't save a fork.
-	realdev=$(findfs $dev 2> /dev/null)
-	if [ -n "$realdev" ] && [ -b "$realdev" ]; then
-		REAL_DEVICE="$realdev"
-		return $OCF_SUCCESS
-	fi
-
-	return $OCF_ERR_GENERIC
-}
-
-
-verify_device()
-{
-	declare realdev
-
-	if [ -z "$OCF_RESKEY_device" ]; then
-	       ocf_log err "No device or label specified."
-	       return $OCF_ERR_ARGS
-	fi
-
-	real_device $OCF_RESKEY_device
-	realdev=$REAL_DEVICE
-	if [ -n "$realdev" ]; then
-		if [ "$realdev" != "$OCF_RESKEY_device" ]; then
-			ocf_log info "Specified $OCF_RESKEY_device maps to $realdev"
-		fi
-		return $OCF_SUCCESS
-	fi
-
-	ocf_log err "Device or label \"$OCF_RESKEY_device\" not valid"
-
-	return $OCF_ERR_ARGS
-}
-
 
 verify_fstype()
 {
@@ -396,6 +227,8 @@ verify_options()
 			;;
 		esac
 
+		do_verify_option $OCF_RESKEY_fstype "$o"
+
 		case $OCF_RESKEY_fstype in
 		ext2|ext3|ext4)
 			case $o in
@@ -500,7 +333,7 @@ verify_options()
 }
 
 
-verify_all()
+do_validate()
 {
 	verify_name || return $OCF_ERR_ARGS
 	verify_fstype || return $OCF_ERR_ARGS
@@ -510,389 +343,9 @@ verify_all()
 }
 
 
-#
-# mountInUse device mount_point
-#
-# Check to see if either the device or mount point are in use anywhere on
-# the system.  It is not required that the device be mounted on the named
-# moint point, just if either are in use.
-#
-mountInUse () {
-	typeset mp tmp_mp
-	typeset dev tmp_dev
-	typeset junka junkb junkc junkd
-
-	if [ $# -ne 2 ]; then
-		ocf_log err "Usage: mountInUse device mount_point".
-		return $FAIL
-	fi
-
-	dev=$1
-	mp=$2
-
-	while read tmp_dev tmp_mp junka junkb junkc junkd; do
-		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
-			return $YES
-		fi
-		
-		if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
-			return $YES
-		fi
-	done < /proc/mounts
-
-	return $NO
-}
-
-
-#
-# isMounted device mount_point
-#
-# Check to see if the device is mounted.  Print a warning if its not
-# mounted on the directory we expect it to be mounted on.
-#
-isMounted () {
-
-	typeset mp tmp_mp
-	typeset dev tmp_dev
-	typeset ret=$FAIL
-	typeset found=1
-	typeset poss_mp
-
-	if [ $# -ne 2 ]; then
-		ocf_log err "Usage: isMounted device mount_point"
-		return $FAIL
-	fi
-
-	real_device $1
-	dev=$REAL_DEVICE
-	if [ -z "$dev" ]; then
-		ocf_log err \
-			"fs (isMounted): Could not match $1 with a real device"
-		return $OCF_ERR_ARGS
-	fi
-
-	if [ -h "$2" ]; then
-		mp=$(readlink -f $2)
-	else
-		mp=$2
-	fi
-
-	ret=$NO
-
-	while read tmp_dev tmp_mp junk_a junk_b junk_c junk_d
-	do
-		real_device $tmp_dev
-		tmp_dev=$REAL_DEVICE
-
-		# This bash glyph simply removes a trailing slash
-		# if one exists.  /a/b/ -> /a/b; /a/b -> /a/b.
-		tmp_mp=${tmp_mp%/}
-		mp=${mp%/}
-
-		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
-			#
-			# Check to see if its mounted in the right
-			# place
-			#
-			if [ -n "$tmp_mp" ]; then
-				if [ "$tmp_mp" != "$mp" ]; then
-					poss_mp=$tmp_mp
-				else
-					found=0
-				fi
-			fi
-			ret=$YES
-		fi
-	done < /proc/mounts
-
-	if [ $ret -eq $YES ] && [ $found -ne 0 ]; then
-		ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp"
-	fi
-
-	return $ret
-}
-
-
-# 
-# isAlive mount_point
-# 
-# Check to see if mount_point is alive (testing read/write)
-# 
-isAlive()
+do_pre_mount()
 {
-	declare errcode
-	declare mount_point
-	declare file=".writable_test"
-	declare rw
-	
-	if [ $# -ne 1 ]; then
-	        ocf_log err "Usage: isAlive mount_point"
-		return $FAIL
-	fi
-	mount_point=$1
-	
-	test -d $mount_point
-	if [ $? -ne 0 ]; then
-		ocf_log err "fs (isAlive): $mount_point is not a directory"
-		return $FAIL
-	fi
-	
-	[ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
-	
-	# depth 10 test (read test)
-	ls $mount_point > /dev/null 2> /dev/null
-	errcode=$?
-	if [ $errcode -ne 0 ]; then
-		ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed read test on [$mount_point]. Return code: $errcode"
-		return $NO
-	fi
-	
-	[ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
-	
-	# depth 20 check (write test)
-	rw=$YES
-	for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
-                if [ "$o" = "ro" ]; then
-		        rw=$NO
-                fi
-	done
-	if [ $rw -eq $YES ]; then
-	        file=$mount_point/$file
-		while true; do
-			if [ -e "$file" ]; then
-				file=${file}_tmp
-				continue
-			else
-			        break
-			fi
-		done
-		touch $file > /dev/null 2> /dev/null
-		errcode=$?
-		if [ $errcode -ne 0 ]; then
-			ocf_log err "fs:${OCF_RESKEY_name}: isAlive failed write test on [$mount_point]. Return code: $errcode"
-			return $NO
-		fi
-		rm -f $file > /dev/null 2> /dev/null
-	fi
-	
-	return $YES
-}
-
-
-#
-# Decide which quota options are enabled and return a string 
-# which we can pass to quotaon
-#
-quota_opts()
-{
-	declare quotaopts=""
-	declare opts=$1
-	declare mopt
-
-	for mopt in `echo $opts | sed -e s/,/\ /g`; do
-		case $mopt in
-		usrquota)
-			quotaopts="u$quotaopts"
-			continue
-			;;
-		grpquota)
-			quotaopts="g$quotaopts"
-			continue
-			;;
-		noquota)
-			quotaopts=""
-			return 0
-			;;
-		esac
-	done
-
-	echo $quotaopts
-	return 0
-}
-
-
-
-#
-# Enable quotas on the mount point if the user requested them
-#
-enable_fs_quotas()
-{
-	declare -i need_check=0
-	declare -i rv
-	declare quotaopts=""
-	declare mopt
-	declare opts=$1
-	declare mp=$2
-
-	if [ -z "`which quotaon`" ]; then
-		ocf_log err "quotaon not found in $PATH"
-		return $OCF_ERR_GENERIC
-	fi
-
-	quotaopts=$(quota_opts $opts)
-
-	ocf_log info "quotaopts = $quotaopts"
-
-	[ -z "$quotaopts" ] && return 0
-
-	# Ok, create quota files if they don't exist
-	for f in quota.user aquota.user quota.group aquota.group; do
-		if ! [ -f "$mp/$f" ]; then
-			ocf_log info "$mp/$f was missing - creating"
-			touch "$mp/$f" 
-			chmod 600 "$mp/$f"
-			need_check=1
-		fi
-	done
-
-	if [ $need_check -eq 1 ]; then
-		ocf_log info "Checking quota info in $mp"
-		quotacheck -$quotaopts "$mp"
-	fi
-
-	ocf_log info "Enabling Quotas on $mp"
-	ocf_log debug "quotaon -$quotaopts \"$mp\""
-	quotaon -$quotaopts "$mp"
-	rv=$?
-	if [ $rv -ne 0 ]; then
-		# Just a warning
-		ocf_log warn "Unable to turn on quotas for $mp; return = $rv"
-	fi
-
-	return $rv
-}
-
-
-#
-# startFilesystem
-#
-startFilesystem() {
-	typeset -i ret_val=$SUCCESS
-	typeset mp=""			# mount point
-	typeset dev=""			# device
-	typeset fstype=""
-	typeset opts=""
-	typeset device_in_use=""
-	typeset mount_options=""
-
-	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $OCF_SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $OCF_ERR_ARGS
-	    	;;
-	esac
-	
-	#
-	# Get the device
-	#
-	real_device $OCF_RESKEY_device
-	dev=$REAL_DEVICE
-	if [ -z "$dev" ]; then
-			ocf_log err "\
-startFilesystem: Could not match $OCF_RESKEY_device with a real device"
-			return $OCF_ERR_ARGS
-	fi
-
-	#
-	# Ensure we've got a valid directory
-	#
-	if [ -e "$mp" ]; then
-		if ! [ -d "$mp" ]; then
-			ocf_log err"\
-startFilesystem: Mount point $mp exists but is not a directory"
-			return $OCF_ERR_ARGS
-		fi
-	else
-		ocf_log err "\
-startFilesystem: Creating mount point $mp for device $dev"
-		mkdir -p "$mp"
-		ret_val=$?
-		if [ $ret_val -ne 0 ]; then
-			ocf_log err "\
-startFilesystem: Unable to create $mp.  Error code: $ret_val"
-			return $OCF_ERR_GENERIC
-		fi
-	fi
-
-	#
-	# Get the filesystem type, if specified.
-	#
-	fstype_option=""
-	fstype=${OCF_RESKEY_fstype}
-       	case "$fstype" in 
-	""|"[ 	]*")
-		fstype=""
-		;;
-	*)	# found it
-		fstype_option="-t $fstype"
-		;;
-	esac
-
-	#
-	# See if the device is already mounted.
-	# 
-	isMounted $dev "$mp"
-	case $? in
-	$YES)		# already mounted
-		ocf_log debug "$dev already mounted"
-		return $OCF_SUCCESS
-		;;
-	$NO)		# not mounted, continue
-		;;
-	*)
-		return $FAIL
-		;;
-	esac
-
-
-	#
-	# Make sure that neither the device nor the mount point are mounted
-	# (i.e. they may be mounted in a different location).  The'mountInUse'
-	# function checks to see if either the device or mount point are in
-	# use somewhere else on the system.
-	#
-	mountInUse $dev "$mp"
-	case $? in
-	$YES)		# uh oh, someone is using the device or mount point
-		ocf_log err "\
-Cannot mount $dev on $mp, the device or mount point is already in use!"
-		return $FAIL
-		;;
-	$NO)		# good, no one else is using it
-		;;
-	$FAIL)
-		return $FAIL
-		;;
-	*)
-		ocf_log err "Unknown return from mountInUse"
-		return $FAIL
-		;;
-	esac
-
-	#
-	# Get the mount options, if they exist.
-	#
-	mount_options=""
-	opts=${OCF_RESKEY_options}
-	case "$opts" in 
-	""|"[ 	]*")
-		opts=""
-		;;
-	*)	# found it
-		mount_options="-o $opts"
-		;;
-	esac
-
+	declare fstype="$OCF_RESKEY_fstype"
 
 	#
 	# Check to determine if we need to fsck the filesystem.
@@ -936,24 +389,15 @@ Unknown file system type '$fstype' for device $dev.  Assuming fsck is required."
 'fsck -p $dev' failed, error=$ret_val; check $fsck_log for errors"
 			ocf_log debug "Invalidating buffers for $dev"
 			$INVALIDATEBUFFERS -f $dev
-			return $FAIL
+			return $OCF_ERR_GENERIC
 		fi
 		rm -f $fsck_log
 	fi
 
-	#
-	# Mount the device
-	#
-	ocf_log info "mounting $dev on $mp"
-	ocf_log debug "mount $fstype_option $mount_options $dev $mp"
-	mount $fstype_option $mount_options $dev "$mp"
-	ret_val=$?
-	if [ $ret_val -ne 0 ]; then
-		ocf_log err "\
-'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val"
-		return $FAIL
-	fi
+	return 0
+}
 
+do_post_mount() {
 	#
 	# Create this for the NFS NLM broadcast bit
 	#
@@ -965,218 +409,35 @@ Unknown file system type '$fstype' for device $dev.  Assuming fsck is required."
 		fi
 	fi
 
-	enable_fs_quotas $opts "$mp"
-	
-	return $SUCCESS
+	return 0
 }
 
 
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopFilesystem() {
-	typeset -i ret_val=0
-	typeset -i try=1
-	typeset -i max_tries=3		# how many times to try umount
-	typeset -i sleep_time=5		# time between each umount failure
-	typeset -i nfslock_reclaim=0
-	typeset done=""
-	typeset umount_failed=""
-	typeset force_umount=""
-	typeset self_fence=""
-	typeset fstype=""
-	typeset quotaopts=""
-
+do_force_unmount() {
+	if [ "$OCF_RESKEY_nfslock" = "yes" ] || \
+	   [ "$OCF_RESKEY_nfslock" = "1" ]; then
+		ocf_log warning "Dropping node-wide NFS locks"
+		pkill -KILL -x lockd
+		mkdir -p "$mp"/.clumanager/statd
+		# Copy out the notify list; our 
+		# IPs are already torn down
+		notify_list_store "$mp"/.clumanager/statd
 
-	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"stopFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $FAIL
-	    	;;
-	esac
-	
-
-	#
-	# Get the device
-	#
-	real_device $OCF_RESKEY_device
-	dev=$REAL_DEVICE
-	if [ -z "$dev" ]; then
-			ocf_log err "\
-stop: Could not match $OCF_RESKEY_device with a real device"
-			return $FAIL
-	fi
-
-	#
-	# Get the force unmount setting if there is a mount point.
-	#
-	if [ -n "$mp" ]; then
-		case ${OCF_RESKEY_force_unmount} in
-	        $YES_STR)	force_umount=$YES ;;
-		1)		force_umount=$YES ;;
-	        *)		force_umount="" ;;
-		esac
-	fi
-
-	if [ -n "$mp" ]; then
-		case ${OCF_RESKEY_self_fence} in
-	        $YES_STR)	self_fence=$YES ;;
-		1)		self_fence=$YES ;;
-	        *)		self_fence="" ;;
-		esac
+		# Save for post-umount phase
+		export nfslock_reclaim=1
 	fi
 
-	#
-	# Unmount the device.  
-	#
-	while [ ! "$done" ]; do
-		isMounted $dev "$mp"
-		case $? in
-		$NO)
-			ocf_log info "$dev is not mounted"
-			umount_failed=
-			done=$YES
-			;;
-		$FAIL)
-			return $FAIL
-			;;
-		$YES)
-			sync; sync; sync
-			quotaopts=$(quota_opts $OCF_RESKEY_options)
-			if [ -n "$quotaopts" ]; then
-				ocf_log debug "Turning off quotas for $mp"
-				quotaoff -$quotaopts "$mp" &> /dev/null
-			fi
-
-
-			ocf_log info "unmounting $mp"
-			umount "$mp"
-			if  [ $? -eq 0 ]; then
-				umount_failed=
-				done=$YES
-				continue
-			fi
-
-			umount_failed=yes
-
-			if [ "$force_umount" ]; then
-				if [ $try -eq 1 ]; then
-				  fuser -TERM -kvm "$mp"
-
-	        		  if [ "$OCF_RESKEY_nfslock" = "yes" ] || \
-				     [ "$OCF_RESKEY_nfslock" = "1" ]; then
-				    ocf_log warning \
-					"Dropping node-wide NFS locks"
-				    pkill -KILL -x lockd
-				    mkdir -p "$mp"/.clumanager/statd
-				    # Copy out the notify list; our 
-				    # IPs are already torn down
-				    notify_list_store "$mp"/.clumanager/statd
-				    nfslock_reclaim=1
-				  fi
-				else
-				  fuser -kvm "$mp"
-				fi
-			fi
-
-			;;
-		*)
-			return $FAIL
-			;;
-		esac
+	return 0
+}
 
-		if [ $try -ge $max_tries ]; then
-			done=$YES
-		elif [ "$done" != "$YES" ]; then
-			sleep $sleep_time
-			let try=try+1
-		fi
-	done # while 
 
+do_post_unmount() {
 	if [ $nfslock_reclaim -eq 1 ]; then
 		# If we have this flag set, do a full reclaim broadcast
 		notify_list_broadcast "$mp"/.clumanager/statd
 	fi
 
-	if [ -n "$umount_failed" ]; then
-		ocf_log err "'umount $mp' failed, error=$ret_val"
-
-		if [ "$self_fence" ]; then
-			ocf_log alert "umount failed - REBOOTING"
-			sync
-			reboot -fn
-		fi
-		return $FAIL
-	else
-		return $SUCCESS
-	fi
+	return 0
 }
 
-
-case $1 in
-start)
-	startFilesystem
-	exit $?
-	;;
-stop)
-	stopFilesystem
-	exit $?
-	;;
-status|monitor)
-  	isMounted ${OCF_RESKEY_device} ${OCF_RESKEY_mountpoint}
-
- 	if [ $? -ne $YES ]; then
-		ocf_log err "fs:${OCF_RESKEY_name}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}"
-		exit $OCF_ERR_GENERIC
-	fi
-
-	if [ "$OCF_RESKEY_quick_status" = "1" ]; then
-		exit 0
-	fi
-
- 	isAlive ${OCF_RESKEY_mountpoint}
- 	[ $? -eq $YES ] && exit 0
-
-	ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!"
-	exit $OCF_ERR_GENERIC
-	;;
-restart)
-	stopFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	startFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	exit 0
-	;;
-meta-data)
-	meta_data
-	exit 0
-	;;
-validate-all)
-	verify_all
-	exit $?
-	;;
-*)
-	echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
-	exit $OCF_ERR_UNIMPLEMENTED
-	;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/netfs.sh b/rgmanager/src/resources/netfs.sh
index bb749f7..55b8ef8 100644
--- a/rgmanager/src/resources/netfs.sh
+++ b/rgmanager/src/resources/netfs.sh
@@ -4,25 +4,9 @@
 # NFS/CIFS file system mount/umount/etc. agent
 #
 
-LC_ALL=C
-LANG=C
-PATH=/bin:/sbin:/usr/bin:/usr/sbin
-export LC_ALL LANG PATH
+. $(dirname $0)/utils/fs-lib.sh
 
-#
-# XXX todo - search and replace on these
-#
-SUCCESS=0
-FAIL=2
-YES=0
-NO=1
-YES_STR="yes"
-
-
-. $(dirname $0)/ocf-shellfuncs
-
-
-meta_data()
+do_metadata()
 {
 	cat <<EOT
 <?xml version="1.0" ?>
@@ -154,33 +138,6 @@ EOT
 }
 
 
-verify_name()
-{
-	[ -n "$OCF_RESKEY_name" ] || exit $OCF_ERR_ARGS
-}
-
-
-verify_mountpoint()
-{
-	if [ -z "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log err "No mount point specified."
-		return $OCF_ERR_ARGS
-	fi
-
-	if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
-		ocf_log info "Mount point $OCF_RESKEY_mountpoint will be created "\
-		     "at mount time."
-		return 0
-	fi
-
-	[ -d "$OCF_RESKEY_mountpoint" ] && return 0
-
-	ocf_log err "$OCF_RESKEY_mountpoint is not a directory"
-	
-	return 1
-}
-
-
 verify_host()
 {
 	if [ -z "$OCF_RESKEY_host" ]; then
@@ -298,116 +255,45 @@ verify_options()
 }
 
 
-verify_all()
+do_validate()
 {
 	verify_name || return $OCF_ERR_ARGS
 	verify_fstype|| return $OCF_ERR_ARGS
 	verify_host || return $OCF_ERR_ARGS
 	verify_mountpoint || return $OCF_ERR_ARGS
 	verify_options || return $OCF_ERR_ARGS
+	# verify_target || return $OCF_ERR_ARGS
 }
 
 
-
 #
-# isMounted fullpath mount_point
+# Override real_device to use fs-lib's functions for start/stopfilesystem
 #
-# Check to see if the full path is mounted where we need it.
-#
-isMounted () {
-
-	typeset mp tmp_mp
-	typeset fullpath tmp_fullpath
-
-	if [ $# -ne 2 ]; then
-		ocf_log err "Usage: isMounted host:/export mount_point"
-		return $FAIL
-	fi
-
-	fullpath=$1
-	mp=$(readlink -f $2)
-
-	while read tmp_fullpath tmp_mp
-	do
-		if [ "$tmp_fullpath" = "$fullpath" -a \
-		     "$tmp_mp" = "$mp" ]; then
-			return $YES
-		fi
-	done < <(mount | awk '{print $1,$3}')
-
-	return $NO
+real_device() {
+	export REAL_DEVICE="$1"
 }
 
+
 #
-# startNFSFilesystem
+# do_mount - nfs / cifs are mounted differently than blockdevs
 #
-startNFSFilesystem() {
-	typeset -i ret_val=$SUCCESS
-	typeset mp=""			# mount point
-	typeset host=""
-	typeset fullpath=""
-	typeset exp=""
-	typeset opts=""
-	typeset mount_options=""
+do_mount() {
+	declare opts=""
+	declare mount_options=""
+	declare ret_val
+	declare mp="$OCF_RESKEY_mountpoint"
 
 	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"startFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $FAIL
-	    	;;
-	esac
-	#
-	# Get the device
+	# Get the filesystem type, if specified.
 	#
-	host=${OCF_RESKEY_host}
-	exp=${OCF_RESKEY_export}
-
-	fullpath=$host:$exp
-
-	#
-	# Ensure we've got a valid directory
-	#
-	if [ -e "$mp" ]; then
-		if ! [ -d "$mp" ]; then
-			ocf_log err "\
-startFilesystem: Mount point $mp exists but is not a directory"
-			return $FAIL
-		fi
-	else
-		ocf_log info "\
-startFilesystem: Creating mount point $mp for $fullpath"
-		mkdir -p "$mp"
-		ret_val=$?
-		if [ $ret_val -ne 0 ]; then
-			ocf_log err "\
-startFilesystem: Unable to create $mp.  Error code: $ret_val"
-			return $OCF_ERR_GENERIC
-		fi
-	fi
-
-	#
-	# See if the mount path is already mounted.
-	# 
-	isMounted $fullpath $mp
-	case $? in
-	$YES)		# already mounted
-		ocf_log debug "$fullpath already mounted on $mp"
-		return $SUCCESS
-		;;
-	$NO)		# not mounted, continue
+	fstype_option=""
+	fstype=${OCF_RESKEY_fstype}
+       	case "$fstype" in 
+	""|"[ 	]*")
+		fstype=""
 		;;
-	$FAIL)
-		return $FAIL
+	*)	# found it
+		fstype_option="-t $fstype"
 		;;
 	esac
 
@@ -425,155 +311,29 @@ startFilesystem: Unable to create $mp.  Error code: $ret_val"
 		;;
 	esac
 
-	#
-	# Mount the NFS export
-	#
-	ocf_log debug "mount $fstype_option $mount_options $fullpath $mp"
-
         case $OCF_RESKEY_fstype in
-		nfs|nfs4)
-			mount -t $OCF_RESKEY_fstype $mount_options $host:$exp $mp
-			;;
-		cifs)
-			mount -t $OCF_RESKEY_fstype $mount_options //$host/$exp $mp
-			;;
+	nfs|nfs4)
+		mount -t $OCF_RESKEY_fstype $mount_options $OCF_RESKEY_host:"$OCF_RESKEY_export" "$mp"
+		;;
+	cifs)
+		mount -t $OCF_RESKEY_fstype $mount_options //$OCF_RESKEY_host/"$OCF_RESKEY_export" "$mp"
+		;;
 	esac
 
 	ret_val=$?
 	if [ $ret_val -ne 0 ]; then
 		ocf_log err "\
-'mount $fstype_option $mount_options $fullpath $mp' failed, error=$ret_val"
-		return $FAIL
+'mount $fstype_option $mount_options $OCF_RESKEY_host:$OCF_RESKEY_export $mp' failed, error=$ret_val"
+		return 1
 	fi
 	
-	return $SUCCESS
+	return 0
 }
 
 
-#
-# stopFilesystem serviceID deviceID
-#
-# Run the stop actions
-#
-stopNFSFilesystem() {
-	typeset -i ret_val=0
-	typeset -i try=1
-	typeset -i max_tries=3		# how many times to try umount
-	typeset -i sleep_time=2		# time between each umount failure
-	typeset done=""
-	typeset umount_failed=""
-	typeset no_umount=""
-	typeset force_umount=""
-	typeset fstype=""
-
-
-	#
-	# Get the mount point, if it exists.  If not, no need to continue.
-	#
-	mp=${OCF_RESKEY_mountpoint}
-	case "$mp" in 
-      	""|"[ 	]*")		# nothing to mount
-    		return $SUCCESS
-    		;;
-	/*)			# found it
-	  	;;
-	*)	 		# invalid format
-			ocf_log err \
-"stopNFSFilesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
-	    	return $FAIL
-	    	;;
-	esac
-	
-	#
-	# Get the host/path
-	#
-	fullpath="${OCF_RESKEY_host}:${OCF_RESKEY_export}"
-
-	#
-	# Get the force unmount setting if there is a mount point.
-	#
-	if [ -n "$mp" ]; then
-		case ${OCF_RESKEY_force_unmount} in
-	        $YES_STR)	force_umount="$YES" ;;
-		1)		force_umount="$YES" ;;
-	        *)		force_umount="" ;;
-		esac
-	fi
-
-	#
-	# Unmount
-	#
-        while [ ! "$done" ]; do
-	isMounted $fullpath $mp
-	case $? in
-	$NO)
-		ocf_log debug "$fullpath is not mounted"
-		umount_failed=
-		done=$YES
-		;;
-	$FAIL)
-		return $FAIL
-		;;
-	$YES)
-		case ${OCF_RESKEY_no_unmount} in
-                $YES_STR)       no_umount="$YES" ;;
-                1)              no_umount="$YES" ;;
-                *)              no_umount="" ;;
-                esac
-		
-		if [ "$no_umount" ]; then
-				ocf_log info "skipping unmount operation of $mp"
-				return $SUCCESS
-		fi
-
-		sync; sync; sync
-                        ocf_log info "unmounting $mp"
-
-                        umount $mp
-		if  [ $? -eq 0 ]; then
-                                umount_failed=
-                                done=$YES
-                                continue
-		fi
-
-		umount_failed=yes
-
-		if [ "$force_umount" ]; then
-			if [ $try -eq 1 ]; then
-				fuser -TERM -kvm "$mp"
-			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
-		;;
-	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
-
-	return $SUCCESS
-}
+#do_force_unmount() {
+#	umount -f "$OCF_RESKEY_mountpoint"
+#}
 
 
 populate_defaults()
@@ -585,54 +345,13 @@ populate_defaults()
 	if [ -z "$OCF_RESKEY_options" ]; then
 		export OCF_RESKEY_options=sync,soft,noac
 	fi
+
+	export OCF_RESKEY_device="$OCF_RESKEY_host:$OCF_RESKEY_export"
 }
 
 
 #
 # Main...
 #
-
 populate_defaults
-
-case $1 in
-start)
-	startNFSFilesystem
-	exit $?
-	;;
-stop)
-	stopNFSFilesystem
-	exit $?
-	;;
-status|monitor)
-	isMounted ${OCF_RESKEY_host}:${OCF_RESKEY_export} \
-		${OCF_RESKEY_mountpoint}
-	exit $?
-	;;
-restart)
-	stopNFSFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	startNFSFilesystem
-	if [ $? -ne 0 ]; then
-		exit $OCF_ERR_GENERIC
-	fi
-
-	exit 0
-	;;
-meta-data)
-	meta_data
-	exit 0
-	;;
-validate-all)
-	verify_all
-	exit $?
-	;;
-*)
-	echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
-	exit $OCF_ERR_UNIMPLEMENTED
-	;;
-esac
-
-exit 0
+main $*
diff --git a/rgmanager/src/resources/utils/fs-lib.sh b/rgmanager/src/resources/utils/fs-lib.sh
new file mode 100644
index 0000000..55d2778
--- /dev/null
+++ b/rgmanager/src/resources/utils/fs-lib.sh
@@ -0,0 +1,941 @@
+#!/bin/bash
+
+#
+# File system common functions
+#
+
+LC_ALL=C
+LANG=C
+PATH=/bin:/sbin:/usr/bin:/usr/sbin
+export LC_ALL LANG PATH
+
+# Private return codes
+FAIL=2
+NO=1
+YES=0
+YES_STR="yes"
+
+[ -z "$OCF_RESOURCE_INSTANCE" ] && export OCF_RESOURCE_INSTANCE="filesystem:$OCF_RESKEY_name"
+
+#
+# Using a global to contain the return value saves
+# clone() operations.  This is important to reduce
+# resource consumption during status checks.
+#
+# There is no way to return a string from a function
+# in bash without cloning the process, which is exactly
+# what we are trying to avoid.  So, we have to resort
+# to using a dedicated global variable.  This one is
+# for the real_device() function below.
+#
+declare REAL_DEVICE
+
+#
+# Stub ocf_log function for when we are using 
+# quick_status, since ocf_log generally forks (and
+# sourcing ocf-shellfuncs forks -a lot-).
+#
+ocf_log()
+{
+	echo $*
+}
+
+#
+# Assume NFS_TRICKS are not available until we are
+# proved otherwise.
+#
+export NFS_TRICKS=1
+
+#
+# Quick status doesn't fork() or clone() when using
+# device files directly.  (i.e. not symlinks, LABEL= or
+# UUID=
+#
+if [ "$1" = "status" -o "$1" = "monitor" ] &&
+   [ "$OCF_RESKEY_quick_status" = "1" ]; then
+	echo Using Quick Status
+
+	# XXX maybe we can make ocf-shellfuncs have a 'quick' mode too?
+	export OCF_SUCCESS=0
+	export OCF_ERR_GENERIC=1
+else
+	#
+	# Grab nfs lock tricks if available
+	#
+	if [ -f "$(dirname $0)/svclib_nfslock" ]; then
+		. $(dirname $0)/svclib_nfslock
+		NFS_TRICKS=0
+	fi
+
+	. $(dirname $0)/ocf-shellfuncs
+fi
+
+
+verify_name()
+{
+	if [ -z "$OCF_RESKEY_name" ]; then
+		ocf_log err "No file system name specified."
+		return $OCF_ERR_ARGS
+	fi
+	return $OCF_SUCCESS
+}
+
+
+verify_mountpoint()
+{
+	if [ -z "$OCF_RESKEY_mountpoint" ]; then
+		ocf_log err "No mount point specified."
+		return $OCF_ERR_ARGS
+	fi
+
+	if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
+		ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\
+				"created at mount time."
+		return $OCF_SUCCESS
+	fi
+
+	[ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS
+
+	ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory."
+	
+	return $OCF_ERR_ARGS
+}
+
+
+#
+# This used to be called using $(...), but doing this causes bash
+# to set up a pipe and clone().  So, the output of this function is
+# stored in the global variable REAL_DEVICE, declared previously.
+#
+real_device()
+{
+	declare dev=$1
+	declare realdev
+
+	REAL_DEVICE=""
+
+	[ -z "$dev" ] && return $OCF_ERR_ARGS
+
+	# If our provided blockdev is a device, we are done
+	if [ -b "$dev" ]; then
+		REAL_DEVICE="$dev"
+	       	return $OCF_SUCCESS
+	fi
+
+	# Oops, we have a link.  Sorry, this is going to fork.
+	if [ -h "$dev" ]; then 
+		realdev=$(readlink -f $dev)
+		if [ $? -ne 0 ]; then
+			return $OCF_ERR_ARGS
+		fi
+		REAL_DEVICE="$realdev"
+		return $OCF_SUCCESS
+	fi
+
+	# It's not a link, it's not a block device.  If it also
+	# does not match UUID= or LABEL=, then findfs is not 
+	# going to find anything useful, so we should quit now.
+	if [ "${dev/UUID=/}" = "$dev" ] &&
+	   [ "${dev/LABEL=/}" = "$dev" ]; then
+		return $OCF_ERR_GENERIC
+	fi
+	
+	# When using LABEL= or UUID=, we can't save a fork.
+	realdev=$(findfs $dev 2> /dev/null)
+	if [ -n "$realdev" ] && [ -b "$realdev" ]; then
+		REAL_DEVICE="$realdev"
+		return $OCF_SUCCESS
+	fi
+
+	return $OCF_ERR_GENERIC
+}
+
+
+verify_device()
+{
+	declare realdev
+
+	if [ -z "$OCF_RESKEY_device" ]; then
+	       ocf_log err "No device or label specified."
+	       return $OCF_ERR_ARGS
+	fi
+
+	real_device $OCF_RESKEY_device
+	realdev=$REAL_DEVICE
+	if [ -n "$realdev" ]; then
+		if [ "$realdev" != "$OCF_RESKEY_device" ]; then
+			ocf_log info "Specified $OCF_RESKEY_device maps to $realdev"
+		fi
+		return $OCF_SUCCESS
+	fi
+
+	ocf_log err "Device or label \"$OCF_RESKEY_device\" not valid"
+
+	return $OCF_ERR_ARGS
+}
+
+
+#
+# mount_in_use device mount_point
+#
+# Check to see if either the device or mount point are in use anywhere on
+# the system.  It is not required that the device be mounted on the named
+# moint point, just if either are in use.
+#
+mount_in_use () {
+	declare mp tmp_mp
+	declare dev tmp_dev
+	declare junka junkb junkc junkd
+
+	if [ $# -ne 2 ]; then
+		ocf_log err "Usage: mount_in_use device mount_point".
+		return $FAIL
+	fi
+
+	dev=$1
+	mp=$2
+
+	while read tmp_dev tmp_mp junka junkb junkc junkd; do
+		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+			return $YES
+		fi
+		
+		if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
+			return $YES
+		fi
+	done < /proc/mounts
+
+	return $NO
+}
+
+
+#
+# is_mounted device mount_point
+#
+# Check to see if the device is mounted.  Print a warning if its not
+# mounted on the directory we expect it to be mounted on.
+#
+is_mounted () {
+
+	declare mp tmp_mp
+	declare dev tmp_dev
+	declare ret=$FAIL
+	declare found=1
+	declare poss_mp
+
+	if [ $# -ne 2 ]; then
+		ocf_log err "Usage: is_mounted device mount_point"
+		return $FAIL
+	fi
+
+	real_device "$1"
+	dev=$REAL_DEVICE
+	if [ -z "$dev" ]; then
+		ocf_log err \
+			"fs (is_mounted): Could not match $1 with a real device"
+		return $OCF_ERR_ARGS
+	fi
+
+	if [ -h "$2" ]; then
+		mp=$(readlink -f $2)
+	else
+		mp=$2
+	fi
+
+	ret=$NO
+
+	while read tmp_dev tmp_mp junk_a junk_b junk_c junk_d
+	do
+		real_device $tmp_dev
+		tmp_dev=$REAL_DEVICE
+
+		# This bash glyph simply removes a trailing slash
+		# if one exists.  /a/b/ -> /a/b; /a/b -> /a/b.
+		tmp_mp=${tmp_mp%/}
+		mp=${mp%/}
+
+		# XXX fork/clone warning XXX
+		# Mountpoint from /proc/mounts containing spaces will
+		# have spaces represented in octal.  printf takes care
+		# of this for us.
+		tmp_mp=$(printf "$mp")
+
+		if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+			#
+			# Check to see if its mounted in the right
+			# place
+			#
+			if [ -n "$tmp_mp" ]; then
+				if [ "$tmp_mp" != "$mp" ]; then
+					poss_mp=$tmp_mp
+				else
+					found=0
+				fi
+			fi
+			ret=$YES
+		fi
+	done < /proc/mounts
+
+	if [ $ret -eq $YES ] && [ $found -ne 0 ]; then
+		ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp"
+	fi
+
+	return $ret
+}
+
+
+# 
+# is_alive mount_point
+# 
+# Check to see if mount_point is alive (testing read/write)
+# 
+is_alive()
+{
+	declare errcode
+	declare mount_point
+	declare file=".writable_test.$(hostname)"
+	declare rw
+	
+	if [ $# -ne 1 ]; then
+	        ocf_log err "Usage: isAlive mount_point"
+		return $FAIL
+	fi
+	mount_point=$1
+
+	[ -z "$OCF_CHECK_LEVEL" ] && export OCF_CHECK_LEVEL=0
+	
+	test -d "$mount_point"
+	if [ $? -ne 0 ]; then
+		ocf_log err "fs (isAlive): $mount_point is not a directory"
+		return $FAIL
+	fi
+	
+	[ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
+	
+	# depth 10 test (read test)
+	ls "$mount_point" > /dev/null 2> /dev/null
+	errcode=$?
+	if [ $errcode -ne 0 ]; then
+		ocf_log err "${OCF_RESOURCE_INSTANCE}: failed read test on [$mount_point]. Return code: $errcode"
+		return $NO
+	fi
+	
+	[ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
+	
+	# depth 20 check (write test)
+	rw=$YES
+	for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
+                if [ "$o" = "ro" ]; then
+		        rw=$NO
+                fi
+	done
+	if [ $rw -eq $YES ]; then
+	        file="$mount_point"/$file
+		while true; do
+			if [ -e "$file" ]; then
+				file=${file}_tmp
+				continue
+			else
+			        break
+			fi
+		done
+		touch $file > /dev/null 2> /dev/null
+		errcode=$?
+		if [ $errcode -ne 0 ]; then
+			ocf_log err "${OCF_RESOURCE_INSTANCE}: isAlive failed write test on [$mount_point]. Return code: $errcode"
+			return $NO
+		fi
+		rm -f $file > /dev/null 2> /dev/null
+	fi
+	
+	return $YES
+}
+
+
+#
+# Decide which quota options are enabled and return a string 
+# which we can pass to quotaon
+#
+quota_opts()
+{
+	declare quotaopts=""
+	declare opts=$1
+	declare mopt
+
+	for mopt in `echo $opts | sed -e s/,/\ /g`; do
+		case $mopt in
+		quota)
+			quotaopts="gu"
+			break
+			;;
+		usrquota)
+			quotaopts="u$quotaopts"
+			continue
+			;;
+		grpquota)
+			quotaopts="g$quotaopts"
+			continue
+			;;
+		noquota)
+			quotaopts=""
+			return 0
+			;;
+		esac
+	done
+
+	echo $quotaopts
+	return 0
+}
+
+
+
+#
+# Enable quotas on the mount point if the user requested them
+#
+enable_fs_quotas()
+{
+	declare -i need_check=0
+	declare -i rv
+	declare quotaopts=""
+	declare mopt
+	declare opts=$1
+	declare mp=$2
+
+	if [ -z "`which quotaon`" ]; then
+		ocf_log err "quotaon not found in $PATH"
+		return $OCF_ERR_GENERIC
+	fi
+
+	quotaopts=$(quota_opts $opts)
+	[ -z "$quotaopts" ] && return 0
+
+	ocf_log debug "quotaopts = $quotaopts"
+
+	# Ok, create quota files if they don't exist
+	for f in quota.user aquota.user quota.group aquota.group; do
+		if ! [ -f "$mp/$f" ]; then
+			ocf_log info "$mp/$f was missing - creating"
+			touch "$mp/$f" 
+			chmod 600 "$mp/$f"
+			need_check=1
+		fi
+	done
+
+	if [ $need_check -eq 1 ]; then
+		ocf_log info "Checking quota info in $mp"
+		quotacheck -$quotaopts "$mp"
+	fi
+
+	ocf_log info "Enabling Quotas on $mp"
+	ocf_log debug "quotaon -$quotaopts \"$mp\""
+	quotaon -$quotaopts "$mp"
+	rv=$?
+	if [ $rv -ne 0 ]; then
+		# Just a warning
+		ocf_log warn "Unable to turn on quotas for $mp; return = $rv"
+	fi
+
+	return $rv
+}
+
+
+# Agent-specific actions to take before mounting
+# (if required).  Typically things like fsck.
+do_pre_mount() {
+	return 0
+}
+
+# Default mount handler - for block devices
+#
+do_mount() {
+	declare dev="$1"
+	declare mp="$2"
+	declare mount_options=""
+	declare fstype_option=""
+	declare fstype
+
+	#
+	# Get the filesystem type, if specified.
+	#
+	fstype_option=""
+	fstype=${OCF_RESKEY_fstype}
+       	case "$fstype" in 
+	""|"[ 	]*")
+		fstype=""
+		;;
+	*)	# found it
+		fstype_option="-t $fstype"
+		;;
+	esac
+
+	#
+	# Get the mount options, if they exist.
+	#
+	mount_options=""
+	opts=${OCF_RESKEY_options}
+	case "$opts" in 
+	""|"[ 	]*")
+		opts=""
+		;;
+	*)	# found it
+		mount_options="-o $opts"
+		;;
+	esac
+
+	#
+	# Mount the device
+	#
+	ocf_log info "mounting $dev on $mp"
+	ocf_log debug "mount $fstype_option $mount_options $dev $mp"
+	mount $fstype_option $mount_options $dev "$mp"
+}
+
+
+# Agent-specific actions to take after mounting
+# (if required).
+do_post_mount() {
+	return 0
+}
+
+
+# Agent-specific actions to take before unmounting
+# (if required)
+do_pre_unmount() {
+	return 0
+}
+
+
+# Agent-specific actions to take after umount succeeds
+# (if required)
+do_post_unmount() {
+	return 0
+}
+
+
+# Agent-specific force-unmount logic, if required
+do_force_unmount() {
+	return 0
+}
+
+
+#
+# start_filesystem
+#
+start_filesystem() {
+	declare -i ret_val=$OCF_SUCCESS
+	declare mp=""			# mount point
+	declare dev=""			# device
+	declare fstype=""
+	declare opts=""
+	declare mount_options=""
+
+	#
+	# Get the mount point, if it exists.  If not, no need to continue.
+	#
+	mp=${OCF_RESKEY_mountpoint}
+	case "$mp" in 
+      	""|"[ 	]*")		# nothing to mount
+    		return $OCF_SUCCESS
+    		;;
+	/*)			# found it
+	  	;;
+	*)	 		# invalid format
+			ocf_log err \
+"start_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+	    	return $OCF_ERR_ARGS
+	    	;;
+	esac
+	
+	#
+	# Get the device
+	#
+	real_device $OCF_RESKEY_device
+	dev=$REAL_DEVICE
+	if [ -z "$dev" ]; then
+			ocf_log err "\
+start_filesystem: Could not match $OCF_RESKEY_device with a real device"
+			return $OCF_ERR_ARGS
+	fi
+
+	#
+	# Ensure we've got a valid directory
+	#
+	if [ -e "$mp" ]; then
+		if ! [ -d "$mp" ]; then
+			ocf_log err"\
+start_filesystem: Mount point $mp exists but is not a directory"
+			return $OCF_ERR_ARGS
+		fi
+	else
+		ocf_log err "\
+start_filesystem: Creating mount point $mp for device $dev"
+		mkdir -p "$mp"
+		ret_val=$?
+		if [ $ret_val -ne 0 ]; then
+			ocf_log err "\
+start_filesystem: Unable to create $mp.  Error code: $ret_val"
+			return $OCF_ERR_GENERIC
+		fi
+	fi
+
+	#
+	# See if the device is already mounted.
+	# 
+	is_mounted $dev "$mp"
+	case $? in
+	$YES)		# already mounted
+		ocf_log debug "$dev already mounted"
+		return $OCF_SUCCESS
+		;;
+	$NO)		# not mounted, continue
+		;;
+	*)
+		return $FAIL
+		;;
+	esac
+
+
+	#
+	# Make sure that neither the device nor the mount point are mounted
+	# (i.e. they may be mounted in a different location).  The'mount_in_use'
+	# function checks to see if either the device or mount point are in
+	# use somewhere else on the system.
+	#
+	mount_in_use $dev "$mp"
+	case $? in
+	$YES)		# uh oh, someone is using the device or mount point
+		ocf_log err "\
+Cannot mount $dev on $mp, the device or mount point is already in use!"
+		return $FAIL
+		;;
+	$NO)		# good, no one else is using it
+		;;
+	$FAIL)
+		return $FAIL
+		;;
+	*)
+		ocf_log err "Unknown return from mount_in_use"
+		return $FAIL
+		;;
+	esac
+
+	do_pre_mount
+	case $? in
+	0)
+		;;
+	1)
+		return $OCF_ERR_GENERIC
+		;;
+	2)
+		return $OCF_SUCCESS
+		;;
+	esac
+
+	do_mount "$dev" "$mp"
+	case $? in
+	0)
+		;;
+	1)
+		return $OCF_ERR_GENERIC
+		;;
+	2)
+		return $OCF_SUCCESS
+		;;
+	esac
+
+	do_post_mount 
+	case $? in
+	0)
+		;;
+	1)
+		return $OCF_ERR_GENERIC
+		;;
+	2)
+		return $OCF_SUCCESS
+		;;
+	esac
+
+	enable_fs_quotas $opts "$mp"
+
+	return $OCF_SUCCESS
+}
+
+
+#
+# stop_filesystem serviceID deviceID
+#
+# Run the stop actions
+#
+stop_filesystem() {
+	declare -i ret_val=0
+	declare -i try=1
+	declare -i max_tries=3		# how many times to try umount
+	declare -i sleep_time=5		# time between each umount failure
+	declare done=""
+	declare umount_failed=""
+	declare force_umount=""
+	declare self_fence=""
+	declare fstype=""
+	declare quotaopts=""
+
+
+	#
+	# Get the mount point, if it exists.  If not, no need to continue.
+	#
+	mp=${OCF_RESKEY_mountpoint}
+	case "$mp" in 
+      	""|"[ 	]*")		# nothing to mount
+    		return $OCF_SUCCESS
+    		;;
+	/*)			# found it
+	  	;;
+	*)	 		# invalid format
+			ocf_log err \
+"stop_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+	    	return $FAIL
+	    	;;
+	esac
+	
+	#
+	# Get the device
+	#
+	real_device $OCF_RESKEY_device
+	dev=$REAL_DEVICE
+	if [ -z "$dev" ]; then
+			ocf_log err "\
+stop: Could not match $OCF_RESKEY_device with a real device"
+			return $FAIL
+	fi
+
+	#
+	# Get the force unmount setting if there is a mount point.
+	#
+	if [ -n "$mp" ]; then
+		case ${OCF_RESKEY_force_unmount} in
+	        $YES_STR)	force_umount=$YES ;;
+		1)		force_umount=$YES ;;
+	        *)		force_umount="" ;;
+		esac
+	fi
+
+	if [ -n "$mp" ]; then
+		case ${OCF_RESKEY_self_fence} in
+	        $YES_STR)	self_fence=$YES ;;
+		1)		self_fence=$YES ;;
+	        *)		self_fence="" ;;
+		esac
+	fi
+
+	do_pre_unmount
+	case $? in
+	0)
+		;;
+	1)
+		return $OCF_ERR_GENERIC
+		;;
+	2)
+		return $OCF_SUCCESS
+		;;
+	esac
+
+	#
+	# Unmount the device.  
+	#
+	while [ ! "$done" ]; do
+		is_mounted $dev "$mp"
+		case $? in
+		$NO)
+			ocf_log info "$dev is not mounted"
+			umount_failed=
+			done=$YES
+			;;
+		$FAIL)
+			return $FAIL
+			;;
+		$YES)
+			sync
+
+			quotaopts=$(quota_opts $OCF_RESKEY_options)
+			if [ -n "$quotaopts" ]; then
+				ocf_log debug "Turning off quotas for $mp"
+				quotaoff -$quotaopts "$mp" &> /dev/null
+			fi
+
+			ocf_log info "unmounting $mp"
+			umount "$mp"
+			ret_val=$?
+			if  [ $ret_val -eq 0 ]; then
+				umount_failed=
+				done=$YES
+				continue
+			fi
+			ocf_log debug "umount failed: $ret_val"
+
+			umount_failed=yes
+
+			if [ "$force_umount" ]; then
+				if [ $try -eq 1 ]; then
+					ocf_log warning "Sending SIGTERM to processes on $mp"
+					fuser -TERM -kvm "$mp"
+
+					do_force_unmount
+					case $? in
+					0)
+						;;
+					1)
+						return $OCF_ERR_GENERIC
+						;;
+					2)
+						return $OCF_SUCCESS
+						;;
+					esac
+				else 
+					ocf_log warning "Sending SIGKILL to processes on $mp"
+					fuser -kvm "$mp"
+				fi
+			fi
+
+			;;
+		*)
+			return $OCF_ERR_GENERIC
+			;;
+		esac
+
+		if [ $try -ge $max_tries ]; then
+			done=$YES
+		elif [ "$done" != "$YES" ]; then
+			sleep $sleep_time
+			let try=try+1
+		fi
+	done # while 
+
+	do_post_unmount
+	case $? in
+	0)
+		;;
+	1)
+		return $OCF_ERR_GENERIC
+		;;
+	2)
+		return $OCF_SUCCESS
+		;;
+	esac
+
+	if [ -n "$umount_failed" ]; then
+		ocf_log err "'umount $mp' failed, error=$ret_val"
+
+		if [ "$self_fence" ]; then
+			ocf_log alert "umount failed - REBOOTING"
+			sync
+			reboot -fn
+		fi
+		return $OCF_ERR_GENERIC
+	fi
+
+	return $OCF_SUCCESS
+}
+
+
+do_start() {
+	declare tries=0
+	declare rv
+
+	while [ $tries -lt 3 ]; do
+		start_filesystem
+		rv=$?
+		if [ $rv -eq 0 ]; then
+			return 0
+		fi
+
+		((tries++))
+		sleep 3
+	done
+	return $rv
+}
+
+
+do_stop() {
+	stop_filesystem
+	return $?
+}
+
+
+do_monitor() {
+  	is_mounted ${OCF_RESKEY_device} "${OCF_RESKEY_mountpoint}"
+
+ 	if [ $? -ne $YES ]; then
+		ocf_log err "${OCF_RESOURCE_INSTANCE}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}"
+		return $OCF_ERR_GENERIC
+	fi
+
+	if [ "$OCF_RESKEY_quick_status" = "1" ]; then
+		return 0
+	fi
+
+ 	is_alive "${OCF_RESKEY_mountpoint}"
+ 	[ $? -eq $YES ] && return 0
+
+	ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!"
+	return $OCF_ERR_GENERIC
+}
+
+
+do_restart() {
+	stop_filesystem
+	if [ $? -ne 0 ]; then
+		return $OCF_ERR_GENERIC
+	fi
+
+	start_filesystem
+	if [ $? -ne 0 ]; then
+		return $OCF_ERR_GENERIC
+	fi
+
+	return 0
+}
+
+
+# MUST BE OVERRIDDEN
+do_metadata() {
+	return 1
+}
+
+
+do_validate() {
+	return 1
+}
+
+
+main() {
+	case $1 in
+	start)
+		do_start
+		exit $?
+		;;
+	stop)
+		do_stop
+		exit $?
+		;;
+	status|monitor)
+		do_monitor
+		exit $?
+		;;
+	restart)
+		do_restart
+		exit $?
+		;;
+	meta-data)
+		do_metadata
+		exit $?
+		;;
+	validate-all)
+		do_validate
+		;;
+	*)
+		echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
+		exit $OCF_ERR_UNIMPLEMENTED
+		;;
+	esac
+	exit 0
+}
+
-- 
1.6.2.5




More information about the Cluster-devel mailing list