diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
index 73ce6b6d0..38d101616 100644
--- a/heartbeat/Makefile.am
+++ b/heartbeat/Makefile.am
@@ -1,157 +1,159 @@
 # Makefile.am for OCF RAs
 #
 # Author: Sun Jing Dong
 # Copyright (C) 2004 IBM
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
 # of the License, or (at your option) any later version.
 # 
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # 
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 MAINTAINERCLEANFILES = Makefile.in
 
 EXTRA_DIST		= $(ocf_SCRIPTS) $(ocfcommon_DATA) \
 			  $(common_DATA) $(hb_DATA) $(dtd_DATA) \
 			  README
 
 AM_CPPFLAGS		= -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha
 
 halibdir		= $(libexecdir)/heartbeat
 
 ocfdir		        = $(OCF_RA_DIR_PREFIX)/heartbeat
 
 dtddir			= $(datadir)/$(PACKAGE_NAME)
 dtd_DATA		= ra-api-1.dtd
 
 if USE_IPV6ADDR_AGENT
 ocf_PROGRAMS           = IPv6addr
 else
 ocf_PROGRAMS           =
 endif
 
 if IPV6ADDR_COMPATIBLE
 halib_PROGRAMS         = send_ua
 else
 halib_PROGRAMS         =
 endif
 
 IPv6addr_SOURCES        = IPv6addr.c IPv6addr_utils.c
 send_ua_SOURCES         = send_ua.c IPv6addr_utils.c
 
 IPv6addr_LDADD          = -lplumb $(LIBNETLIBS)
 send_ua_LDADD           = $(LIBNETLIBS)
 
 ocf_SCRIPTS	     =  ClusterMon		\
 			CTDB			\
 			Dummy			\
 		        IPaddr			\
 		        IPaddr2			\
 			anything		\
 			AoEtarget		\
 			apache			\
 			asterisk		\
 			nginx			\
 			AudibleAlarm		\
 			clvm		\
 			conntrackd		\
 			db2			\
 			dhcpd		\
 			Delay			\
 			dnsupdate		\
 			docker			\
 			eDir88			\
 			EvmsSCC			\
 			Evmsd			\
 			ethmonitor		\
 			exportfs		\
 			Filesystem		\
 			fio			\
 			galera			\
 			ids			\
 			iscsi			\
 			ICP			\
 			IPsrcaddr		\
 			iSCSITarget		\
 			iSCSILogicalUnit	\
 			iface-bridge		\
 			iface-vlan		\
 			jboss			\
 			kamailio		\
 			LinuxSCSI		\
 			LVM			\
 			lxc			\
 			MailTo			\
 			ManageRAID		\
 			ManageVE		\
 			mysql			\
 			mysql-proxy		\
 			named			\
 			nfsnotify		\
 			nfsserver		\
 			oracle			\
 			oralsnr			\
 			pingd			\
 			portblock		\
 			postfix			\
 			pound			\
 			pgsql			\
 			proftpd			\
 			Pure-FTPd		\
 			rabbitmq-cluster	\
 			Raid1			\
 			redis			\
 			Route			\
 			rsyncd			\
 			rsyslog			\
 			SAPDatabase		\
 			SAPInstance		\
 			SendArp			\
 			ServeRAID		\
 			slapd			\
 			SphinxSearchDaemon	\
 			Squid			\
 			Stateful		\
 			SysInfo			\
 			scsi2reservation	\
 			sfex			\
                         sg_persist              \
 			symlink			\
 			syslog-ng		\
 			tomcat			\
 			VIPArip			\
 			VirtualDomain		\
 			varnish			\
 			vmware			\
 			WAS			\
 			WAS6			\
 			WinPopup		\
 			Xen			\
 			Xinetd			\
 			zabbixserver
 
 ocfcommondir		= $(OCF_LIB_DIR_PREFIX)/heartbeat
 ocfcommon_DATA		= ocf-shellfuncs 	\
 			  ocf-binaries	 	\
 			  ocf-directories 	\
 			  ocf-returncodes 	\
  			  ocf-rarun		\
+ 			  ocf-distro		\
 			  apache-conf.sh 	\
 			  http-mon.sh    	\
 			  sapdb-nosha.sh	\
 			  sapdb.sh		\
 			  ora-common.sh		\
 			  mysql-common.sh		\
+			  nfsserver-redhat.sh		\
 			  findif.sh
 
 # Legacy locations
 hbdir			= $(sysconfdir)/ha.d
 hb_DATA			= shellfuncs
diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
index 02a2f7fbb..3cec5c8e7 100755
--- a/heartbeat/nfsserver
+++ b/heartbeat/nfsserver
@@ -1,817 +1,660 @@
 #!/bin/sh
 # nfsserver
 #
 # Description: Manages nfs server as OCF resource
 # by hxinwei@gmail.com
 # License: GNU General Public License v2 (GPLv2) and later
 
 if [ -n "$OCF_DEBUG_LIBRARY" ]; then
     . $OCF_DEBUG_LIBRARY
 else
     : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
 fi
 
+if is_redhat_based; then
+	. ${OCF_FUNCTIONS_DIR}/nfsserver-redhat.sh
+fi
+
 DEFAULT_INIT_SCRIPT="/etc/init.d/nfsserver"
 if ! [ -f $DEFAULT_INIT_SCRIPT ]; then
 	# On some systems, the script is just called nfs
 	DEFAULT_INIT_SCRIPT="/etc/init.d/nfs"
 fi
 
 DEFAULT_NOTIFY_CMD=`which sm-notify`
 DEFAULT_NOTIFY_CMD=${DEFAULT_NOTIFY_CMD:-"/sbin/sm-notify"}
 DEFAULT_NOTIFY_FOREGROUND="false"
 DEFAULT_RPCPIPEFS_DIR="/var/lib/nfs/rpc_pipefs"
 EXEC_MODE=0
 SELINUX_ENABLED=-1
 STATD_PATH="/var/lib/nfs"
 STATD_DIR=""
