diff options
Diffstat (limited to 'rgmanager/src/resources/utils')
-rw-r--r-- | rgmanager/src/resources/utils/Makefile.am | 37 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/config-utils.sh.in | 309 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/fs-lib.sh.in | 1230 | ||||
-rwxr-xr-x | rgmanager/src/resources/utils/httpd-parse-config.pl | 83 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/member_util.sh.in | 116 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/messages.sh.in | 269 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/named-parse-config.pl | 49 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/ra-skelet.sh.in | 156 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/rhev-check.sh | 55 | ||||
-rw-r--r-- | rgmanager/src/resources/utils/tomcat-parse-config.pl | 63 |
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"; + } +} |