Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F2825137
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in
index 2956d1264..6be4e4e30 100644
--- a/heartbeat/ocf-shellfuncs.in
+++ b/heartbeat/ocf-shellfuncs.in
@@ -1,1048 +1,1048 @@
#
#
# 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
: ${HA_SBIN_DIR:=@sbindir@}
__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|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" ] || [ -z "${HA_debug}" ] ; 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 > /dev/null 2>&1
- if [ $? = 0 ]; then
- return 0
- fi
+ local pid pidfile="$1"
+ if [ ! -e "$pidfile" ]; then
+ # Not exists
+ return 2
+ fi
+ pid=$(cat "$pidfile")
+ kill -0 "$pid" > /dev/null 2>&1
+ if [ $? = 0 ]; then
+ return 0
+ fi
- # Stale
- return 1
+ # 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.
ocf_is_clone() {
[ ! -z "${OCF_RESKEY_CRM_meta_clone_max}" ]
}
# 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() {
[ "${OCF_RESKEY_CRM_meta_promotable}" = "true" ] || { [ ! -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
#
ocf_is_ver() {
echo $1 | grep '^[0-9][0-9.-]*[0-9A-Za-z.\+-]*$' >/dev/null 2>&1
}
# 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
sort_version="sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n"
older=$( (echo "$v1"; echo "$v2") | $sort_version | head -1 )
if [ "$v1" = "$v2" ]; then
return 1
elif [ "$v1" = "$older" ]; 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 -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
}
# usage: crm_mon_no_validation args...
# run crm_mon without any cib schema validation
# This is useful when an agent runs in a bundle to avoid potential
# schema validation errors when host and bundle are not perfectly aligned
# To be used, your shell must support on process substitution (e.g. bash)
# returns:
# <crm_mon error codes>
crm_mon_no_validation()
{
# The subshell prevents parsing error with incompatible shells
"$SHELL" -c "CIB_file=<(${HA_SBIN_DIR}/cibadmin -Q | sed 's/validate-with=\"[^\"]*\"/validate-with=\"none\"/') \
${HA_SBIN_DIR}/crm_mon \$*" -- $*
}
#
# 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_bash_has_xtracefd() {
[ -n "$BASH_VERSION" ] && [ ${BASH_VERSINFO[0]} -ge 4 ]
}
# for backwards compatibility
ocf_is_bash4() {
ocf_bash_has_xtracefd
}
ocf_trace_redirect_to_file() {
local dest=$1
if ocf_bash_has_xtracefd; then
exec 9>$dest
BASH_XTRACEFD=9
else
exec 2>$dest
fi
}
ocf_trace_redirect_to_fd() {
local fd=$1
if ocf_bash_has_xtracefd; 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=${OCF_RESKEY_trace_dir}/${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_RESKEY_trace_dir:="$HA_VARLIB/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
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:31 AM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322376
Default Alt Text
(26 KB)
Attached To
Mode
rR Resource Agents
Attached
Detach File
Event Timeline
Log In to Comment