-NFS_SYSCONFIG="/etc/sysconfig/nfs"
-NFS_SYSCONFIG_LOCAL_BACKUP="/etc/sysconfig/nfs.ha.bu"
-NFS_SYSCONFIG_AUTOGEN_TAG="AUTOGENERATED by $0 high availability resource-agent"
 
 nfsserver_meta_data() {
 	cat <<END
 <?xml version="1.0"?>
 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 <resource-agent name="nfsserver">
 <version>1.0</version>
 
 <longdesc lang="en">
 Nfsserver helps to manage the Linux nfs server as a failover-able resource in Linux-HA.
 It depends on Linux specific NFS implementation details, so is considered not portable to other platforms yet.
 </longdesc>
 
 <shortdesc lang="en">Manages an NFS server</shortdesc>
 
 <parameters>
 
 <parameter name="nfs_init_script" unique="0" required="0">
 <longdesc lang="en">
 The default init script shipped with the Linux distro.
 The nfsserver resource agent offloads the start/stop/monitor 
 work to the init script because the procedure to start/stop/monitor 
 nfsserver varies on different Linux distro. In the event that this
 option is not set, this agent will attempt to use an init script at 
 this location, ${DEFAULT_INIT_SCRIPT}, or detect a systemd unit-file 
 to use in the event that no init script is detected.
 </longdesc>
 <shortdesc lang="en">
 Init script for nfsserver
 </shortdesc>
 <content type="string" default="auto detected" />
 </parameter>
 
 <parameter name="nfs_no_notify" unique="0" required="0">
 <longdesc lang="en">
 Do not send reboot notifications to NFSv3 clients during server startup.
 </longdesc>
 <shortdesc lang="en">
 Disable NFSv3 server reboot notifications
 </shortdesc>
 <content type="boolean" default="false" />
 </parameter>
 
 <parameter name="nfs_notify_foreground" unique="0" required="0">
 <longdesc lang="en">
 Keeps the sm-notify attached to its controlling terminal and running in the foreground.
 </longdesc>
 <shortdesc lang="en">
 Keeps the notify tool running in the foreground.
 </shortdesc>
 <content type="boolean" default="$DEFAULT_NOTIFY_FOREGROUND" />
 </parameter>
 
 <parameter name="nfs_smnotify_retry_time" unique="0" required="0">
 <longdesc lang="en">
 Specifies the length of sm-notify retry time, in minutes, to continue retrying notifications to unresponsive hosts.  
 If this option is not specified, sm-notify attempts to send notifications for 15 minutes. Specifying a value of 0 
 causes sm-notify to continue sending notifications to unresponsive peers until it is manually killed.
 </longdesc>
 <shortdesc lang="en">
 Specifies the length of sm-notify retry time (minutes).
 </shortdesc>
 <content type="integer" default="" />
 </parameter>
 
 <parameter name="nfs_ip" unique="0" required="0">
 <longdesc lang="en">
 Comma separated list of floating IP addresses used to access the nfs service
 </longdesc>
 <shortdesc lang="en">
 IP addresses.
 </shortdesc>
 <content type="string"/>
 </parameter>
 
-<parameter name="nfsd_args" unique="0" required="0">
-<longdesc lang="en">
-Specifies what arguments to pass to the nfs daemon on startup. View the rpc.nfsd man page for information on what arguments are available.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-rpc.nfsd options
-</shortdesc>
-<content type="string" />
-</parameter>
-
-<parameter name="lockd_udp_port" unique="0" required="0">
-<longdesc lang="en">
-The udp port lockd should listen on.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-lockd udp port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
-<parameter name="lockd_tcp_port" unique="0" required="0">
-<longdesc lang="en">
-The tcp port lockd should listen on.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-lockd tcp port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
-<parameter name="statd_outgoing_port" unique="0" required="0">
-<longdesc lang="en">
-The source port number sm-notify uses when sending reboot notifications.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-sm-notify source port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
-<parameter name="statd_port" unique="0" required="0">
-<longdesc lang="en">
-The port number used for RPC listener sockets.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-rpc.statd listener port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
-<parameter name="mountd_port" unique="0" required="0">
-<longdesc lang="en">
-The port number used for rpc.mountd listener sockets.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-rpc.mountd listener port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
-<parameter name="rquotad_port" unique="0" required="0">
-<longdesc lang="en">
-The port number used for rpc.rquotad.
-Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
-</longdesc>
-<shortdesc lang="en">
-rpc.rquotad port
-</shortdesc>
-<content type="integer" />
-</parameter>
-
 <parameter name="nfs_shared_infodir" unique="0" required="0">
 <longdesc lang="en">
 The nfsserver resource agent will save nfs related information in this specific directory.
 And this directory must be able to fail-over before nfsserver itself.
 </longdesc>
 <shortdesc lang="en">
 Directory to store nfs server related information.
 </shortdesc>
 <content type="string" default="" />
 </parameter>
 
 <parameter name="rpcpipefs_dir" unique="0" required="0">
 <longdesc lang="en">
 The mount point for the sunrpc file system. Default is $DEFAULT_RPCPIPEFS_DIR. 
 This script will mount (bind) nfs_shared_infodir on /var/lib/nfs/ (cannot be changed),
 and this script will mount the sunrpc file system on $DEFAULT_RPCPIPEFS_DIR (default, can be changed by this parameter).
 If you want to move only rpc_pipefs/ (e.g. to keep rpc_pipefs/ local) from default, please set this value.
 </longdesc>
 <shortdesc lang="en">
 The mount point for the sunrpc file system.
 </shortdesc>
 <content type="string" default="$DEFAULT_RPCPIPEFS_DIR" />
 </parameter>
 
+$(
+is_redhat_based && nfsserver_redhat_meta_data
+)
+
 </parameters>
 
 <actions>
 <action name="start"   timeout="40" />
 <action name="stop"    timeout="20s" />
 <action name="monitor" depth="0"  timeout="20s" interval="10" />
 <action name="meta-data"  timeout="5" />
 <action name="validate-all"  timeout="30" />
 </actions>
 </resource-agent>
 END
 
 return $OCF_SUCCESS
 }
 
 nfsserver_usage() {
 	cat <<END
 		usage: $0 {start|stop|monitor|status|validate-all|meta-data}
 END
 }
 
 if [ $# -ne 1 ]; then
 	nfsserver_usage
 	exit $OCF_ERR_ARGS
 fi
 
 case $__OCF_ACTION in
 	meta-data)  nfsserver_meta_data
 		exit $OCF_SUCCESS
 		;;
 	usage|help) nfsserver_usage
 		exit $OCF_SUCCESS
 		;;
 	*)
 		;;	
 esac
 
 fp="$OCF_RESKEY_nfs_shared_infodir"
 : ${OCF_RESKEY_nfs_notify_cmd="$DEFAULT_NOTIFY_CMD"}
 : ${OCF_RESKEY_nfs_notify_foreground="$DEFAULT_NOTIFY_FOREGROUND"}
 
 if [ -z ${OCF_RESKEY_rpcpipefs_dir} ]; then
 	rpcpipefs_make_dir=$fp/rpc_pipefs
 	rpcpipefs_umount_dir=${DEFAULT_RPCPIPEFS_DIR}
 else
 	rpcpipefs_make_dir=${OCF_RESKEY_rpcpipefs_dir}
 	rpcpipefs_umount_dir=${OCF_RESKEY_rpcpipefs_dir}
 fi
 
 # Use statd folder if it exists
 if [ -d "/var/lib/nfs/statd" ]; then
 	STATD_DIR="statd"
 	STATD_PATH="/var/lib/nfs/statd"
 fi
 
 # SELinux information. We are taking the permissions from
 # the current statd dir and applying it to the HA one that is
 # being mounted in its place.
 which restorecon > /dev/null 2>&1 && selinuxenabled
 SELINUX_ENABLED=$?
 if [ $SELINUX_ENABLED -eq 0 ]; then
 	export SELINUX_LABEL="$(ls -ldZ $STATD_PATH | cut -f4 -d' ')"
 fi
 
 ##
 # EXEC_MODE values
 # 1  user init script or default init script
 # 2  systemd (with nfs-lock.service)
 # 3  systemd (with rpc-statd.service)
 #
 # On error, this function will terminate the process
 # with error code $OCF_ERR_INSTALLED
 ##
 set_exec_mode()
 {
 
 	##
 	# If EXEC_MODE is already set, we don't need to run this function again.
 	## 
 	if [ $EXEC_MODE -ne 0 ]; then
 		return 0;
 	fi
 
 	##
 	# If the user defined an init script, It must exist for us to continue
 	##
 	if [ -n "$OCF_RESKEY_nfs_init_script" ]; then
 		# check_binary will exit the process if init script does not exist
 		check_binary ${OCF_RESKEY_nfs_init_script}
 		EXEC_MODE=1
 		return 0
 	fi
 
 	##
 	# Check to see if the default init script exists, if so we'll use that.
 	##
 	if which $DEFAULT_INIT_SCRIPT > /dev/null 2>&1; then
 		OCF_RESKEY_nfs_init_script=$DEFAULT_INIT_SCRIPT
 		EXEC_MODE=1
 		return 0
 	fi
 
 	##
 	# Attempt systemd (with nfs-lock.service).
 	##
 	if which systemctl > /dev/null 2>&1; then
 		if systemctl list-unit-files | grep nfs-server > /dev/null && systemctl list-unit-files | grep nfs-lock > /dev/null; then
 			EXEC_MODE=2
 			# when using systemd, the nfs-lock service file handles nfsv3 locking daemons for us.
 			return 0
 		fi
 	fi
 
 	##
 	# Attempt systemd (with rpc-statd.service).
 	##
 	if which systemctl > /dev/null 2>&1; then
 		if systemctl list-unit-files | grep nfs-server > /dev/null && systemctl list-unit-files | grep rpc-statd > /dev/null; then
 			EXEC_MODE=3
 			return 0
 		fi
 	fi
 
 	ocf_exit_reason "No init script or systemd unit file detected for nfs server"
 	exit $OCF_ERR_INSTALLED
 }
 
 ##
 # wrapper for init script and systemd calls.
 ##
 nfs_exec()
 {
 	local cmd=$1
 	set_exec_mode
 
 	case $EXEC_MODE in 
 		1) ${OCF_RESKEY_nfs_init_script} $cmd;;
 		2) systemctl $cmd nfs-server.service ;;
 		3) systemctl $cmd nfs-server.service ;;
 	esac
 }
 
 v3locking_exec()
 {
 	local cmd=$1
 	set_exec_mode
 
 	if [ $EXEC_MODE -eq 2 ]; then
 		systemctl $cmd nfs-lock.service
 	elif [ $EXEC_MODE -eq 3 ]; then
 		systemctl $cmd rpc-statd.service
 	else 
 		case $cmd in
 			start) locking_start;;
 			stop) locking_stop;;
 			status) locking_status;;
 		esac
 	fi
 }
 
 nfsserver_monitor ()
 {
 	fn=`mktemp`
 	nfs_exec status > $fn 2>&1 
 	rc=$?
 	ocf_log debug "$(cat $fn)"
 	rm -f $fn
 
 	#Adapte LSB status code to OCF return code
 	if [ $rc -eq 0 ]; then
 		# don't report success if nfs servers are up
 		# without locking daemons.
 		v3locking_exec "status"
 		rc=$?
 		if [ $rc -ne 0 ]; then
 			ocf_exit_reason "NFS server is up, but the locking daemons are down"
 			rc=$OCF_ERR_GENERIC
 		fi
 		return $rc
 	elif [ $rc -eq 3 ]; then
 		return $OCF_NOT_RUNNING
 	else
 		return $OCF_ERR_GENERIC
 	fi
 }
 
