Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in
index 3c3cc4d38..8e44f09eb 100644
--- a/heartbeat/ocf-shellfuncs.in
+++ b/heartbeat/ocf-shellfuncs.in
@@ -1,1051 +1,1056 @@
#
#
# 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() {
if test -c /dev/urandom; then
od -An -N4 -tu4 /dev/urandom | tr -d '[:space:]'
else
awk -v pid=$$ 'BEGIN{srand(pid); print rand()}' | sed 's/^.*[.]//'
fi
}
# 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=$?
[ -n "$output" ] && 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
}
# mkdir(1) based locking
# first the directory is created with the name given as $1
# then a file named "pid" is created within that directory with
# the process PID
# stale locks are handled carefully, the inode of a directory
# needs to match before and after test if the process is running
# empty directories are also handled appropriately
# we relax (sleep) occasionally to allow for other processes to
# finish managing the lock in case they are in the middle of the
# business
relax() { sleep 0.5; }
ocf_get_stale_pid() {
local piddir pid dir_inode
piddir="$1"
[ -z "$piddir" ] && return 2
dir_inode="`ls -di $piddir 2>/dev/null`"
[ -z "$dir_inode" ] && return 1
pid=`cat $piddir/pid 2>/dev/null`
if [ -z "$pid" ]; then
# empty directory?
relax
if [ "$dir_inode" = "`ls -di $piddir 2>/dev/null`" ]; then
echo $dir_inode
else
return 1
fi
elif kill -0 $pid >/dev/null 2>&1; then
return 1
elif relax && [ -e "$piddir/pid" ] && [ "$dir_inode" = "`ls -di $piddir 2>/dev/null`" ]; then
echo $pid
else
return 1
fi
}
# There is a race when the following two functions to manage the
# lock file (mk and rm) are invoked in parallel by different
# instances. It is up to the caller to reduce probability of that
# taking place (see ocf_take_lock() below).
ocf_mk_pid() {
mkdir $1 2>/dev/null && echo $$ > $1/pid
}
ocf_rm_pid() {
rm -f $1/pid
rmdir $1 2>/dev/null
}
# Testing and subsequently removing a stale lock (containing the
# process pid) is inherently difficult to do in such a way as to
# prevent a race between creating a pid file and removing it and
# its directory. We reduce the probability of that happening by
# checking if the stale lock persists over a random period of
# time.
ocf_take_lock() {
local lockdir=$1
local rnd
local stale_pid
# we don't want it too short, so strip leading zeros
rnd=$(ocf_maybe_random | sed 's/^0*//')
stale_pid=`ocf_get_stale_pid $lockdir`
if [ -n "$stale_pid" ]; then
sleep 0.$rnd
# remove "stale pid" only if it persists
[ "$stale_pid" = "`ocf_get_stale_pid $lockdir`" ] &&
ocf_rm_pid $lockdir
fi
while ! ocf_mk_pid $lockdir; do
ocf_log info "Sleeping until $lockdir is released..."
sleep 0.$rnd
done
}
ocf_release_lock_on_exit() {
trap "ocf_rm_pid $1" 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
}
# usage: systemd_is_running
# returns:
# 0 PID 1 is systemd
# 1 otherwise
systemd_is_running()
{
[ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ]
}
# usage: systemd_drop_in <name> <After|Before> <dependency.service>
systemd_drop_in()
{
+ local conf_file
if [ $# -ne 3 ]; then
ocf_log err "Incorrect number of arguments [$#] for systemd_drop_in."
fi
systemdrundir="/run/systemd/system/resource-agents-deps.target.d"
- mkdir "$systemdrundir"
- cat > "$systemdrundir/$1.conf" <<EOF
+ mkdir -p "$systemdrundir"
+ conf_file="$systemdrundir/$1.conf"
+ cat >"$conf_file" <<EOF
[Unit]
$2=$3
EOF
+ # The information is accessible through systemd API and systemd would
+ # complain about improper permissions.
+ chmod o+r "$conf_file"
systemctl daemon-reload
}
#
# 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
}
# Helper functions to map from nodename/bundle-name and physical hostname
# list_index_for_word "node0 node1 node2 node3 node4 node5" node4 --> 5
# list_word_at_index "NA host1 host2 host3 host4 host5" 3 --> host2
# list_index_for_word "node1 node2 node3 node4 node5" node7 --> ""
# list_word_at_index "host1 host2 host3 host4 host5" 8 --> ""
# attribute_target node1 --> host1
list_index_for_word() {
echo $1 | tr ' ' '\n' | awk -v x="$2" '$0~x {print NR}'
}
list_word_at_index() {
echo $1 | tr ' ' '\n' | awk -v n="$2" 'n == NR'
}
ocf_attribute_target() {
if [ x$1 = x ]; then
if [ x$OCF_RESKEY_CRM_meta_container_attribute_target = xhost -a x$OCF_RESKEY_CRM_meta_physical_host != x ]; then
echo $OCF_RESKEY_CRM_meta_physical_host
else
if [ x$OCF_RESKEY_CRM_meta_on_node != x ]; then
echo $OCF_RESKEY_CRM_meta_on_node
else
ocf_local_nodename
fi
fi
return
elif [ x"$OCF_RESKEY_CRM_meta_notify_all_uname" != x ]; then
index=$(list_index_for_word "$OCF_RESKEY_CRM_meta_notify_all_uname" $1)
mapping=""
if [ x$index != x ]; then
mapping=$(list_word_at_index "$OCF_RESKEY_CRM_meta_notify_all_hosts" $index)
fi
if [ x$mapping != x -a x$mapping != xNA ]; then
echo $mapping
return
fi
fi
echo $1
}
__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

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:19 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322323
Default Alt Text
(26 KB)

Event Timeline