summaryrefslogtreecommitdiffstats
path: root/rgmanager/src/resources/utils
diff options
context:
space:
mode:
Diffstat (limited to 'rgmanager/src/resources/utils')
-rw-r--r--rgmanager/src/resources/utils/Makefile.am37
-rw-r--r--rgmanager/src/resources/utils/config-utils.sh.in309
-rw-r--r--rgmanager/src/resources/utils/fs-lib.sh.in1230
-rwxr-xr-xrgmanager/src/resources/utils/httpd-parse-config.pl83
-rw-r--r--rgmanager/src/resources/utils/member_util.sh.in116
-rw-r--r--rgmanager/src/resources/utils/messages.sh.in269
-rw-r--r--rgmanager/src/resources/utils/named-parse-config.pl49
-rw-r--r--rgmanager/src/resources/utils/ra-skelet.sh.in156
-rw-r--r--rgmanager/src/resources/utils/rhev-check.sh55
-rw-r--r--rgmanager/src/resources/utils/tomcat-parse-config.pl63
10 files changed, 2367 insertions, 0 deletions
diff --git a/rgmanager/src/resources/utils/Makefile.am b/rgmanager/src/resources/utils/Makefile.am
new file mode 100644
index 0000000..48b0b6a
--- /dev/null
+++ b/rgmanager/src/resources/utils/Makefile.am
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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
+
+commonscripts = fs-lib.sh \
+ httpd-parse-config.pl \
+ member_util.sh \
+ messages.sh \
+ named-parse-config.pl \
+ ra-skelet.sh \
+ tomcat-parse-config.pl \
+ config-utils.sh
+
+EXTRA_DIST = $(commonscripts) \
+ rhev-check.sh
+
+sbin_SCRIPTS = rhev-check.sh
+
+rasutilsdir = ${CLUSTERDATA}/utils
+
+rasutils_SCRIPTS = $(commonscripts)
diff --git a/rgmanager/src/resources/utils/config-utils.sh.in b/rgmanager/src/resources/utils/config-utils.sh.in
new file mode 100644
index 0000000..b59bcc7
--- /dev/null
+++ b/rgmanager/src/resources/utils/config-utils.sh.in
@@ -0,0 +1,309 @@
+#!@BASH_SHELL@
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+declare RA_COMMON_pid_dir=/var/run/cluster
+declare RA_COMMON_conf_dir=/etc/cluster
+
+declare -i FAIL=255
+declare -a ip_keys
+
+generate_configTemplate()
+{
+ cat > "$1" << EOT
+#
+# "$1" was created from the "$2"
+#
+# This template configuration was automatically generated, and will be
+# automatically regenerated if removed. Once this file has been altered,
+# automatic re-generation will stop. Remember to copy this file to all
+# other cluster members after making changes, or your service will not
+# operate correctly.
+#
+EOT
+}
+
+generate_configTemplateXML()
+{
+ cat > "$1" << EOT
+<!--
+ "$1" was created from the "$2"
+
+ This template configuration was automatically generated, and will be
+ automatically regenerated if removed. Once this file has been altered,
+ automatic re-generation will stop. Remember to copy this file to all
+ other cluster members after making changes, or your service will not
+ operate correctly.
+-->
+EOT
+}
+
+sha1_addToFile()
+{
+ declare sha1line="# rgmanager-sha1 $(sha1sum "$1")"
+ echo $sha1line >> "$1"
+}
+
+sha1_addToFileXML()
+{
+ declare sha1line="<!--# rgmanager-sha1 $(sha1sum "$1")-->"
+ echo $sha1line >> "$1"
+}
+
+sha1_verify()
+{
+ declare sha1_new sha1_old
+ declare oldFile=$1
+
+ ocf_log debug "Checking: SHA1 checksum of config file $oldFile"
+
+ sha1_new=`cat "$oldFile" | grep -v "# rgmanager-sha1" | sha1sum | sed 's/^\([a-z0-9]\+\) .*$/\1/'`
+ sha1_old=`tail -n 1 "$oldFile" | sed 's/^\(<!--\)\?# rgmanager-sha1 \(.*\)$/\2/' | sed 's/^\([a-z0-9]\+\) .*$/\1/'`
+
+ if [ "$sha1_new" = "$sha1_old" ]; then
+ ocf_log debug "Checking: SHA1 checksum > succeed"
+ return 0;
+ else
+ ocf_log debug "Checking: SHA1 checksum > failed - file changed"
+ return 1;
+ fi
+}
+
+#
+# Usage: ccs_get key
+#
+ccs_get()
+{
+ declare outp
+ declare key
+
+ [ -n "$1" ] || return $FAIL
+
+ key="$*"
+
+ outp=$(ccs_tool query "$key" 2>&1)
+ if [ $? -ne 0 ]; then
+ if [[ "$outp" =~ "Query failed: Invalid argument" ]]; then
+ # This usually means that element does not exist
+ # e.g. when checking for IP address
+ return 0;
+ fi
+
+ if [ "$outp" = "${outp/No data available/}" ] || [ "$outp" = "${outp/Operation not permitted/}" ]; then
+ ocf_log err "$outp ($key)"
+ return $FAIL
+ fi
+
+ # no real error, just no data available
+ return 0
+ fi
+
+ echo $outp
+
+ return 0
+}
+
+#
+# Build a list of service IP keys; traverse refs if necessary
+# Usage: get_service_ip_keys desc serviceName
+#
+get_service_ip_keys()
+{
+ declare svc=$1
+ declare -i x y=0
+ declare outp
+ declare key
+
+ #
+ # Find service-local IP keys
+ #
+ x=1
+ while : ; do
+ key="/cluster/rm/service[@name=\"$svc\"]/ip[$x]"
+
+ #
+ # Try direct method
+ #
+ outp=$(ccs_get "$key/@address")
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ #
+ # Try by reference
+ #
+ if [ -z "$outp" ]; then
+ outp=$(ccs_get "$key/@ref")
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+ key="/cluster/rm/resources/ip[@address=\"$outp\"]"
+ fi
+
+ if [ -z "$outp" ]; then
+ break
+ fi
+
+ #ocf_log debug "IP $outp found @ $key"
+
+ ip_keys[$y]="$key"
+
+ ((y++))
+ ((x++))
+ done
+
+ ocf_log debug "$y IP addresses found for $svc/$OCF_RESKEY_name"
+
+ return 0
+}
+
+build_ip_list()
+{
+ declare ipaddrs ipaddr
+ declare -i x=0
+
+ while [ -n "${ip_keys[$x]}" ]; do
+ ipaddr=$(ccs_get "${ip_keys[$x]}/@address")
+ if [ -z "$ipaddr" ]; then
+ break
+ fi
+
+ # remove netmask
+ iponly=`echo $ipaddr | sed 's/\/.*//'`
+ ipaddrs="$ipaddrs $iponly"
+ ((x++))
+ done
+
+ echo $ipaddrs
+}
+
+generate_name_for_pid_file()
+{
+ declare filename=$(basename $0)
+
+ echo "$RA_COMMON_pid_dir/$(basename $0 | sed 's/^\(.*\)\..*/\1/')/$OCF_RESOURCE_INSTANCE.pid"
+
+ return 0;
+}
+
+generate_name_for_pid_dir()
+{
+ declare filename=$(basename $0)
+
+ echo "$RA_COMMON_pid_dir/$(basename $0 | sed 's/^\(.*\)\..*/\1/')/$OCF_RESOURCE_INSTANCE"
+
+ return 0;
+}
+
+generate_name_for_conf_dir()
+{
+ declare filename=$(basename $0)
+
+ echo "$RA_COMMON_conf_dir/$(basename $0 | sed 's/^\(.*\)\..*/\1/')/$OCF_RESOURCE_INSTANCE"
+
+ return 0;
+}
+
+set_pid_directory_permissions()
+{
+ declare program_name="$1"
+ declare dirname="$2"
+ declare username="$3"
+
+ if [ "$program_name" = "mysql" ]; then
+ if [ -n "$username" ]; then
+ chown "${username}.root" "$dirname"
+ else
+ chown mysql.root "$dirname"
+ fi
+ elif [ "$program_name" = "tomcat-5" -o "$program_name" = "tomcat-6" ]; then
+ if [ -n "$username" ]; then
+ chown "${username}.root" "$dirname"
+ else
+ chown tomcat.root "$dirname"
+ fi
+ elif [ "$program_name" = "named" ]; then
+ if [ -n "$username" ]; then
+ chown "${username}.root" "$dirname"
+ fi
+ fi
+}
+
+#
+# Usage: create_pid_directory [username]
+#
+create_pid_directory()
+{
+ declare program_name="$(basename $0 | sed 's/^\(.*\)\..*/\1/')"
+ declare dirname="$RA_COMMON_pid_dir/$program_name"
+ declare username="$1"
+
+ if [ -d "$dirname" ]; then
+ # make sure the permissions are correct even if directory exists
+ set_pid_directory_permissions "$program_name" "$dirname" "$username"
+ return 0;
+ fi
+
+ chmod 711 "$RA_COMMON_pid_dir"
+ mkdir -p "$dirname"
+
+ set_pid_directory_permissions "$program_name" "$dirname" "$username"
+ return 0;
+}
+
+create_conf_directory()
+{
+ declare dirname="$1"
+
+ if [ -d "$dirname" ]; then
+ return 0;
+ fi
+
+ mkdir -p "$dirname"
+
+ return 0;
+}
+
+check_pid_file() {
+ declare pid_file="$1"
+
+ if [ -z "$pid_file" ]; then
+ return 1;
+ fi
+
+ if [ ! -e "$pid_file" ]; then
+ return 0;
+ fi
+
+ ## if PID file is empty then it should be safe to remove it
+ read pid < "$pid_file"
+ if [ -z "$pid" ]; then
+ rm $pid_file
+ ocf_log debug "PID File \"$pid_file\" Was Removed - Zero length";
+ return 0;
+ fi
+
+ if [ ! -d /proc/`cat "$pid_file"` ]; then
+ rm "$pid_file"
+ ocf_log debug "PID File \"$pid_file\" Was Removed - PID Does Not Exist";
+ return 0;
+ fi
+
+ return 1;
+}
diff --git a/rgmanager/src/resources/utils/fs-lib.sh.in b/rgmanager/src/resources/utils/fs-lib.sh.in
new file mode 100644
index 0000000..8b0ef5e
--- /dev/null
+++ b/rgmanager/src/resources/utils/fs-lib.sh.in
@@ -0,0 +1,1230 @@
+#!@BASH_SHELL@
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+#
+# File system common functions
+#
+
+LC_ALL=C
+LANG=C
+PATH=/bin:/sbin:/usr/bin:/usr/sbin
+export LC_ALL LANG PATH
+
+# Define this value to 0 by default, bind-mount.sh or any other agent
+# that uses this value will alter it after sourcing fs-lib.sh
+export IS_BIND_MOUNT=0
+
+# Private return codes
+FAIL=2
+NO=1
+YES=0
+YES_STR="yes"
+
+[ -z "$OCF_RESOURCE_INSTANCE" ] && export OCF_RESOURCE_INSTANCE="filesystem:$OCF_RESKEY_name"
+
+#
+# Using a global to contain the return value saves
+# clone() operations. This is important to reduce
+# resource consumption during status checks.
+#
+# There is no way to return a string from a function
+# in bash without cloning the process, which is exactly
+# what we are trying to avoid. So, we have to resort
+# to using a dedicated global variables.
+declare REAL_DEVICE
+declare STRIP_SLASHES=""
+declare FINDMNT_OUTPUT=""
+
+#
+# Stub ocf_log function for when we are using
+# quick_status, since ocf_log generally forks (and
+# sourcing ocf-shellfuncs forks -a lot-).
+#
+ocf_log()
+{
+ echo $*
+}
+
+#
+# Assume NFS_TRICKS are not available until we are
+# proved otherwise.
+#
+export NFS_TRICKS=1
+
+#
+# Quick status doesn't fork() or clone() when using
+# device files directly. (i.e. not symlinks, LABEL= or
+# UUID=
+#
+if [ "$1" = "status" -o "$1" = "monitor" ] &&
+ [ "$OCF_RESKEY_quick_status" = "1" ]; then
+ echo Using Quick Status
+
+ # XXX maybe we can make ocf-shellfuncs have a 'quick' mode too?
+ export OCF_SUCCESS=0
+ export OCF_ERR_GENERIC=1
+else
+ #
+ # Grab nfs lock tricks if available
+ #
+ if [ -f "$(dirname $0)/svclib_nfslock" ]; then
+ . $(dirname $0)/svclib_nfslock
+ NFS_TRICKS=0
+ fi
+
+ . $(dirname $0)/ocf-shellfuncs
+fi
+
+
+verify_name()
+{
+ if [ -z "$OCF_RESKEY_name" ]; then
+ ocf_log err "No file system name specified."
+ return $OCF_ERR_ARGS
+ fi
+ return $OCF_SUCCESS
+}
+
+
+verify_mountpoint()
+{
+ if [ -z "$OCF_RESKEY_mountpoint" ]; then
+ ocf_log err "No mount point specified."
+ return $OCF_ERR_ARGS
+ fi
+
+ if ! [ -e "$OCF_RESKEY_mountpoint" ]; then
+ ocf_log info "Mount point $OCF_RESKEY_mountpoint will be "\
+ "created at mount time."
+ return $OCF_SUCCESS
+ fi
+
+ [ -d "$OCF_RESKEY_mountpoint" ] && return $OCF_SUCCESS
+
+ ocf_log err "$OCF_RESKEY_mountpoint exists but is not a directory."
+
+ return $OCF_ERR_ARGS
+}
+
+
+#
+# This used to be called using $(...), but doing this causes bash
+# to set up a pipe and clone(). So, the output of this function is
+# stored in the global variable REAL_DEVICE, declared previously.
+#
+real_device()
+{
+ declare dev="$1"
+ declare realdev
+
+ if [ $IS_BIND_MOUNT -eq 1 ]; then
+ REAL_DEVICE="$dev"
+ return $OCF_SUCCESS
+ fi
+ REAL_DEVICE=""
+
+ [ -z "$dev" ] && return $OCF_ERR_ARGS
+
+ # Oops, we have a link. Sorry, this is going to fork.
+ if [ -h "$dev" ]; then
+ realdev=$(readlink -f $dev)
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_ARGS
+ fi
+ REAL_DEVICE="$realdev"
+ return $OCF_SUCCESS
+ fi
+
+ # If our provided blockdev is a device, we are done
+ if [ -b "$dev" ]; then
+ REAL_DEVICE="$dev"
+ return $OCF_SUCCESS
+ fi
+
+ # It's not a link, it's not a block device. If it also
+ # does not match UUID= or LABEL=, then findfs is not
+ # going to find anything useful, so we should quit now.
+ if [ "${dev/UUID=/}" = "$dev" ] &&
+ [ "${dev/LABEL=/}" = "$dev" ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ # When using LABEL= or UUID=, we can't save a fork.
+ realdev=$(findfs "$dev" 2> /dev/null)
+ if [ -n "$realdev" ] && [ -b "$realdev" ]; then
+ REAL_DEVICE="$realdev"
+ return $OCF_SUCCESS
+ fi
+
+ return $OCF_ERR_GENERIC
+}
+
+
+verify_device()
+{
+ declare realdev
+
+ if [ -z "$OCF_RESKEY_device" ]; then
+ ocf_log err "No device or label specified."
+ return $OCF_ERR_ARGS
+ fi
+
+ real_device "$OCF_RESKEY_device"
+ realdev="$REAL_DEVICE"
+ if [ -n "$realdev" ]; then
+ if [ "$realdev" != "$OCF_RESKEY_device" ]; then
+ ocf_log info "Specified $OCF_RESKEY_device maps to $realdev"
+ fi
+ return $OCF_SUCCESS
+ fi
+
+ ocf_log err "Device or label \"$OCF_RESKEY_device\" not valid"
+
+ return $OCF_ERR_ARGS
+}
+
+list_mounts()
+{
+ if [ $IS_BIND_MOUNT -eq 1 ]; then
+ cat /etc/mtab
+ else
+ cat /proc/mounts
+ fi
+}
+
+##
+# Tries to use findmnt util to return list
+# of mountpoints for a device
+#
+# Global variables are used to reduce forking when capturing stdout.
+#
+# Return values
+# 0 - device mount points found, mountpoint list returned to FINDMNT_OUTPUT global variable
+# 1 - device mount not found
+# 2 - findmnt tool isn't found or can not be used
+#
+##
+try_findmnt()
+{
+ FINDMNT_OUTPUT=""
+
+ case $OCF_RESKEY_use_findmnt in
+ 0|false|no|off)
+ return 2 ;;
+ *)
+ : ;;
+ esac
+
+ which findmnt > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ FINDMNT_OUTPUT="$(findmnt -o TARGET --noheadings $1)"
+ if [ $? -ne 0 ]; then
+ # workaround mount helpers inconsistency that still
+ # add / on the device entry in /proc/mounts
+ FINDMNT_OUTPUT="$(findmnt -o TARGET --noheadings $1/)"
+ if [ $? -ne 0 ]; then
+ return 1
+ else
+ return 0
+ fi
+ else
+ return 0
+ fi
+ fi
+
+ return 2
+}
+
+##
+# Returns result in global variable to reduce forking
+##
+strip_trailing_slashes()
+{
+ local tmp=$1
+ while [ "${tmp#${tmp%?}}" = "/" ]
+ do
+ tmp="${tmp%/}"
+ done
+
+ STRIP_SLASHES="$tmp"
+}
+
+#
+# kill_procs_using_mount mount_point [signal]
+#
+# Kill any processes using the specified mountpoint, using the optional
+# specified signal. This is used in place of fuser to avoid it becoming
+# blocked while following symlinks to an unresponsive file system.
+# Defaults to SIGKILL if no signal specified.
+#
+kill_procs_using_mount () {
+ declare mp
+ declare procs
+ declare mmap_procs
+
+ if [ $# -lt 1 -o -z "$1" ]; then
+ ocf_log err "Usage: kill_procs_using_mount mount_point [signal]"
+ return $FAIL
+ fi
+
+ strip_trailing_slashes "$1"
+ mp="$STRIP_SLASHES"
+
+ if [ -z "$mp" ]; then
+ ocf_log err "Usage: kill_procs_using_mount mount_point [signal]"
+ return $FAIL
+ fi
+
+ # anything held open in mount point after the slash
+ procs=$(find /proc/[0-9]*/ -type l -lname "${mp}/*" -or -lname "${mp}" 2>/dev/null | awk -F/ '{print $3}' | uniq)
+
+ # anything with memory mapping to something in the mountpoint
+ mmap_procs=$(grep " ${mp}" /proc/[0-9]*/maps | awk -F/ '{print $3}' | uniq)
+ procs=$(echo -e "${procs}\n${mmap_procs}" | sort | uniq)
+
+ for pid in $procs; do
+ if [ -n "$2" ]; then
+ kill -s $2 $pid
+ else
+ kill -s KILL $pid
+ fi
+ done
+
+ return $SUCCESS
+}
+
+#
+# mount_in_use device mount_point
+#
+# Check to see if either the device or mount point are in use anywhere on
+# the system. It is not required that the device be mounted on the named
+# moint point, just if either are in use.
+#
+mount_in_use () {
+ declare mp tmp_mp
+ declare tmp_type
+ declare dev tmp_dev
+ declare junkb junkc junkd
+ declare res=$FAIL
+ declare findmnt_res=2
+
+ if [ $# -ne 2 ]; then
+ ocf_log err "Usage: mount_in_use device mount_point".
+ return $FAIL
+ fi
+
+ dev="$1"
+ mp="$2"
+
+ # First try and find out if the device has a mount point by
+ # attempting to use the findmnt tool. It is much faster than
+ # iterating through /proc/mounts
+ try_findmnt $dev
+ findmnt_res=$?
+ if [ $findmnt_res -eq 0 ]; then
+ case $OCF_RESKEY_fstype in
+ cifs|nfs|nfs4)
+ # -r means to include '/' character and not treat it as escape character
+ while read -r tmp_mp
+ do
+ if [ "$tmp_mp" = "$mp" ]; then
+ return $YES
+ fi
+ done < <(echo "$FINDMNT_OUTPUT")
+ ;;
+ *)
+ return $YES
+ ;;
+ esac
+ fi
+
+ while read -r tmp_dev tmp_mp tmp_type junkb junkc junkd; do
+
+ if [ "$tmp_type" = "autofs" ]; then
+ continue
+ fi
+
+ # Does the device match? We might have already tried findmnt
+ # which is why this could get skipped
+ if [ $findmnt_res -eq 2 ]; then
+ if [ "${tmp_dev:0:1}" != "-" ]; then
+ # XXX fork/clone warning XXX
+ tmp_dev="$(printf "$tmp_dev")"
+ fi
+
+ strip_trailing_slashes "$tmp_dev"
+ tmp_dev="$STRIP_SLASHES"
+ if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+ case $OCF_RESKEY_fstype in
+ cifs|nfs|nfs4)
+ ;;
+ *)
+ return $YES
+ ;;
+ esac
+ fi
+ fi
+
+ # Mountpoint from /proc/mounts containing spaces will
+ # have spaces represented in octal. printf takes care
+ # of this for us.
+ tmp_mp="$(printf "$tmp_mp")"
+
+ if [ -n "$tmp_mp" -a "$tmp_mp" = "$mp" ]; then
+ return $YES
+ fi
+ done < <(list_mounts)
+
+ return $NO
+}
+
+##
+# Returns whether or not the device is mounted.
+# If the mountpoint does not match the one provided, the
+# mount point found is printed to stdout.
+##
+real_mountpoint()
+{
+ declare dev=$1
+ declare mp=$2
+ declare ret=$NO
+ declare tmp_mp
+ declare tmp_dev
+ declare tmp_type
+ declare found=1
+ declare poss_mp=""
+
+ try_findmnt $dev
+ case $? in
+ 0) #findmnt found mount points, loop through them to find a match
+
+ # -r means to include '/' character and not treat it as escape character
+ while read -r tmp_mp
+ do
+ ret=$YES
+ if [ "$tmp_mp" != "$mp" ]; then
+ poss_mp=$tmp_mp
+ else
+ found=0
+ break
+ fi
+ done < <(echo "$FINDMNT_OUTPUT")
+ ;;
+ 1)
+ # findmnt found no mount points for the device
+ return $NO
+ ;;
+ 2) # findmnt tool could not be used.
+ # Using slow method reading /proc/mounts dir.
+ while read -r tmp_dev tmp_mp tmp_type junk_b junk_c junk_d
+ do
+ if [ "$tmp_type" = "autofs" ]; then
+ continue
+ fi
+
+ if [ "${tmp_dev:0:1}" != "-" ]; then
+ # XXX fork/clone warning XXX
+ tmp_dev="$(printf "$tmp_dev")"
+ fi
+
+ # CIFS mounts can sometimes have trailing slashes
+ # in their first field in /proc/mounts, so strip them.
+ strip_trailing_slashes "$tmp_dev"
+ tmp_dev="$STRIP_SLASHES"
+ real_device "$tmp_dev"
+ tmp_dev="$REAL_DEVICE"
+
+ # XXX fork/clone warning XXX
+ # Mountpoint from /proc/mounts containing spaces will
+ # have spaces represented in octal. printf takes care
+ # of this for us.
+ tmp_mp="$(printf "$tmp_mp")"
+
+ if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then
+ ret=$YES
+ #
+ # Check to see if its mounted in the right
+ # place
+ #
+ if [ -n "$tmp_mp" ]; then
+ if [ "$tmp_mp" != "$mp" ]; then
+ poss_mp=$tmp_mp
+ else
+ found=0
+ break
+ fi
+ fi
+ fi
+ done < <(list_mounts)
+ esac
+
+ if [ $found -ne 0 ]; then
+ echo "$poss_mp"
+ fi
+ return $ret
+}
+
+#
+# is_mounted device mount_point
+#
+# Check to see if the device is mounted. Print a warning if its not
+# mounted on the directory we expect it to be mounted on.
+#
+is_mounted () {
+
+ declare mp
+ declare dev
+ declare ret=$FAIL
+ declare poss_mp
+
+ if [ $# -ne 2 ]; then
+ ocf_log err "Usage: is_mounted device mount_point"
+ return $FAIL
+ fi
+
+ real_device "$1"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "$OCF_RESOURCE_INSTANCE: is_mounted: Could not match $1 with a real device"
+ return $OCF_ERR_ARGS
+ fi
+
+ if [ -h "$2" ]; then
+ mp="$(readlink -f $2)"
+ else
+ mp="$2"
+ fi
+
+ # This bash glyph simply removes a trailing slash
+ # if one exists. /a/b/ -> /a/b; /a/b -> /a/b.
+ mp="${mp%/}"
+
+ poss_mp=$(real_mountpoint "$dev" "$mp")
+ ret=$?
+
+ if [ $ret -eq $YES ] && [ -n "$poss_mp" ]; then
+ # if we made it here, then the device is mounted, but not where
+ # we expected it to be
+ case $OCF_RESKEY_fstype in
+ cifs|nfs|nfs4)
+ ret=$NO
+ ;;
+ *)
+ ocf_log warn "Device $dev is mounted on $poss_mp instead of $mp"
+ ;;
+ esac
+ fi
+
+
+ return $ret
+}
+
+
+#
+# is_alive mount_point
+#
+# Check to see if mount_point is alive (testing read/write)
+#
+is_alive()
+{
+ declare errcode
+ declare mount_point="$1"
+ declare file
+ declare rw
+
+ if [ $# -ne 1 ]; then
+ ocf_log err "Usage: is_alive mount_point"
+ return $FAIL
+ fi
+
+ [ -z "$OCF_CHECK_LEVEL" ] && export OCF_CHECK_LEVEL=0
+
+ test -d "$mount_point"
+ if [ $? -ne 0 ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: $mount_point is not a directory"
+ return $FAIL
+ fi
+
+ [ $OCF_CHECK_LEVEL -lt 10 ] && return $YES
+
+ # depth 10 test (read test)
+ ls "$mount_point" > /dev/null 2> /dev/null
+ errcode=$?
+ if [ $errcode -ne 0 ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: failed read test on [$mount_point]. Return code: $errcode"
+ return $NO
+ fi
+
+ [ $OCF_CHECK_LEVEL -lt 20 ] && return $YES
+
+ # depth 20 check (write test)
+ rw=$YES
+ for o in `echo $OCF_RESKEY_options | sed -e s/,/\ /g`; do
+ if [ "$o" = "ro" ]; then
+ rw=$NO
+ fi
+ done
+ if [ $rw -eq $YES ]; then
+ file=$(mktemp "$mount_point/.check_writable.$(hostname).XXXXXX")
+ if [ ! -e "$file" ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: is_alive: failed write test on [$mount_point]. Return code: $errcode"
+ return $NO
+ fi
+ rm -f $file > /dev/null 2> /dev/null
+ fi
+
+ return $YES
+}
+
+
+#
+# Decide which quota options are enabled and return a string
+# which we can pass to quotaon
+#
+quota_opts()
+{
+ declare quotaopts=""
+ declare opts="$1"
+ declare mopt
+
+ for mopt in `echo $opts | sed -e s/,/\ /g`; do
+ case $mopt in
+ quota)
+ quotaopts="gu"
+ break
+ ;;
+ usrquota)
+ quotaopts="u$quotaopts"
+ continue
+ ;;
+ grpquota)
+ quotaopts="g$quotaopts"
+ continue
+ ;;
+ noquota)
+ quotaopts=""
+ return 0
+ ;;
+ esac
+ done
+
+ echo $quotaopts
+ return 0
+}
+
+
+
+#
+# Enable quotas on the mount point if the user requested them
+#
+enable_fs_quotas()
+{
+ declare -i need_check=0
+ declare -i rv
+ declare quotaopts=""
+ declare mopt
+ declare opts="$1"
+ declare mp="$2"
+
+ if ! type quotaon &> /dev/null; then
+ ocf_log err "quotaon not found in $PATH"
+ return $OCF_ERR_GENERIC
+ fi
+
+ quotaopts=$(quota_opts $opts)
+ [ -z "$quotaopts" ] && return 0
+
+ ocf_log debug "quotaopts = $quotaopts"
+
+ # Ok, create quota files if they don't exist
+ for f in quota.user aquota.user quota.group aquota.group; do
+ if ! [ -f "$mp/$f" ]; then
+ ocf_log info "$mp/$f was missing - creating"
+ touch "$mp/$f"
+ chmod 600 "$mp/$f"
+ need_check=1
+ fi
+ done
+
+ if [ $need_check -eq 1 ]; then
+ ocf_log info "Checking quota info in $mp"
+ quotacheck -$quotaopts "$mp"
+ fi
+
+ ocf_log info "Enabling Quotas on $mp"
+ ocf_log debug "quotaon -$quotaopts \"$mp\""
+ quotaon -$quotaopts "$mp"
+ rv=$?
+ if [ $rv -ne 0 ]; then
+ # Just a warning
+ ocf_log warn "Unable to turn on quotas for $mp; return = $rv"
+ fi
+
+ return $rv
+}
+
+
+# Agent-specific actions to take before mounting
+# (if required). Typically things like fsck.
+do_pre_mount() {
+ return 0
+}
+
+# Default mount handler - for block devices
+#
+do_mount() {
+ declare dev="$1"
+ declare mp="$2"
+ declare mount_options=""
+ declare fstype_option=""
+ declare fstype
+
+ #
+ # Get the filesystem type, if specified.
+ #
+ fstype_option=""
+ fstype=${OCF_RESKEY_fstype}
+ case "$fstype" in
+ ""|"[ ]*")
+ fstype=""
+ ;;
+ *) # found it
+ fstype_option="-t $fstype"
+ ;;
+ esac
+
+ #
+ # Get the mount options, if they exist.
+ #
+ mount_options=""
+ opts=${OCF_RESKEY_options}
+ case "$opts" in
+ ""|"[ ]*")
+ opts=""
+ ;;
+ *) # found it
+ mount_options="-o $opts"
+ ;;
+ esac
+
+ #
+ # Mount the device
+ #
+ ocf_log info "mounting $dev on $mp"
+ ocf_log err "mount $fstype_option $mount_options $dev $mp"
+ mount $fstype_option $mount_options "$dev" "$mp"
+ ret_val=$?
+ if [ $ret_val -ne 0 ]; then
+ ocf_log err "\
+'mount $fstype_option $mount_options $dev $mp' failed, error=$ret_val"
+ return 1
+ fi
+
+ return 0
+}
+
+
+# Agent-specific actions to take after mounting
+# (if required).
+do_post_mount() {
+ return 0
+}
+
+
+# Agent-specific actions to take before unmounting
+# (if required)
+do_pre_unmount() {
+ return 0
+}
+
+
+# Agent-specific actions to take after umount succeeds
+# (if required)
+do_post_unmount() {
+ return 0
+}
+
+
+# Agent-specific force unmount logic, if required
+# return = 0 if successful, or nonzero if unsuccessful
+# (unsuccessful = try harder)
+do_force_unmount() {
+ return 1
+}
+
+
+#
+# start_filesystem
+#
+start_filesystem() {
+ declare -i ret_val=$OCF_SUCCESS
+ declare mp="${OCF_RESKEY_mountpoint}"
+ declare dev="" # device
+ declare fstype=""
+ declare opts=""
+ declare mount_options=""
+
+ #
+ # Check if fstype is supported
+ #
+ verify_fstype
+ case $? in
+ $OCF_ERR_ARGS)
+ ocf_log err "File system type $OCF_RESKEY_fstype not supported"
+ return $OCF_ERR_ARGS
+ ;;
+ *)
+ ;;
+ esac
+
+ #
+ # Check if mount point was specified. If not, no need to continue.
+ #
+ case "$mp" in
+ ""|"[ ]*") # nothing to mount
+ return $OCF_SUCCESS
+ ;;
+ /*) # found it
+ ;;
+ *) # invalid format
+ ocf_log err \
+"start_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+ return $OCF_ERR_ARGS
+ ;;
+ esac
+
+ #
+ # Get the device
+ #
+ real_device "$OCF_RESKEY_device"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "\
+start_filesystem: Could not match $OCF_RESKEY_device with a real device"
+ return $OCF_ERR_ARGS
+ fi
+
+ #
+ # Ensure we've got a valid directory
+ #
+ if [ -e "$mp" ]; then
+ if ! [ -d "$mp" ]; then
+ ocf_log err"\
+start_filesystem: Mount point $mp exists but is not a directory"
+ return $OCF_ERR_ARGS
+ fi
+ else
+ ocf_log err "\
+start_filesystem: Creating mount point $mp for device $dev"
+ mkdir -p "$mp"
+ ret_val=$?
+ if [ $ret_val -ne 0 ]; then
+ ocf_log err "\
+start_filesystem: Unable to create $mp. Error code: $ret_val"
+ return $OCF_ERR_GENERIC
+ fi
+ fi
+
+ #
+ # See if the device is already mounted.
+ #
+ is_mounted "$dev" "$mp"
+ case $? in
+ $YES) # already mounted
+ ocf_log debug "$dev already mounted"
+ return $OCF_SUCCESS
+ ;;
+ $NO) # not mounted, continue
+ ;;
+ *)
+ return $FAIL
+ ;;
+ esac
+
+
+ #
+ # Make sure that neither the device nor the mount point are mounted
+ # (i.e. they may be mounted in a different location). The'mount_in_use'
+ # function checks to see if either the device or mount point are in
+ # use somewhere else on the system.
+ #
+ mount_in_use "$dev" "$mp"
+ case $? in
+ $YES) # uh oh, someone is using the device or mount point
+ ocf_log err "\
+Cannot mount $dev on $mp, the device or mount point is already in use!"
+ return $FAIL
+ ;;
+ $NO) # good, no one else is using it
+ ;;
+ $FAIL)
+ return $FAIL
+ ;;
+ *)
+ ocf_log err "Unknown return from mount_in_use"
+ return $FAIL
+ ;;
+ esac
+
+ do_pre_mount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ do_mount "$dev" "$mp"
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ do_post_mount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ enable_fs_quotas "$opts" "$mp"
+
+ return $OCF_SUCCESS
+}
+
+
+#
+# stop_filesystem - unmount a file system; calls out to
+#
+stop_filesystem() {
+ declare -i ret_val=0
+ declare -i try
+ declare -i sleep_time=5 # time between each umount failure
+ declare umount_failed=""
+ declare force_umount=""
+ declare self_fence=""
+ declare quotaopts=""
+
+ #
+ # Get the mount point, if it exists. If not, no need to continue.
+ #
+ mp=${OCF_RESKEY_mountpoint}
+ case "$mp" in
+ ""|"[ ]*") # nothing to mount
+ return $OCF_SUCCESS
+ ;;
+ /*) # found it
+ ;;
+ *) # invalid format
+ ocf_log err \
+"stop_filesystem: Invalid mount point format (must begin with a '/'): \'$mp\'"
+ return $FAIL
+ ;;
+ esac
+
+ #
+ # Get the device
+ #
+ real_device "$OCF_RESKEY_device"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "\
+stop: Could not match $OCF_RESKEY_device with a real device"
+ return $OCF_ERR_INSTALLED
+ fi
+
+ #
+ # Get the force unmount setting if there is a mount point.
+ #
+ case ${OCF_RESKEY_force_unmount} in
+ $YES_STR) force_umount=$YES ;;
+ on) force_umount=$YES ;;
+ true) force_umount=$YES ;;
+ 1) force_umount=$YES ;;
+ *) force_umount="" ;;
+ esac
+
+ #
+ # self_fence _MUST_ be initialized before calling do_pre_unmount
+ # The netfs agent depends on the self_fence variable.
+ #
+ case ${OCF_RESKEY_self_fence} in
+ $YES_STR) self_fence=$YES ;;
+ on) self_fence=$YES ;;
+ true) self_fence=$YES ;;
+ 1) self_fence=$YES ;;
+ *) self_fence="" ;;
+ esac
+
+ do_pre_unmount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ #
+ # Preparations: sync, turn off quotas
+ #
+ sync
+
+ quotaopts=$(quota_opts $OCF_RESKEY_options)
+ if [ -n "$quotaopts" ]; then
+ ocf_log debug "Turning off quotas for $mp"
+ quotaoff -$quotaopts "$mp" &> /dev/null
+ fi
+
+ #
+ # Unmount the device.
+ #
+ for try in 1 2 3; do
+ if [ $try -ne 1 ]; then
+ sleep $sleep_time
+ fi
+
+ is_mounted "$dev" "$mp"
+ case $? in
+ $NO)
+ ocf_log info "$dev is not mounted"
+ umount_failed=
+ break
+ ;;
+ $YES) # fallthrough
+ ;;
+ *)
+ return $FAIL
+ ;;
+ esac
+
+ case ${OCF_RESKEY_no_unmount} in
+ yes|YES|true|TRUE|YES|on|ON|1)
+ ocf_log debug "Skipping umount on stop because of 'no_unmount' option"
+ return $OCF_SUCCESS
+ ;;
+ *) : ;;
+ esac
+
+ ocf_log info "unmounting $mp"
+ umount "$mp"
+ ret_val=$?
+ # some versions of umount will exit with status 16 iff
+ # the umount(2) succeeded but /etc/mtab could not be written.
+ if [ $ret_val -eq 0 -o $ret_val -eq 16 ]; then
+ umount_failed=
+ break
+ fi
+
+ ocf_log debug "umount failed: $ret_val"
+ umount_failed=yes
+
+ if [ -z "$force_umount" ]; then
+ continue
+ fi
+
+ # Force unmount: try #1: send SIGTERM
+ if [ $try -eq 1 ]; then
+ # Try fs-specific force unmount, if provided
+ do_force_unmount
+ if [ $? -eq 0 ]; then
+ # if this succeeds, we should be done
+ continue
+ fi
+
+ ocf_log warning "Sending SIGTERM to processes on $mp"
+ kill_procs_using_mount "$mp" "TERM"
+ continue
+ else
+ ocf_log warning "Sending SIGKILL to processes on $mp"
+ kill_procs_using_mount "$mp"
+
+ if [ $? -eq 0 ]; then
+ # someone is still accessing the mount, We've already sent
+ # SIGTERM, now we've sent SIGKILL and are trying umount again.
+ continue
+ fi
+ # mount has failed, and no one is accessing it. There's
+ # nothing left for us to try.
+ break
+ fi
+ done # for
+
+ do_post_unmount
+ case $? in
+ 0)
+ ;;
+ 1)
+ return $OCF_ERR_GENERIC
+ ;;
+ 2)
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ if [ -n "$umount_failed" ]; then
+ ocf_log err "'umount $mp' failed, error=$ret_val"
+
+ if [ "$self_fence" ]; then
+ ocf_log alert "umount failed - REBOOTING"
+ sync
+ reboot -fn
+ fi
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+
+do_start() {
+ declare tries=0
+ declare rv
+
+ while [ $tries -lt 3 ]; do
+ start_filesystem
+ rv=$?
+ if [ $rv -eq 0 ]; then
+ return 0
+ fi
+
+ ((tries++))
+ sleep 3
+ done
+ return $rv
+}
+
+
+do_stop() {
+ stop_filesystem
+ return $?
+}
+
+
+do_monitor() {
+ ocf_log debug "Checking fs \"$OCF_RESKEY_name\", Level $OCF_CHECK_LEVEL"
+
+ #
+ # Get the device
+ #
+ real_device "$OCF_RESKEY_device"
+ dev="$REAL_DEVICE"
+ if [ -z "$dev" ]; then
+ ocf_log err "\
+start_filesystem: Could not match $OCF_RESKEY_device with a real device"
+ return $OCF_NOT_RUNNING
+ fi
+
+ is_mounted "$dev" "${OCF_RESKEY_mountpoint}"
+
+ if [ $? -ne $YES ]; then
+ ocf_log err "${OCF_RESOURCE_INSTANCE}: ${OCF_RESKEY_device} is not mounted on ${OCF_RESKEY_mountpoint}"
+ return $OCF_NOT_RUNNING
+ fi
+
+ if [ "$OCF_RESKEY_quick_status" = "1" ]; then
+ return 0
+ fi
+
+ is_alive "${OCF_RESKEY_mountpoint}"
+ [ $? -eq $YES ] && return 0
+
+ ocf_log err "fs:${OCF_RESKEY_name}: Mount point is not accessible!"
+ return $OCF_ERR_GENERIC
+}
+
+
+do_restart() {
+ stop_filesystem
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ start_filesystem
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ return 0
+}
+
+
+# MUST BE OVERRIDDEN
+do_metadata() {
+ return 1
+}
+
+
+do_validate() {
+ return 1
+}
+
+
+main() {
+ case $1 in
+ start)
+ do_start
+ exit $?
+ ;;
+ stop)
+ do_stop
+ exit $?
+ ;;
+ status|monitor)
+ do_monitor
+ exit $?
+ ;;
+ restart)
+ do_restart
+ exit $?
+ ;;
+ meta-data)
+ do_metadata
+ exit $?
+ ;;
+ validate-all)
+ do_validate
+ ;;
+ *)
+ echo "usage: $0 {start|stop|status|monitor|restart|meta-data|validate-all}"
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+ esac
+ exit 0
+}
+
diff --git a/rgmanager/src/resources/utils/httpd-parse-config.pl b/rgmanager/src/resources/utils/httpd-parse-config.pl
new file mode 100755
index 0000000..5b643f6
--- /dev/null
+++ b/rgmanager/src/resources/utils/httpd-parse-config.pl
@@ -0,0 +1,83 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+##
+## This script removes <IfDefine foo> sections from the
+## Apache httpd.conf file. This is quite useful because we
+## don't have any direct access to the parsed configuration
+## file of the httpd server.
+##
+## Usage: ./httpd-parse-config.pl -Dfoo1 -Dfoo2 < httpd.conf
+## where fooX are defines as passed to the httpd server
+##
+## Note: All whitespace characters at the beginning and end
+## of lines are removed.
+##
+use strict;
+
+my @defines = ();
+## Default behaviour is to show all lines when we are not
+## in the <IfDefine foo> sections.
+my @show = (1);
+
+sub testIfDefine($) {
+ my $param = $1;
+ my $positiveTest = 1;
+ if ($param =~ /^!(.*)$/) {
+ $param = $1;
+ $positiveTest = 0;
+ }
+
+ foreach my $def (@defines) {
+ if ($def eq $param) {
+ return $positiveTest;
+ }
+ }
+
+ return (1-$positiveTest);
+}
+
+foreach my $arg (@ARGV) {
+ if ($arg =~ /^-D(.*)$/) {
+ push(@defines, $1);
+ }
+}
+
+## Parse config file and remove IfDefine sections
+while (my $line = <STDIN>) {
+ chomp($line);
+ $line =~ s/^\s*(.*?)\s*$/$1/;
+ if ($line =~ /<IfDefine (.*)>/) {
+ if (testIfDefine($1) == 1) {
+ if ($show[$#show] == 1) {
+ push (@show, 1);
+ } else {
+ push (@show, 0);
+ }
+ } else {
+ push (@show, 0);
+ }
+ } elsif ($line =~ /<\/IfDefine>/) {
+ pop(@show);
+ } elsif ($show[$#show] == 1) {
+ print $line, "\n";
+ }
+}
+
diff --git a/rgmanager/src/resources/utils/member_util.sh.in b/rgmanager/src/resources/utils/member_util.sh.in
new file mode 100644
index 0000000..0dab7b7
--- /dev/null
+++ b/rgmanager/src/resources/utils/member_util.sh.in
@@ -0,0 +1,116 @@
+#!@BASH_SHELL@
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+#
+# Use corosync-quorumtool to figure out if the specified node is a member
+# of the cluster. Returns 1 if not a member, and
+# 0 if the node is happily running.
+#
+# Tested on RHEL6 and F17 Note that the old version of this function utilized
+# clustat, which had introspection in to the configuration.
+# If a node was not found, the old version would return '2', but the only
+# consumer of this function never cared about that value.
+#
+is_node_member_clustat()
+{
+ local node="$1"
+ local output_list
+
+ # Still having a tag while (a) online but (b) not running pacemaker
+ # (e.g. crm_node) or rgmanager not considered adequate for things like
+ # the LVM agent - so we use corosync-quorumtool instead. The function
+ # name really should be changed.
+ #
+ # corosync 1.4.1 output looks like:
+ #
+ # # corosync-quorumtool -l
+ # Nodeid Name
+ # 1 rhel6-1
+ # 2 rhel6-2
+ #
+ # corosync 2.0.1 output looks like:
+ # # corosync-quorumtool -l
+ #
+ # Membership information
+ # ----------------------
+ # Nodeid Votes Name
+ # 1 1 rhel7-1.priv.redhat.com
+ # 2 1 rhel7-2.priv.redhat.com
+ #
+
+ output_list=$(corosync-quorumtool -l | grep -v "^Nodeid")
+
+ # first try searching for the node in the output as both a FQDN or shortname
+ echo "$output_list" | grep -i -e " $node\$" -e " $node\..*\$" &> /dev/null && return 0
+
+ # if the node was not found in the quorum list, try any known aliases found in /etc/hosts
+ for alias in $(cat /etc/hosts | grep -e "\s$node\s" -e "\s$node\$" | tail -n 1 | sed 's/\t/ /g' | cut -f2- -d " ");
+ do
+ echo "$output_list" | grep -i -e " $alias\$" &> /dev/null && return 0
+ done
+
+ return 1
+}
+
+
+#
+# Print the local node name to stdout
+# Returns 0 if could be found, 1 if not
+# Tested on RHEL6 (cman) and Fedora 17 (corosync/pacemaker)
+#
+local_node_name()
+{
+ local node nid localid
+
+ if which magma_tool &> /dev/null; then
+ # Use magma_tool, if available.
+ line=$(magma_tool localname | grep "^Local")
+
+ if [ -n "$line" ]; then
+ echo ${line/* = /}
+ return 0
+ fi
+ fi
+
+ if which cman_tool &> /dev/null; then
+ # Use cman_tool
+
+ line=$(cman_tool status | grep -i "Node name: $1")
+ [ -n "$line" ] || return 1
+ echo ${line/*name: /}
+ return 0
+ fi
+
+ if ! which crm_node &> /dev/null; then
+ # no crm_node? :(
+ return 2
+ fi
+
+ localid=$(crm_node -i)
+ while read nid node; do
+ if [ "$nid" = "$localid" ]; then
+ echo $node
+ return 0
+ fi
+ done < <(crm_node -l)
+
+ return 1
+}
+
diff --git a/rgmanager/src/resources/utils/messages.sh.in b/rgmanager/src/resources/utils/messages.sh.in
new file mode 100644
index 0000000..1c4f13c
--- /dev/null
+++ b/rgmanager/src/resources/utils/messages.sh.in
@@ -0,0 +1,269 @@
+#!@BASH_SHELL@
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+declare CLOG_INIT=100
+declare CLOG_SUCCEED=200
+declare CLOG_SUCCEED_KILL=201
+
+declare CLOG_FAILED=400
+declare CLOG_FAILED_TIMEOUT=401
+declare CLOG_FAILED_NOT_FOUND=403
+declare CLOG_FAILED_INVALID=404
+declare CLOG_FAILED_NOT_READABLE=405
+declare CLOG_FAILED_KILL=406
+
+##
+## Usage:
+## clog_service_start %operation%
+##
+clog_service_start()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log info "Starting Service $OCF_RESOURCE_INSTANCE"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Starting Service $OCF_RESOURCE_INSTANCE > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Starting Service $OCF_RESOURCE_INSTANCE > Failed"
+ ;;
+ $CLOG_FAILED_TIMEOUT)
+ ocf_log error "Starting Service $OCF_RESOURCE_INSTANCE > Failed - Timeout Error"
+ ;;
+ esac
+ return 0
+}
+
+##
+## Usage:
+## clog_service_stop %operation%
+##
+clog_service_stop()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log info "Stopping Service $OCF_RESOURCE_INSTANCE"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log info "Stopping Service $OCF_RESOURCE_INSTANCE > Succeed"
+ ;;
+ $CLOG_SUCCEED_KILL)
+ ocf_log info "Killing Service $OCF_RESOURCE_INSTANCE > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Stopping Service $OCF_RESOURCE_INSTANCE > Failed"
+ ;;
+ $CLOG_FAILED_NOT_STOPPED)
+ ocf_log error "Stopping Service $OCF_RESOURCE_INSTANCE > Failed - Application Is Still Running"
+ ;;
+ $CLOG_FAILED_KILL)
+ ocf_log error "Killing Service $OCF_RESOURCE_INSTANCE > Failed"
+ ;;
+ esac
+ return 0
+}
+
+##
+## Usage:
+## clog_service_status %operation%
+##
+clog_service_status()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Monitoring Service $OCF_RESOURCE_INSTANCE"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Running"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Not Running"
+ ;;
+ $CLOG_FAILED_NOT_FOUND)
+ ocf_log error "Monitoring Service $OCF_RESOURCE_INSTANCE > Service Is Not Running - PID File Not Found"
+ ;;
+ esac
+ return 0
+}
+
+##
+## Usage:
+## clog_service_verify %operation%
+## clog_service_verify $CLOG_FAILED %reason%
+##
+clog_service_verify()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Verifying Configuration Of $OCF_RESOURCE_INSTANCE"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Succeed"
+ ;;
+ $CLOG_FAILED_NOT_CHILD)
+ ocf_log error "Service $OCF_RESOURCE_INSTANCE Is Not A Child Of A Service"
+ ;;
+ $CLOG_FAILED)
+ if [ "x$2" = "x" ]; then
+ ocf_log error "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Failed"
+ else
+ ocf_log error "Verifying Configuration Of $OCF_RESOURCE_INSTANCE > Failed - $2"
+ fi
+ ;;
+ esac
+ return 0
+}
+
+
+##
+## Usage:
+## clog_check_sha1 %operation% %filename%
+##
+clog_check_sha1()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Checking SHA1 Checksum Of File $1"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Checking SHA1 Checksum Of File > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log debug "Checking SHA1 Checksum Of File > Failed - File Changed"
+ ;;
+ esac
+ return 0;
+}
+
+##
+## Usage:
+## clog_check_file_exist %operation% %filename%
+##
+clog_check_file_exist()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Checking Existence Of File $2"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Checking Existence Of File $2 > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed"
+ ;;
+ $CLOG_FAILED_INVALID)
+ ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - Invalid Argument"
+ ;;
+ $CLOG_FAILED_NOT_FOUND)
+ ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - File Doesn't Exist"
+ ;;
+ $CLOG_FAILED_NOT_READABLE)
+ ocf_log error "Checking Existence Of File $2 [$OCF_RESOURCE_INSTANCE] > Failed - File Is Not Readable"
+ ;;
+ esac
+ return 0;
+}
+
+##
+## Usage:
+## clog_check_pid %operation% %filename%
+##
+clog_check_pid()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Checking Non-Existence Of PID File $2"
+ return 0
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Checking Non-Existence of PID File $2 > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Checking Non-Existence of PID File $2 [$OCF_RESOURCE_INSTANCE] > Failed - PID File Exists For $OCF_RESOURCE_INSTANCE"
+ ;;
+ esac
+ return 0;
+}
+
+##
+## Usage:
+## clog_check_syntax %operation% %filename%
+##
+clog_check_syntax()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Checking Syntax Of The File $2"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Checking Syntax Of The File $2 > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Checking Syntax Of The File $2 [$OCF_RESOURCE_INSTANCE] > Failed"
+ ;;
+ esac
+ return 0;
+}
+
+##
+## Usage:
+## clog_generate_config %operation% %old filename% %new filename%
+##
+clog_generate_config()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Generating New Config File $3 From $2"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Generating New Config File $3 From $2 > Succeed"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Generating New Config File $3 From $2 [$OCF_RESOURCE_INSTANCE] > Failed"
+ ;;
+ esac
+ return 0;
+}
+
+##
+## Usage:
+## clog_looking_for %operation% %resource%
+## clog_looking_for %operation% "IP Addresses"
+## clog_looking_for %operation% "Filesystems"
+##
+clog_looking_for()
+{
+ case $1 in
+ $CLOG_INIT)
+ ocf_log debug "Looking For $2"
+ ;;
+ $CLOG_SUCCEED)
+ ocf_log debug "Looking For $2 > Succeed - $3 $2 Found"
+ ;;
+ $CLOG_FAILED)
+ ocf_log error "Looking For $2 [$OCF_RESOURCE_INSTANCE] > Failed"
+ ;;
+ $CLOG_FAILED_NOT_FOUND)
+ ocf_log error "Looking For $2 [$OCF_RESOURCE_INSTANCE] > Failed - No $2 Found"
+ ;;
+ esac
+ return 0;
+}
diff --git a/rgmanager/src/resources/utils/named-parse-config.pl b/rgmanager/src/resources/utils/named-parse-config.pl
new file mode 100644
index 0000000..a941a60
--- /dev/null
+++ b/rgmanager/src/resources/utils/named-parse-config.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+##
+## Parse named.conf (from STDIN) and add options from cluster.conf
+##
+## ./named-parse-config.pl "directory" "pid-file" "listen-on" "set source <true | false>"
+##
+use strict;
+
+if ($#ARGV < 3) {
+ die ("Not enough arguments");
+}
+
+while (my $line = <STDIN>) {
+ chomp($line);
+ $line =~ s/(.*?)\s*$/$1/;
+ if ($line =~ /^\s*options\s+\{/) {
+ print $line, "\n";
+ print "\tdirectory \"$ARGV[0]\";\n";
+ print "\tpid-file \"$ARGV[1]\";\n";
+ print "\tlisten-on { $ARGV[2] };\n";
+ if ($ARGV[3] =~ "1|true|TRUE|yes|YES|on|ON") {
+ print "\tnotify-source $ARGV[2];\n";
+ print "\ttransfer-source $ARGV[2];\n";
+ print "\tquery-source $ARGV[2];\n";
+ }
+ } else {
+ print $line, "\n";
+ }
+}
+
diff --git a/rgmanager/src/resources/utils/ra-skelet.sh.in b/rgmanager/src/resources/utils/ra-skelet.sh.in
new file mode 100644
index 0000000..ee943b2
--- /dev/null
+++ b/rgmanager/src/resources/utils/ra-skelet.sh.in
@@ -0,0 +1,156 @@
+#!@BASH_SHELL@
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+status_check_pid()
+{
+ declare pid_file="$1"
+
+ if [ -z "$pid_file" ]; then
+ clog_check_file_exist $CLOG_FAILED_INVALID "$pid_file"
+ return $OCF_ERR_GENERIC
+ fi
+
+ if [ ! -e "$pid_file" ]; then
+ clog_check_file_exist $CLOG_FAILED "$pid_file"
+ return $OCF_NOT_RUNNING
+ fi
+
+ read pid < "$pid_file"
+
+ if [ -z "$pid" ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ if [ ! -d /proc/$pid ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ return 0
+}
+
+stop_generic()
+{
+ declare pid_file="$1"
+ declare stop_timeout="$2"
+ declare stop_sig="$3"
+ declare pid;
+ declare count=0;
+
+ if [ -z "$stop_sig" ]; then
+ stop_sig="-TERM"
+ fi
+
+ if [ ! -e "$pid_file" ]; then
+ clog_check_file_exist $CLOG_FAILED_NOT_FOUND "$pid_file"
+ # In stop-after-stop situation there is no PID file but
+ # it will be nice to check for it in stop-after-start
+ # look at bug #449394
+ return 0
+ fi
+
+ if [ -z "$stop_timeout" ]; then
+ stop_timeout=20
+ fi
+
+ read pid < "$pid_file"
+
+ # @todo: PID file empty -> error?
+ if [ -z "$pid" ]; then
+ return 0;
+ fi
+
+ # @todo: PID is not running -> error?
+ if [ ! -d "/proc/$pid" ]; then
+ return 0;
+ fi
+
+ kill $stop_sig "$pid"
+
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ until [ `ps --pid "$pid" &> /dev/null; echo $?` = '1' ] || [ $count -gt $stop_timeout ]
+ do
+ sleep 1
+ let count=$count+1
+ done
+
+ if [ $count -gt $stop_timeout ]; then
+ clog_service_stop $CLOG_FAILED_NOT_STOPPED
+ return $OCF_ERR_GENERIC
+ fi
+
+ return 0;
+}
+
+stop_generic_sigkill() {
+ # Use stop_generic (kill -TERM) and if application did not stop
+ # correctly then use kill -QUIT and check if it was killed
+ declare pid_file="$1"
+ declare stop_timeout="$2"
+ declare kill_timeout="$3"
+ declare stop_sig="$4"
+ declare pid
+
+ if [ -z "$stop_sig" ]; then
+ stop_sig="-TERM"
+ fi
+ ## If stop_timeout is equal to zero then we do not want
+ ## to give -TERM signal at all.
+ if [ $stop_timeout -ne 0 ]; then
+ stop_generic "$pid_file" "$stop_timeout" "$stop_sig"
+ if [ $? -eq 0 ]; then
+ return 0;
+ fi
+ fi
+
+ if [ ! -e "$pid_file" ]; then
+ clog_check_file_exist $CLOG_FAILED_NOT_FOUND "$pid_file"
+ # In stop-after-stop situation there is no PID file but
+ # it will be nice to check for it in stop-after-start
+ # look at bug #449394
+ return 0
+ fi
+ read pid < "$pid_file"
+
+ if [ -z "$pid" ]; then
+ return 0;
+ fi
+
+ if [ ! -d "/proc/$pid" ]; then
+ return 0;
+ fi
+
+ kill -QUIT "$pid"
+ if [ $? -ne 0 ]; then
+ return $OCF_GENERIC_ERROR
+ fi
+
+ sleep "$kill_timeout"
+ ps --pid "$pid" &> /dev/null
+ if [ $? -eq 0 ]; then
+ clog_service_stop $CLOG_FAILED_KILL
+ return $OCF_ERR_GENERIC
+ fi
+
+ clog_service_stop $CLOG_SUCCEED_KILL
+ return 0
+}
diff --git a/rgmanager/src/resources/utils/rhev-check.sh b/rgmanager/src/resources/utils/rhev-check.sh
new file mode 100644
index 0000000..0529c31
--- /dev/null
+++ b/rgmanager/src/resources/utils/rhev-check.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+MYNAME=`basename $0`
+
+do_log()
+{
+ declare severity=$1
+
+ shift
+ echo "<$severity> $*"
+ clulog -s $severity "$*"
+}
+
+if [ -z "$1" ]; then
+ do_log 4 No host specified.
+ exit 1
+fi
+
+do_log 6 "Checking RHEV status on $1"
+
+tries=3
+http_code=
+
+while [ $tries -gt 0 ]; do
+
+ # Record start/end times so we can calculate the difference
+ start_time=$(date +%s)
+ http_code="$(curl -m 10 -sk https://$1/RHEVManagerWeb/HealthStatus.aspx -D - | head -1 | cut -f2 -d' ')"
+
+ if [ "$http_code" = "200" ]; then
+ exit 0
+ fi
+
+ # Reduce sleep time if the attempt took a noticeable amount
+ # of time.
+ end_time=$(date +%s)
+ delta=$(((end_time - start_time)))
+ sleep_time=$(((90 - delta)))
+
+ ((tries-=1))
+
+ # if we're going to retry and we have a nonzero sleep time,
+ # go to sleep.
+ if [ $tries -gt 0 ] && [ $sleep_time -gt 0 ]; then
+ sleep $sleep_time
+ fi
+done
+
+if [ -n "$http_code" ]; then
+ do_log 3 "RHEV Status check on $1 failed; last HTTP code: $http_code"
+else
+ do_log 3 "RHEV Status check on $1 failed"
+fi
+
+exit 1
diff --git a/rgmanager/src/resources/utils/tomcat-parse-config.pl b/rgmanager/src/resources/utils/tomcat-parse-config.pl
new file mode 100644
index 0000000..7c9badf
--- /dev/null
+++ b/rgmanager/src/resources/utils/tomcat-parse-config.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
+# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+#
+# 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.
+#
+
+##
+## This script replace IP addresses on which tomcat server
+## should listen. Tomcat can't listen on every IP because that
+## way we can run only on instance.
+##
+## Usage: ./tomcat-parse-config.pl ip1 ip2 < /etc/tomcat/server.xml
+## where ipXX defines an IP address [eg. 127.0.0.1 134.45.11.1]
+##
+##
+use strict;
+
+while (my $line = <STDIN>) {
+ chomp ($line);
+
+ if ($line =~ /(.*?)<Connector (.*)/) {
+ my $tmp = $2;
+ my $content = "<Connector ";
+ my $start = $1;
+ my $rest = "";
+
+ while (($tmp =~ />/) == 0) {
+ $content .= $tmp . "\n";
+ $tmp = <STDIN>;
+ chomp($tmp);
+ }
+
+ if ($tmp =~ /(.*?)>(.*)/) {
+ $content .= $1 . ">\n";
+ $rest = $2;
+ chomp($rest);
+ }
+
+ print $start;
+ foreach my $arg (@ARGV) {
+ $content =~ s/\s+address=".*?"/ /;
+ $content =~ s/Connector /Connector address="$arg" /;
+ print $content;
+ }
+ print $rest;
+ } else {
+ print $line,"\n";
+ }
+}