-set_arg()
-{
-	local key="$1"
-	local value="$2"
-	local file="$3"
-	local requires_sysconfig="$4"
-
-	if [ -z "$value" ]; then
-		return
-	fi
-
-	# only write to the tmp /etc/sysconfig/nfs if sysconfig exists.
-	# otherwise this distro does not support setting these options.
-	if [ -d "/etc/sysconfig" ]; then
-		# replace if the value exists, append otherwise
-		if grep "^\s*${key}=" $file ; then
-			sed -i "s/\s*${key}=.*$/${key}=\"${value}\"/" $file
-		else
-			echo "${key}=\"${value}\"" >> $file
-		fi
-	elif [ "$requires_sysconfig" = "true" ]; then
-		ocf_log warn "/etc/sysconfig/nfs not found, unable to set port and nfsd args."
-	fi
-
-	export ${key}="${value}"
-}
-
-set_env_args()
-{
-	local tmpconfig=$(mktemp ${HA_RSCTMP}/nfsserver-tmp-XXXXX)
-	local statd_args
-
-	if [ -f "$NFS_SYSCONFIG" ]; then
-		## Take the $NFS_SYSCONFIG file as our skeleton
-		cp $NFS_SYSCONFIG $tmpconfig
-	fi
-
-	# nfsd args
-	set_arg "RPCNFSDARGS" "$OCF_RESKEY_nfsd_args" "$tmpconfig" "true"
-
-	# mountd args
-	if [ -n "$OCF_RESKEY_mountd_port" ]; then
-		set_arg "RPCMOUNTDOPTS" "-p $OCF_RESKEY_mountd_port" "$tmpconfig" "true"
-	fi
-
-	# statd args. we always want to perform the notify using sm-notify after
-	# both rpc.statd and the nfsd daemons are initialized
-	statd_args="--no-notify"
-	if [ -n "$OCF_RESKEY_statd_outgoing_port" ]; then
-		statd_args="$statd_args -o $OCF_RESKEY_statd_outgoing_port"
-	fi
-	if [ -n "$OCF_RESKEY_statd_port" ]; then
-		statd_args="$statd_args -p $OCF_RESKEY_statd_port"
-	fi
-	set_arg "STATDARG" "$statd_args" "$tmpconfig" "false"
-
-	# lockd ports
-	set_arg "LOCKD_UDPPORT" "$OCF_RESKEY_lockd_udp_port" "$tmpconfig" "true"
-	set_arg "LOCKD_TCPPORT" "$OCF_RESKEY_lockd_tcp_port" "$tmpconfig" "true"
-
-	# rquotad_port
-	if [ -n "$OCF_RESKEY_rquotad_port" ]; then
-		set_arg "RPCRQUOTADOPTS" "-p $OCF_RESKEY_rquotad_port" "$tmpconfig" "true"
-	fi
-
-	# override local nfs config. preserve previous local config though.
-	if [ -s $tmpconfig ]; then
-		cat $NFS_SYSCONFIG | grep -q -e "$NFS_SYSCONFIG_AUTOGEN_TAG" > /dev/null 2>&1 
-		if [ $? -ne 0 ]; then
-			# backup local nfs config if it doesn't have our HA autogen tag in it.
-			mv -f $NFS_SYSCONFIG $NFS_SYSCONFIG_LOCAL_BACKUP
-		fi
-
-		cat $tmpconfig | grep -q -e "$NFS_SYSCONFIG_AUTOGEN_TAG" > /dev/null 2>&1 
-		if [ $? -ne 0 ]; then
-			echo "# $NFS_SYSCONFIG_AUTOGEN_TAG" > $NFS_SYSCONFIG
-			echo "# local config backup stored here, '$NFS_SYSCONFIG_LOCAL_BACKUP'" >> $NFS_SYSCONFIG
-			cat $tmpconfig >> $NFS_SYSCONFIG
-		else
-			cat $tmpconfig > $NFS_SYSCONFIG
-		fi
-	fi
-	rm -f $tmpconfig
-}
-
 prepare_directory ()
 {
 	if [ -z "$fp" ]; then
 		return
 	fi
 
 	[ -d "$fp" ] || mkdir -p $fp
 	[ -d "$rpcpipefs_make_dir" ] || mkdir -p $rpcpipefs_make_dir
 	[ -d "$fp/v4recovery" ] || mkdir -p $fp/v4recovery
 
 	[ -d "$fp/$STATD_DIR" ] || mkdir -p "$fp/$STATD_DIR"
 	[ -d "$fp/$STATD_DIR/sm" ] || mkdir -p "$fp/$STATD_DIR/sm"
 	[ -d "$fp/$STATD_DIR/sm.ha" ] || mkdir -p "$fp/$STATD_DIR/sm.ha"
 	[ -d "$fp/$STATD_DIR/sm.bak" ] || mkdir -p "$fp/$STATD_DIR/sm.bak"
 	[ -n "`id -u rpcuser 2>/dev/null`" -a "`id -g rpcuser 2>/dev/null`" ] &&
 		chown -R rpcuser.rpcuser "$fp/$STATD_DIR"
 
 	[ -f "$fp/etab" ] || touch "$fp/etab"
 	[ -f "$fp/xtab" ] || touch "$fp/xtab"
 	[ -f "$fp/rmtab" ] || touch "$fp/rmtab"
 
 	dd if=/dev/urandom of=$fp/$STATD_DIR/state bs=1 count=4 >/dev/null 2>&1
 	[ -n "`id -u rpcuser 2>/dev/null`" -a "`id -g rpcuser 2>/dev/null`" ] && chown rpcuser.rpcuser "$fp/$STATD_DIR/state"
 	[ $SELINUX_ENABLED -eq 0 ] && chcon -R "$SELINUX_LABEL" "$fp"
 }
 
 is_bound ()
 {
 	if mount | grep -q "on $1 type"; then
 		return 0
 	fi
 
 	return 1
 }
 
 bind_tree ()
 {
 	if [ -z "$fp" ]; then
 		return
 	fi
 
 	if is_bound /var/lib/nfs; then
 		ocf_log debug "$fp is already bound to /var/lib/nfs"
 		return 0
 	fi
 	mount --bind $fp /var/lib/nfs
 	[ $SELINUX_ENABLED -eq 0 ] && restorecon /var/lib/nfs
 }
 
 unbind_tree ()
 {
 	if `mount | grep -q " on $rpcpipefs_umount_dir"`; then
 		umount -t rpc_pipefs $rpcpipefs_umount_dir
 	fi
 	if is_bound /var/lib/nfs; then
 		umount /var/lib/nfs
 	fi
 }
 
 binary_status()
 {
 	local binary=$1
 	local pid
 
 	pid=$(pgrep ${binary})
 	case $? in
 		0)
 			echo "$pid"
 			return $OCF_SUCCESS;;
 		1)
 			return $OCF_NOT_RUNNING;;
 		*)
 			return $OCF_ERR_GENERIC;;
 	esac
 }
 
 locking_status()
 {
 	binary_status "rpc.statd" > /dev/null 2>&1
 }
 
 locking_start()
 {
 	local ret=$OCF_SUCCESS
 
 	ocf_log info "Starting rpc.statd."
 
 	rpc.statd $STATDARG
 
 	ret=$?
 	if [ $ret -ne 0 ]; then
 		ocf_log err "Failed to start rpc.statd"
 		return $ret
 	fi
 	[ -d /var/lock/subsys ] && touch /var/lock/subsys/nfslock
 
 	return $ret
 }
 
 terminate()
 {
 	local pids
 	local i=0
 
 	while : ; do
 		pids=$(binary_status $1)
 		[ -z "$pids" ] && return 0
 	 	kill $pids
 		sleep 1
 		i=$((i + 1))
 		[ $i -gt 3 ] && return 1
 	done
 }
 
 
 killkill()
 {
 	local pids
 	local i=0
 
 	while : ; do
 		pids=$(binary_status $1)
 		[ -z "$pids" ] && return 0
 	 	kill -9 $pids
 		sleep 1
 		i=$((i + 1))
 		[ $i -gt 3 ] && return 1
 	done
 }
 
 stop_process()
 {
 	local process=$1
 
 	ocf_log info "Stopping $process"
 	if terminate $process; then
 		ocf_log debug "$process is stopped"
 	else
 		if killkill $process; then
 			ocf_log debug "$process is stopped"
 		else
 			ocf_log debug "Failed to stop $process"
 			return 1
 		fi
 	fi
 	return 0
 }
 
 locking_stop()
 {
 	ret=0
 
 	# sm-notify can prevent umount of /var/lib/nfs/statd if
 	# it is still trying to notify unresponsive clients.
 	stop_process sm-notify
 	if [ $? -ne 0 ]; then
 		ret=$OCF_ERR_GENERIC
 	fi
 
 	stop_process rpc.statd
 	if [ $? -ne 0 ]; then
 		ret=$OCF_ERR_GENERIC
 	fi
 
 	return $ret
 }
 
 notify_locks()
 {
 	if ocf_is_true "$OCF_RESKEY_nfs_no_notify"; then
 		# we've been asked not to notify clients
 		return;
 	fi
 
 	# run in foreground, if requested
 	if ocf_is_true "$OCF_RESKEY_nfs_notify_foreground"; then
 		opts="-d"
 	fi
 
 	if [ -n "$OCF_RESKEY_nfs_smnotify_retry_time" ]; then
 		opts="$opts -m $OCF_RESKEY_nfs_smnotify_retry_time"
 	fi
 
 	if [ -n "$OCF_RESKEY_statd_outgoing_port" ]; then
 		opts="$opts -p $OCF_RESKEY_statd_outgoing_port"
 	fi
 
 	# forces re-notificaiton regardless if notifies have already gone out
 	opts="$opts -f"
 
 	ocf_log info "executing sm-notify"
 	if [ -n "$OCF_RESKEY_nfs_ip" ]; then
 		for ip in `echo ${OCF_RESKEY_nfs_ip} | sed 's/,/ /g'`; do
 			cp -rpfn $STATD_PATH/sm.ha/* $STATD_PATH/  > /dev/null 2>&1
 			sm-notify $opts -v $ip
 		done
 	else
 		sm-notify $opts
 	fi
 }
 
 nfsserver_start ()
 {
 	local rc;
 
 	if nfsserver_monitor; then
 		ocf_log debug "NFS server is already started"
 		return $OCF_SUCCESS
 	fi
 
-	set_env_args
+	is_redhat_based && set_env_args
 	prepare_directory
 	bind_tree
 
 	# remove the sm-notify pid so sm-notify will be allowed to run again without requiring a reboot.
 	rm -f /var/run/sm-notify.pid
 	#
 	# Synchronize these before starting statd
 	#
 	cp -rpfn $STATD_PATH/sm.ha/* $STATD_PATH/ > /dev/null 2>&1
 	rm -rf $STATD_PATH/sm.ha/* > /dev/null 2>&1
 	cp -rpf $STATD_PATH/sm $STATD_PATH/sm.bak /var/lib/nfs/state $STATD_PATH/sm.ha > /dev/null 2>&1
 
 	ocf_log info "Starting NFS server ..."
 
 	# mounts /proc/fs/nfsd for us
 	lsmod | grep -q nfsd
 	if [ $? -ne 0 ]; then
 		modprobe nfsd
 	fi
 
 	# check to see if we need to start rpc.statd
 	v3locking_exec "status"
 	if [ $? -ne $OCF_SUCCESS ]; then
 		v3locking_exec "start"
 		rc=$?
 		if [ $rc -ne 0 ]; then
 			ocf_exit_reason "Failed to start NFS server locking daemons"
 			return $rc
 		fi
 	else
 		ocf_log info "rpc.statd already up"
 	fi
 
 	fn=`mktemp`
 	nfs_exec start > $fn 2>&1
 	rc=$?
 	ocf_log debug "$(cat $fn)"
 	rm -f $fn
 
 	if [ $rc -ne 0 ]; then
 		ocf_exit_reason "Failed to start NFS server"
 		return $rc
 	fi	
 
 	notify_locks
 
 	ocf_log info "NFS server started"
 	return $OCF_SUCCESS
 }
 
 nfsserver_stop ()
 {
 	ocf_log info "Stopping NFS server ..."
 
 	# backup the current sm state information to the ha folder before stopping.
 	# the ha folder will be synced after startup, restoring the statd client state
 	rm -rf $STATD_PATH/sm.ha/* > /dev/null 2>&1
 	cp -rpf $STATD_PATH/sm $STATD_PATH/sm.bak /var/lib/nfs/state $STATD_PATH/sm.ha > /dev/null 2>&1
 
 	fn=`mktemp`
 	nfs_exec stop > $fn 2>&1
 	rc=$?
 	ocf_log debug "$(cat $fn)"
 	rm -f $fn
 
 	v3locking_exec "stop"
 	if [ $? -ne 0 ]; then
 		ocf_exit_reason "Failed to stop NFS locking daemons"
 		rc=$OCF_ERR_GENERIC
 	fi
 
 	if [ $rc -eq 0 ]; then
 		unbind_tree 
 		ocf_log info "NFS server stopped"
 	else 
 		ocf_exit_reason "Failed to stop NFS server"
 	fi
 	return $rc
 }
 
 nfsserver_validate ()
 {
 	##
 	# set_exec_mode will exit if nfs server is not installed
 	##
 	set_exec_mode
 	check_binary ${OCF_RESKEY_nfs_notify_cmd}
 
 
 	if [ -n "$OCF_RESKEY_CRM_meta_clone" ] && [ -n "$OCF_RESKEY_nfs_shared_infodir" ]; then
 		ocf_exit_reason "This RA does not support clone mode when a shared info directory is in use."
 		exit $OCF_ERR_CONFIGURED
 	fi
 
 	if [ -n "$OCF_RESKEY_nfs_smnotify_retry_time" ]; then
 		if ! ocf_is_decimal "$OCF_RESKEY_nfs_smnotify_retry_time"; then
 			ocf_exit_reason "Invalid nfs_smnotify_retry_time [$OCF_RESKEY_nfs_smnotify_retry_time]"
 			exit $OCF_ERR_CONFIGURED
 		fi
 	fi
 
 	case ${OCF_RESKEY_nfs_notify_cmd##*/} in
 	sm-notify|rpc.statd) ;;
 	*)
 		ocf_exit_reason "Invalid nfs_notify_cmd [$OCF_RESKEY_nfs_notify_cmd]"
 		exit $OCF_ERR_CONFIGURED
 		;;
 	esac
 
 	return $OCF_SUCCESS
 }
 
 nfsserver_validate
 
 case $__OCF_ACTION in
 	start)      nfsserver_start
 		;;
 	stop)       nfsserver_stop
 		;;
 	monitor)    nfsserver_monitor
 		;;
 	validate-all)   exit $OCF_SUCCESS
 		;;
 	*)      nfsserver_usage
 	exit $OCF_ERR_UNIMPLEMENTED
 	;;
 esac
 
