diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in
index 4a74e201d..08a672451 100644
--- a/heartbeat/ocf-shellfuncs.in
+++ b/heartbeat/ocf-shellfuncs.in
@@ -1,922 +1,922 @@
 #
 #
 # 	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 [ "x$__OCF_ACTION" = "xmeta-data" ]; then
 		: ${OCF_RESOURCE_INSTANCE:="RESOURCE_ID"}
 	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 [ -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 `hadate`" $HA_LOGTAG:    ${*}" >> $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" | tr -s ' \t\r\n' ' '`
 	if [ $rc -eq 0 ]; then 
 	    if [ "$verbose" -a ! -z "$output" ]; then
 		ocf_log info "$output"
 	    fi
 	else
 	    if [ ! -z "$output" ]; then
 		ocf_log $loglevel "$output"
 	    else
 		ocf_log $loglevel "command failed: $*"
 	    fi
 	fi
 
 	return $rc
 }
 
 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
+	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 on node reboot.
 #
 # 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
 	if [ -n "$BASH_VERSION" ]; then
 		PS4='+ `date +"%T"`: ${FUNCNAME[0]:+${FUNCNAME[0]}:}${LINENO}: '
 	fi
 	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