diff --git a/heartbeat/nfsserver-redhat.sh b/heartbeat/nfsserver-redhat.sh
new file mode 100644
index 000000000..cef0862ee
--- /dev/null
+++ b/heartbeat/nfsserver-redhat.sh
@@ -0,0 +1,169 @@
+NFS_SYSCONFIG="/etc/sysconfig/nfs"
+NFS_SYSCONFIG_LOCAL_BACKUP="/etc/sysconfig/nfs.ha.bu"
+NFS_SYSCONFIG_AUTOGEN_TAG="AUTOGENERATED by $0 high availability resource-agent"
+
+nfsserver_redhat_meta_data() {
+cat<<EOF
+<parameter name="nfsd_args" unique="0" required="0">
+<longdesc lang="en">
+Specifies what arguments to pass to the nfs daemon on startup. View the rpc.nfsd man page for information on what arguments are available.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+rpc.nfsd options
+</shortdesc>
+<content type="string" />
+</parameter>
+
+<parameter name="lockd_udp_port" unique="0" required="0">
+<longdesc lang="en">
+The udp port lockd should listen on.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+lockd udp port
+</shortdesc>
+<content type="integer" />
+</parameter>
+
+<parameter name="lockd_tcp_port" unique="0" required="0">
+<longdesc lang="en">
+The tcp port lockd should listen on.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+lockd tcp port
+</shortdesc>
+<content type="integer" />
+</parameter>
+
+<parameter name="statd_outgoing_port" unique="0" required="0">
+<longdesc lang="en">
+The source port number sm-notify uses when sending reboot notifications.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+sm-notify source port
+</shortdesc>
+<content type="integer" />
+</parameter>
+
+<parameter name="statd_port" unique="0" required="0">
+<longdesc lang="en">
+The port number used for RPC listener sockets.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+rpc.statd listener port
+</shortdesc>
+<content type="integer" />
+</parameter>
+
+<parameter name="mountd_port" unique="0" required="0">
+<longdesc lang="en">
+The port number used for rpc.mountd listener sockets.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+rpc.mountd listener port
+</shortdesc>
+<content type="integer" />
+</parameter>
+
+<parameter name="rquotad_port" unique="0" required="0">
+<longdesc lang="en">
+The port number used for rpc.rquotad.
+Note that setting this value will override all settings placed in the local /etc/sysconfig/nfs file.
+</longdesc>
+<shortdesc lang="en">
+rpc.rquotad port
+</shortdesc>
+<content type="integer" />
+</parameter>
+EOF
+}
+
+set_arg()
+{
+	local key="$1"
+	local value="$2"
+	local file="$3"
+	local requires_sysconfig="$4"
+
+	if [ -z "$value" ]; then
+		return
+	fi
+
+	# only write to the tmp /etc/sysconfig/nfs if sysconfig exists.
+	# otherwise this distro does not support setting these options.
+	if [ -d "/etc/sysconfig" ]; then
+		# replace if the value exists, append otherwise
+		if grep "^\s*${key}=" $file ; then
+			sed -i "s/\s*${key}=.*$/${key}=\"${value}\"/" $file
+		else
+			echo "${key}=\"${value}\"" >> $file
+		fi
+	elif [ "$requires_sysconfig" = "true" ]; then
+		ocf_log warn "/etc/sysconfig/nfs not found, unable to set port and nfsd args."
+	fi
+
+	export ${key}="${value}"
+}
+
+set_env_args()
+{
+	local tmpconfig=$(mktemp ${HA_RSCTMP}/nfsserver-tmp-XXXXX)
+	local statd_args
+
+	if [ -f "$NFS_SYSCONFIG" ]; then
+		## Take the $NFS_SYSCONFIG file as our skeleton
+		cp $NFS_SYSCONFIG $tmpconfig
+	fi
+
+	# nfsd args
+	set_arg "RPCNFSDARGS" "$OCF_RESKEY_nfsd_args" "$tmpconfig" "true"
+
+	# mountd args
+	if [ -n "$OCF_RESKEY_mountd_port" ]; then
+		set_arg "RPCMOUNTDOPTS" "-p $OCF_RESKEY_mountd_port" "$tmpconfig" "true"
+	fi
+
+	# statd args. we always want to perform the notify using sm-notify after
+	# both rpc.statd and the nfsd daemons are initialized
+	statd_args="--no-notify"
+	if [ -n "$OCF_RESKEY_statd_outgoing_port" ]; then
+		statd_args="$statd_args -o $OCF_RESKEY_statd_outgoing_port"
+	fi
+	if [ -n "$OCF_RESKEY_statd_port" ]; then
+		statd_args="$statd_args -p $OCF_RESKEY_statd_port"
+	fi
+	set_arg "STATDARG" "$statd_args" "$tmpconfig" "false"
+
+	# lockd ports
+	set_arg "LOCKD_UDPPORT" "$OCF_RESKEY_lockd_udp_port" "$tmpconfig" "true"
+	set_arg "LOCKD_TCPPORT" "$OCF_RESKEY_lockd_tcp_port" "$tmpconfig" "true"
+
+	# rquotad_port
+	if [ -n "$OCF_RESKEY_rquotad_port" ]; then
+		set_arg "RPCRQUOTADOPTS" "-p $OCF_RESKEY_rquotad_port" "$tmpconfig" "true"
+	fi
+
+	# override local nfs config. preserve previous local config though.
+	if [ -s $tmpconfig ]; then
+		cat $NFS_SYSCONFIG | grep -q -e "$NFS_SYSCONFIG_AUTOGEN_TAG" > /dev/null 2>&1 
+		if [ $? -ne 0 ]; then
+			# backup local nfs config if it doesn't have our HA autogen tag in it.
+			mv -f $NFS_SYSCONFIG $NFS_SYSCONFIG_LOCAL_BACKUP
+		fi
+
+		cat $tmpconfig | grep -q -e "$NFS_SYSCONFIG_AUTOGEN_TAG" > /dev/null 2>&1 
+		if [ $? -ne 0 ]; then
+			echo "# $NFS_SYSCONFIG_AUTOGEN_TAG" > $NFS_SYSCONFIG
+			echo "# local config backup stored here, '$NFS_SYSCONFIG_LOCAL_BACKUP'" >> $NFS_SYSCONFIG
+			cat $tmpconfig >> $NFS_SYSCONFIG
+		else
+			cat $tmpconfig > $NFS_SYSCONFIG
+		fi
+	fi
+	rm -f $tmpconfig
+}
diff --git a/heartbeat/ocf-distro b/heartbeat/ocf-distro
new file mode 100644
index 000000000..530ee57ed
--- /dev/null
+++ b/heartbeat/ocf-distro
@@ -0,0 +1,47 @@
+#
+# This is OCF Linux distribution query support
+# 
+# Currently needed for the nfsserver RA which has some already
+# released RH specific stuff (/etc/sysconfig/nfs editing)
+# 
+
+_DEBIAN_VERSION_FILE="/etc/debian_version"
+_REDHAT_RELEASE_FILE="/etc/redhat-release"
+_SUSE_RELEASE_FILE="/etc/SuSE-release"
+_RELEASE_FILES="/etc/*-release"
+_REDHAT_BASED_DISTROS_RE='red *hat|fedora|centos|scientific linux'
+
+get_release_id() {
+	if which lsb_release >/dev/null 2>&1; then
+		lsb_release -si
+	elif [ -e $_DEBIAN_VERSION_FILE ]; then
+		echo Debian
+	elif [ -e $_SUSE_RELEASE_FILE ]; then
+		echo SUSE
+	elif [ -e $_REDHAT_RELEASE_FILE ]; then
+		echo Redhat
+	else # FIXME not exactly the id here, but will do for our purpose
+		cat $_RELEASE_FILES 2>/dev/null
+	fi
+}
+
+is_redhat_based() {
+	get_release_id | egrep -qsi "$_REDHAT_BASED_DISTROS_RE"
+}
+
+# get_os_ver() is currently unused
+get_os_ver() {
+	if which lsb_release >/dev/null 2>&1; then
+		OS=`lsb_release -si`
+		VER=`lsb_release -sr`
+	elif [ -f $_DEBIAN_VERSION_FILE ]; then
+		OS=Debian
+		VER=$(cat $_DEBIAN_VERSION_FILE)
+	elif [ -f $_REDHAT_RELEASE_FILE ]; then
+		OS=RedHat  # redhat or similar
+		VER= # here some complex sed script
+	else
+		OS=$(uname -s)
+		VER=$(uname -r)
+	fi
+}
diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in
index 2023661ab..2f5f68414 100644
--- a/heartbeat/ocf-shellfuncs.in
+++ b/heartbeat/ocf-shellfuncs.in
@@ -1,920 +1,921 @@
 #
 #
 # 	Common helper functions for the OCF Resource Agents supplied by
 # 	heartbeat.
 #
 # Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Brée
 #                    All Rights Reserved.
 #
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
 # version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 # 
 
 # Build version: $Format:%H$
 
 # TODO: Some of this should probably split out into a generic OCF
 # library for shell scripts, but for the time being, we'll just use it
 # ourselves...
 #
 
 # TODO wish-list:
 # - Generic function for evaluating version numbers
 # - Generic function(s) to extract stuff from our own meta-data
 # - Logging function which automatically adds resource identifier etc
 #   prefixes
 # TODO: Move more common functionality for OCF RAs here.
 #
 
 # This was common throughout all legacy Heartbeat agents
 unset LC_ALL; export LC_ALL
 unset LANGUAGE; export LANGUAGE
 
 __SCRIPT_NAME=`basename $0`
 
 if [ -z "$OCF_ROOT" ]; then
     : ${OCF_ROOT=@OCF_ROOT_DIR@}
 fi
 
 if [ "$OCF_FUNCTIONS_DIR" = ${OCF_ROOT}/resource.d/heartbeat ]; then  # old
 	unset OCF_FUNCTIONS_DIR
 fi
 
 : ${OCF_FUNCTIONS_DIR:=${OCF_ROOT}/lib/heartbeat}
 
 . ${OCF_FUNCTIONS_DIR}/ocf-binaries
 . ${OCF_FUNCTIONS_DIR}/ocf-returncodes
 . ${OCF_FUNCTIONS_DIR}/ocf-directories
 . ${OCF_FUNCTIONS_DIR}/ocf-rarun
+. ${OCF_FUNCTIONS_DIR}/ocf-distro
 
 # Define OCF_RESKEY_CRM_meta_interval in case it isn't already set,
 # to make sure that ocf_is_probe() always works
 : ${OCF_RESKEY_CRM_meta_interval=0}
 
 ocf_is_root() {
 	if [ X`id -u` = X0 ]; then
 		true
 	else
 		false
 	fi
 }
 
 ocf_maybe_random() {
 	local rnd="$RANDOM"
 	# Something sane-ish in case a shell doesn't support $RANDOM
 	[ -n "$rnd" ] || rnd=$$
 	echo $rnd
 }
 
 # Portability comments:
 # o The following rely on Bourne "sh" pattern-matching, which is usually
 #   that for filename generation (note: not regexp).
 # o The "*) true ;;" clause is probably unnecessary, but is included
 #   here for completeness.
 # o The negation in the pattern uses "!".  This seems to be common
 #   across many OSes (whereas the alternative "^" fails on some).
 # o If an OS is encountered where this negation fails, then a possible
 #   alternative would be to replace the function contents by (e.g.):
 #	[ -z "`echo $1 | tr -d '[0-9]'`" ]
 #
 ocf_is_decimal() {
 	case "$1" in
 	""|*[!0-9]*)	# empty, or at least one non-decimal
 		false ;;
 	*)
 		true ;;
 	esac
 }
 
 ocf_is_true() {
 	case "$1" in
 	yes|true|1|YES|TRUE|ja|on|ON) true ;;
 	*)	false ;;
 	esac
 }
 
 ocf_is_hex() {
 	case "$1" in
         ""|*[!0-9a-fA-F]*)	# empty, or at least one non-hex
 		false ;;
 	*)
 		true ;;
 	esac
 }
 
 ocf_is_octal() {
 	case "$1" in
         ""|*[!0-7]*)	# empty, or at least one non-octal
 		false ;;
 	*)
 		true ;;
 	esac
 }
 
 __ocf_set_defaults() {
 	__OCF_ACTION="$1"
 
 	# Return to sanity for the agents...
 	unset LANG
 	LC_ALL=C
 	export LC_ALL
 
 	# TODO: Review whether we really should source this. Or rewrite
 	# to match some emerging helper function syntax...? This imports
 	# things which no OCF RA should be using...
 
 	# Strip the OCF_RESKEY_ prefix from this particular parameter
 	if [ -z "$OCF_RESKEY_OCF_CHECK_LEVEL" ]; then
 		: ${OCF_CHECK_LEVEL:=0}
 	else
 		: ${OCF_CHECK_LEVEL:=$OCF_RESKEY_OCF_CHECK_LEVEL}
 	fi
 
 	if [ ! -d "$OCF_ROOT" ]; then
 		ha_log "ERROR: OCF_ROOT points to non-directory $OCF_ROOT."
 		exit $OCF_ERR_GENERIC
 	fi
 
 	if [ -z "$OCF_RESOURCE_TYPE" ]; then
 		: ${OCF_RESOURCE_TYPE:=$__SCRIPT_NAME}
 	fi
 
 	if [ -z "$OCF_RA_VERSION_MAJOR" ]; then
 		: We are being invoked as an init script.
 		: Fill in some things with reasonable values.
 		: ${OCF_RESOURCE_INSTANCE:="default"}
 		return 0
         fi
 
 	if [ "x$__OCF_ACTION" = "xmeta-data" ]; then
 		OCF_RESOURCE_INSTANCE="undef"
 	fi	
 
 	if [ -z "$OCF_RESOURCE_INSTANCE" ]; then
 		ha_log "ERROR: Need to tell us our resource instance name."
 		exit $OCF_ERR_ARGS
 	fi
 }
 
 hadate() {
   date "+${HA_DATEFMT}"
 }
 
 set_logtag() {
 	if [ -z "$HA_LOGTAG" ]; then
 		if [ -n "$OCF_RESOURCE_INSTANCE" ]; then
 			HA_LOGTAG="$__SCRIPT_NAME($OCF_RESOURCE_INSTANCE)[$$]"
 		else
 			HA_LOGTAG="$__SCRIPT_NAME[$$]"
 		fi
 	fi
 }
 
 __ha_log() {
 	local ignore_stderr=false
 	local loglevel
 
 	[ "x$1" = "x--ignore-stderr" ] && ignore_stderr=true && shift
 
 	[ none = "$HA_LOGFACILITY" ] && HA_LOGFACILITY=""
 	# if we're connected to a tty, then output to stderr
 	if tty >/dev/null; then
 		if [ "x$HA_debug" = "x0" -a "x$loglevel" = xdebug ] ; then
 			return 0
 		elif [ "$ignore_stderr" = "true" ]; then
 			# something already printed this error to stderr, so ignore
 			return 0
 		fi
 		if [ "$HA_LOGTAG" ]; then
 			echo "$HA_LOGTAG: $*"
 		else
 			echo "$*"
 		fi >&2
 		return 0
 	fi
 
 	set_logtag
 
 	if [ "x${HA_LOGD}" = "xyes" ] ; then 
 		ha_logger -t "${HA_LOGTAG}" "$@"
 		if [ "$?" -eq "0" ] ; then
 			return 0
 		fi
 	fi
 
 	if
 	  [ -n "$HA_LOGFACILITY" ]
         then
 	  : logging through syslog
 	  # loglevel is unknown, use 'notice' for now
           loglevel=notice
           case "${*}" in
             *ERROR*)		loglevel=err;;
             *WARN*)		loglevel=warning;;
             *INFO*|info)	loglevel=info;;
 	  esac
 	  logger -t "$HA_LOGTAG" -p ${HA_LOGFACILITY}.${loglevel} "${*}"
         fi	
         if
 	  [ -n "$HA_LOGFILE" ]
 	then
 	  : appending to $HA_LOGFILE
 	  echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_LOGFILE
 	fi
 	if
 	  [ -z "$HA_LOGFACILITY" -a -z "$HA_LOGFILE" ] && ! [ "$ignore_stderr" = "true" ]
 	then
 	  : appending to stderr
 	  echo `hadate`"${*}" >&2
 	fi
         if
           [ -n "$HA_DEBUGLOG" ]
         then
           : appending to $HA_DEBUGLOG
 		  if [ "$HA_LOGFILE"x != "$HA_DEBUGLOG"x ]; then
             echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_DEBUGLOG
           fi
         fi
 }
 
 ha_log()
 {
 	__ha_log "$@"
 }
 
 ha_debug() {
 
         if [ "x${HA_debug}" = "x0" ] ; then
                 return 0
         fi
 	if tty >/dev/null; then
 		if [ "$HA_LOGTAG" ]; then
 			echo "$HA_LOGTAG: $*"
 		else
 			echo "$*"
 		fi >&2
 		return 0
 	fi
 
 	set_logtag
 
         if [ "x${HA_LOGD}" = "xyes" ] ; then  
 		ha_logger -t "${HA_LOGTAG}" -D "ha-debug" "$@"
                 if [ "$?" -eq "0" ] ; then
                         return 0
                 fi
         fi
 
 	[ none = "$HA_LOGFACILITY" ] && HA_LOGFACILITY=""
 
 	if
 	  [ -n "$HA_LOGFACILITY" ]
 	then
 	  : logging through syslog
 	  logger -t "$HA_LOGTAG" -p "${HA_LOGFACILITY}.debug" "${*}"
 	fi
         if
 	  [ -n "$HA_DEBUGLOG" ]
 	then
 	  : appending to $HA_DEBUGLOG
 	  echo "$HA_LOGTAG:	"`hadate`"${*}" >> $HA_DEBUGLOG
 	fi
 	if
 	  [ -z "$HA_LOGFACILITY" -a -z "$HA_DEBUGLOG" ]
 	then
 	  : appending to stderr
 	  echo "$HA_LOGTAG:	`hadate`${*}:	${HA_LOGFACILITY}" >&2
 	fi
 }
 
 ha_parameter() {
 	local VALUE
     VALUE=`sed -e 's%[	][	]*% %' -e 's%^ %%' -e 's%#.*%%'   $HA_CF | grep -i "^$1 " | sed 's%[^ ]* %%'`
     if
 	[ "X$VALUE" = X ]
     then
 	
 	case $1 in
 	    keepalive)	VALUE=2;;
 	    deadtime)
 		ka=`ha_parameter keepalive`
 		VALUE=`expr $ka '*' 2 '+' 1`;;
 	esac
     fi
     echo $VALUE
 }
 
 ocf_log() {
 	# TODO: Revisit and implement internally.
 	if
           [ $# -lt 2 ]
         then
           ocf_log err "Not enough arguments [$#] to ocf_log."
         fi
         __OCF_PRIO="$1"
         shift
         __OCF_MSG="$*"
 
         case "${__OCF_PRIO}" in
           crit)	__OCF_PRIO="CRIT";;
           err)	__OCF_PRIO="ERROR";;
           warn)	__OCF_PRIO="WARNING";;
           info)	__OCF_PRIO="INFO";;
           debug)__OCF_PRIO="DEBUG";;
           *)	__OCF_PRIO=`echo ${__OCF_PRIO}| tr '[a-z]' '[A-Z]'`;;
 	esac
 
 	if [ "${__OCF_PRIO}" = "DEBUG" ]; then
 		ha_debug "${__OCF_PRIO}: $__OCF_MSG"
 	else
 		ha_log "${__OCF_PRIO}: $__OCF_MSG"
 	fi
 }
 
 #
 # ocf_exit_reason: print exit error string to stderr
 # Usage:           Allows the OCF script to provide a string
 #                  describing why the exit code was returned.
 # Arguments:   reason - required, The string that represents why the error
 #                       occured.
 #
 ocf_exit_reason()
 {
 	local cookie="$OCF_EXIT_REASON_PREFIX"
 	local fmt
 	local msg
 
 	# No argument is likely not intentional.
 	# Just one argument implies a printf format string of just "%s".
 	# "Least surprise" in case some interpolated string from variable
 	# expansion or other contains a percent sign.
 	# More than one argument: first argument is going to be the format string.
 	case $# in
 	0)	ocf_log err "Not enough arguments to ocf_log_exit_msg." ;;
 	1)	fmt="%s" ;;
 
 	*)	fmt=$1
 		shift
 		case $fmt in
 		*%*) : ;; # ok, does look like a format string
 		*) ocf_log warn "Does not look like format string: [$fmt]" ;;
 		esac ;;
 	esac
 
 	if [ -z "$cookie" ]; then
 		# use a default prefix
 		cookie="ocf-exit-reason:"
 	fi
 
 	msg=$(printf "${fmt}" "$@")
 	printf >&2 "%s%s\n" "$cookie" "$msg"
 	__ha_log --ignore-stderr "ERROR: $msg"
 }
 
 #
 # ocf_deprecated: Log a deprecation warning
 # Usage:          ocf_deprecated [param-name]
 # Arguments:      param-name optional, name of a boolean resource
 #                            parameter that can be used to suppress
 #                            the warning (default
 #                            "ignore_deprecation")
 ocf_deprecated() {
     local param
     param=${1:-ignore_deprecation}
     # don't use ${!param} here, it's a bashism
     if ! ocf_is_true $(eval echo \$OCF_RESKEY_$param); then
 	ocf_log warn "This resource agent is deprecated" \
 	    "and may be removed in a future release." \
 	    "See the man page for details." \
 	    "To suppress this warning, set the \"${param}\"" \
 	    "resource parameter to true."
     fi
 }
 
 #
 # Ocf_run: Run a script, and log its output.
 # Usage:   ocf_run [-q] [-info|-warn|-err] <command>
 #	-q: don't log the output of the command if it succeeds
 #	-info|-warn|-err: log the output of the command at given
 #		severity if it fails (defaults to err)
 #
 ocf_run() {
 	local rc
 	local output
 	local verbose=1
 	local loglevel=err
 	local var
 
 	for var in 1 2
 	do
 	    case "$1" in
 		"-q")
 		    verbose=""
 		    shift 1;;
 		"-info"|"-warn"|"-err")
 		    loglevel=`echo $1 | sed -e s/-//g`
 		    shift 1;;
 		*)
 		    ;;		
 	    esac
 	done
 
 	output=`"$@" 2>&1`
 	rc=$?
 	output=`echo $output`
 	if [ $rc -eq 0 ]; then 
 	    if [ "$verbose" -a ! -z "$output" ]; then
 		ocf_log info "$output"
 	    fi
 	    return $OCF_SUCCESS
 	else
 	    if [ ! -z "$output" ]; then
 		ocf_log $loglevel "$output"
 	    else
 		ocf_log $loglevel "command failed: $*"
 	    fi
 	    return $rc
 	fi
 }
 
 ocf_pidfile_status() {
     local pid pidfile=$1
     if [ ! -e $pidfile ]; then
 	# Not exists
 	return 2
     fi
     pid=`cat $pidfile`
     kill -0 $pid 2>&1 > /dev/null
     if [ $? = 0 ]; then
 	return 0
     fi
 
     # Stale
     return 1
 }
 
 ocf_take_lock() {
     local lockfile=$1
     local rnd=$(ocf_maybe_random)
 
     sleep 0.$rnd
     while 
 	ocf_pidfile_status $lockfile
     do
 	ocf_log info "Sleeping until $lockfile is released..."
 	sleep 0.$rnd
     done
     echo $$ > $lockfile
 }
 
 
 ocf_release_lock_on_exit() {
     local lockfile=$1
     trap "rm -f $lockfile" EXIT
 }
 
 # returns true if the CRM is currently running a probe. A probe is
 # defined as a monitor operation with a monitoring interval of zero.
 ocf_is_probe() {
     [ "$__OCF_ACTION" = "monitor" -a "$OCF_RESKEY_CRM_meta_interval" = 0 ]
 }
 
 # returns true if the resource is configured as a clone. This is
 # defined as a resource where the clone-max meta attribute is present,
 # and set to greater than zero.
 ocf_is_clone() {
     [ ! -z "${OCF_RESKEY_CRM_meta_clone_max}" ] && [ "${OCF_RESKEY_CRM_meta_clone_max}" -gt 0 ]
 }
 
 # returns true if the resource is configured as a multistate
 # (master/slave) resource. This is defined as a resource where the
 # master-max meta attribute is present, and set to greater than zero.
 ocf_is_ms() {
     [ ! -z "${OCF_RESKEY_CRM_meta_master_max}" ] && [ "${OCF_RESKEY_CRM_meta_master_max}" -gt 0 ]
 }
 
 # version check functions
 # allow . and - to delimit version numbers
 # max version number is 999
 # letters and such are effectively ignored
 #
 ocf_is_ver() {
 	echo $1 | grep '^[0-9][0-9.-]*[0-9]$' >/dev/null 2>&1
 }
 ocf_ver2num() {
 	echo $1 | awk -F'[.-]' '
 	{for(i=1; i<=NF; i++) s=s*1000+$i; print s}
 	'
 }
 ocf_ver_level(){
 	echo $1 | awk -F'[.-]' '{print NF}'
 }
 ocf_ver_complete_level(){
 	local ver="$1"
 	local level="$2"
 	local i=0
 	while [ $i -lt $level ]; do
 		ver=${ver}.0
 		i=`expr $i + 1`
 	done
 	echo $ver
 }
 
 # usage: ocf_version_cmp VER1 VER2
 #     version strings can contain digits, dots, and dashes
 #     must start and end with a digit
 # returns:
 #     0: VER1 smaller (older) than VER2
 #     1: versions equal
 #     2: VER1 greater (newer) than VER2
 #     3: bad format
 ocf_version_cmp() {
 	ocf_is_ver "$1" || return 3
 	ocf_is_ver "$2" || return 3
 	local v1=$1
 	local v2=$2
 	local v1_level=`ocf_ver_level $v1`
 	local v2_level=`ocf_ver_level $v2`
 	local level_diff
 	if [ $v1_level -lt $v2_level ]; then
 		level_diff=`expr $v2_level - $v1_level`
 		v1=`ocf_ver_complete_level $v1 $level_diff`
 	elif [ $v1_level -gt $v2_level ]; then
 		level_diff=`expr $v1_level - $v2_level`
 		v2=`ocf_ver_complete_level $v2 $level_diff`
 	fi
 	v1=`ocf_ver2num $v1`
 	v2=`ocf_ver2num $v2`
 	if [ $v1 -eq $v2 ]; then
 		return 1
 	elif [ $v1 -lt $v2 ]; then
 		return 0
 	else
 		return 2 # -1 would look funny in shell ;-)
 	fi
 }
 
 ocf_local_nodename() {
 	# use crm_node -n for pacemaker > 1.1.8
 	which pacemakerd > /dev/null 2>&1
 	if [ $? -eq 0 ]; then
 		local version=$(pacemakerd -$ | grep "Pacemaker .*" | awk '{ print $2 }')
 		version=$(echo $version | awk -F- '{ print $1 }')
 		ocf_version_cmp "$version" "1.1.8"
 		if [ $? -eq 2 ]; then
 			which crm_node > /dev/null 2>&1
 			if [ $? -eq 0 ]; then
 				crm_node -n
 				return
 			fi
 		fi
 	fi
 
 	# otherwise use uname -n
 	uname -n
 }
 
 # usage: dirname DIR
 dirname()
 {
 	local a
 	local b
 
 	[ $# = 1 ] || return 1
 	a="$1"
 	while [ 1 ]; do
 		b="${a%/}"
 		[ "$a" = "$b" ] && break
 		a="$b"
 	done
 	b=${a%/*}
 	[ -z "$b" -o "$a" = "$b"  ] && b="."
 
 	echo "$b"
 	return 0
 }
 
 #
 # pseudo_resource status tracking function...
 #
 # This allows pseudo resources to give correct status information.  As we add
 # resource monitoring, and better resource tracking in general, this will
 # become essential.
 #
 # These scripts work because ${HA_RSCTMP} is cleaned out every time
 # heartbeat is started.
 #
 # We create "resource-string" tracking files under ${HA_RSCTMP} in a
 # very simple way:
 #
 #	Existence of "${HA_RSCTMP}/resource-string" means that we consider
 #	the resource named by "resource-string" to be running.
 #
 # Note that "resource-string" needs to be unique.  Using the resource type
 # plus the resource instance arguments to make up the resource string
 # is probably sufficient...
 #
 # usage: ha_pseudo_resource resource-string op [tracking_file]
 # 	where op is {start|stop|monitor|status|restart|reload|print}
 #	print is a special op which just prints the tracking file location
 #	user can override our choice of the tracking file location by
 #		specifying it as the third arg
 #	Note that all operations are silent...
 #
 ha_pseudo_resource()
 {
   local ha_resource_tracking_file="${3:-${HA_RSCTMP}/$1}"
   case $2 in
     start|restart|reload)  touch "$ha_resource_tracking_file";;
     stop) rm -f "$ha_resource_tracking_file";;
     status|monitor)
            if
              [ -f "$ha_resource_tracking_file" ]
            then
              return 0
            else
              case $2 in
                status)	return 3;;
                *)	return 7;;
              esac
            fi;;
     print)  echo "$ha_resource_tracking_file";;
     *)	return 3;;
   esac
 }
 
 # usage: rmtempdir TMPDIR
 rmtempdir()
 {
 	[ $# = 1 ] || return 1
 	if [ -e "$1" ]; then
 		rmdir "$1" || return 1
 	fi
 	return 0
 }
 
 # usage: maketempfile [-d]
 maketempfile()
 {
 	if [ $# = 1 -a "$1" = "-d" ]; then
 		mktemp -d
 		return -0
 	elif [ $# != 0 ]; then
 		return 1
 	fi
 
 	mktemp
 	return 0
 }
 
 # usage: rmtempfile TMPFILE
 rmtempfile ()
 {
 	[ $# = 1 ] || return 1
 	if [ -e "$1" ]; then
 		rm "$1" || return 1
 	fi
 	return 0
 }
 
 # echo the first lower supported check level
 # pass set of levels supported by the agent
 # (in increasing order, 0 is optional)
 ocf_check_level()
 {
 	local lvl prev
 	lvl=0
 	prev=0
 	if ocf_is_decimal "$OCF_CHECK_LEVEL"; then
 		# the level list should be very short
 		for lvl; do
 			if [ "$lvl" -eq "$OCF_CHECK_LEVEL" ]; then
 				break
 			elif [ "$lvl" -gt "$OCF_CHECK_LEVEL" ]; then
 				lvl=$prev # the previous one
 				break
 			fi
 			prev=$lvl
 		done
 	fi
 	echo $lvl
 }
 
 # usage: ocf_stop_processes SIGNALS WAIT_TIME PIDS
 #
 # we send signals (use quotes for more than one!) in the order
 # given; if one or more processes are still running we try KILL;
 # the wait_time is the _total_ time we'll spend in this function
 # this time may be slightly exceeded if the processes won't leave
 # 
 # returns:
 #     0: all processes left
 #     1: some processes still running
 #
 # example:
 #
 # ocf_stop_processes TERM 5 $pids
 # 
 ocf_stop_processes() {
 	local signals="$1"
 	local wait_time="$(($2/`echo $signals|wc -w`))"
 	shift 2
 	local pids="$*"
 	local sig i
 	test -z "$pids" &&
 		return 0
 	for sig in $signals KILL; do
 		kill -s $sig $pids 2>/dev/null
 		# try to leave early, and yet leave processes time to exit
 		sleep 0.2
 		for i in `seq $wait_time`; do
 			kill -s 0 $pids 2>/dev/null ||
 				return 0
 			sleep 1
 		done
 	done
 	return 1
 }
 
 #
 # create a given status directory
 # if the directory path doesn't start with $HA_VARRUN, then
 # we return with error (most of the calls would be with the user
 # supplied configuration, hence we need to do necessary
 # protection)
 # used mostly for PID files
 #
 # usage: ocf_mkstatedir owner permissions path
 #
 # owner: user.group
 # permissions: permissions
 # path: directory path
 #
 # example:
 #	ocf_mkstatedir named 755 `dirname $pidfile`
 #
 ocf_mkstatedir()
 {
 	local owner
 	local perms
 	local path
 
 	owner=$1
 	perms=$2
 	path=$3
 
 	test -d $path && return 0
 	[ $(id -u) = 0 ] || return 1
 
 	case $path in
 	$HA_VARRUN/*) : this path is ok ;;
 	*) ocf_log err "cannot create $path (does not start with $HA_VARRUN)"
 		return 1
 	;;
 	esac
 
 	mkdir -p $path &&
 	chown $owner $path &&
 	chmod $perms $path
 }
 
 #
 # create a unique status directory in $HA_VARRUN
 # used mostly for PID files
 # the directory is by default set to
 #   $HA_VARRUN/$OCF_RESOURCE_INSTANCE
 # the directory name is printed to stdout
 #
 # usage: ocf_unique_rundir owner permissions name
 #
 # owner: user.group (default: "root")
 # permissions: permissions (default: "755")
 # name: some unique string (default: "$OCF_RESOURCE_INSTANCE")
 #
 # to use the default either don't set the parameter or set it to
 # empty string ("")
 # example:
 #
 #	STATEDIR=`ocf_unique_rundir named "" myownstatedir`
 #
 ocf_unique_rundir()
 {
 	local path
 	local owner
 	local perms
 	local name
 
 	owner=${1:-"root"}
 	perms=${2:-"755"}
 	name=${3:-"$OCF_RESOURCE_INSTANCE"}
 	path=$HA_VARRUN/$name
 	if [ ! -d $path ]; then
 		[ $(id -u) = 0 ] || return 1
 		mkdir -p $path &&
 		chown $owner $path &&
 		chmod $perms $path || return 1
 	fi
 	echo $path
 }
 
 #
 # RA tracing may be turned on by setting OCF_TRACE_RA
 # the trace output will be saved to OCF_TRACE_FILE, if set, or
 # by default to
 #   $HA_VARLIB/trace_ra/<type>/<id>.<action>.<timestamp>
 #   e.g. $HA_VARLIB/trace_ra/oracle/db.start.2012-11-27.08:37:08
 #
 # OCF_TRACE_FILE:
 # - FD (small integer [3-9]) in that case it is up to the callers
 #   to capture output; the FD _must_ be open for writing
 # - absolute path
 #
 # NB: FD 9 may be used for tracing with bash >= v4 in case
 # OCF_TRACE_FILE is set to a path.
 #
 ocf_is_bash4() {
 	echo "$SHELL" | grep bash > /dev/null &&
 			[ ${BASH_VERSINFO[0]} = "4" ]
 }
 ocf_trace_redirect_to_file() {
 	local dest=$1
 	if ocf_is_bash4; then
 		exec 9>$dest
 		BASH_XTRACEFD=9
 	else
 		exec 2>$dest
 	fi
 }
 ocf_trace_redirect_to_fd() {
 	local fd=$1
 	if ocf_is_bash4; then
 		BASH_XTRACEFD=$fd
 	else
 		exec 2>&$fd
 	fi
 }
 __ocf_test_trc_dest() {
 	local dest=$1
 	if ! touch $dest; then
 		ocf_log warn "$dest not writable, trace not going to happen"
 		__OCF_TRC_DEST=""
 		__OCF_TRC_MANAGE=""
 		return 1
 	fi
 	return 0
 }
 ocf_default_trace_dest() {
 	tty >/dev/null && return
 	if [ -n "$OCF_RESOURCE_TYPE" -a \
 			-n "$OCF_RESOURCE_INSTANCE" -a -n "$__OCF_ACTION" ]; then
 		local ts=`date +%F.%T`
 		__OCF_TRC_DEST=$HA_VARLIB/trace_ra/${OCF_RESOURCE_TYPE}/${OCF_RESOURCE_INSTANCE}.${__OCF_ACTION}.$ts
 		__OCF_TRC_MANAGE="1"
 	fi
 }
 
 ocf_start_trace() {
 	export __OCF_TRC_DEST="" __OCF_TRC_MANAGE=""
 	case "$OCF_TRACE_FILE" in
 	[3-9]) ocf_trace_redirect_to_fd "$OCF_TRACE_FILE" ;;
 	/*/*) __OCF_TRC_DEST=$OCF_TRACE_FILE ;;
 	"") ocf_default_trace_dest ;;
 	*)
 		ocf_log warn "OCF_TRACE_FILE must be set to either FD (open for writing) or absolute file path"
 		ocf_default_trace_dest
 		;;
 	esac
 	if [ "$__OCF_TRC_DEST" ]; then
 		mkdir -p `dirname $__OCF_TRC_DEST`
 		__ocf_test_trc_dest $__OCF_TRC_DEST ||
 			return
 		ocf_trace_redirect_to_file "$__OCF_TRC_DEST"
 	fi
 	PS4='+ `date +"%T"`: ${FUNCNAME[0]:+${FUNCNAME[0]}:}${LINENO}: '
 	set -x
 	env=$( echo; printenv | sort )
 }
 ocf_stop_trace() {
 	set +x
 }
 
 __ocf_set_defaults "$@"
 
 : ${OCF_TRACE_RA:=$OCF_RESKEY_trace_ra}
 ocf_is_true "$OCF_TRACE_RA" && ocf_start_trace
 
 # pacemaker sets HA_use_logd, some others use HA_LOGD :/
 if ocf_is_true "$HA_use_logd"; then
 	: ${HA_LOGD:=yes}
 fi