diff --git a/SOURCES/bz1058102-man-page-updates.patch b/SOURCES/bz1058102-man-page-updates.patch new file mode 100644 index 0000000..355f644 --- /dev/null +++ b/SOURCES/bz1058102-man-page-updates.patch @@ -0,0 +1,250 @@ +From 3afd24d578006d68746f9ce35321d0ed34df92e2 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 25 Aug 2014 15:01:13 -0500 +Subject: [PATCH 3/4] High: doc: Add pcs to man page example section + +PCS and CRM SHELL now have their own example sections in the +resource-agent man pages. Below is an example of the CRM SHELL +and PCS examples for the IPaddr2 agent. + +EXAMPLE CRM SHELL + The following is an example configuration for a IPaddr2 resource using the crm(8) shell: + + primitive p_IPaddr2 ocf:heartbeat:IPaddr2 \ + params \ + ip=string \ + op monitor depth="0" timeout="20s" interval="10s" + +EXAMPLE PCS + The following is an example configuration for a IPaddr2 resource using pcs(8) + + pcs resource create p_IPaddr2 ocf:heartbeat:IPaddr2 \ + ip=string \ + op monitor depth="0" timeout="20s" interval="10s" +--- + doc/man/ra2refentry.xsl | 141 +++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 123 insertions(+), 18 deletions(-) + +diff --git a/doc/man/ra2refentry.xsl b/doc/man/ra2refentry.xsl +index 41a60aa..ac148ef 100644 +--- a/doc/man/ra2refentry.xsl ++++ b/doc/man/ra2refentry.xsl +@@ -50,7 +50,8 @@ + + + +- ++ ++ + + + +@@ -403,10 +404,10 @@ + + + +- +- ++ ++ + +- Example ++ Example CRM Shell + + The following is an example configuration for a + +@@ -428,7 +429,7 @@ + \ + params \ + +- ++ + + + \ +@@ -440,7 +441,7 @@ + + meta allow-migrate="true" \ + +- ++ + + +@@ -457,15 +458,15 @@ + + + +- +- ++ ++ + + +- ++ + + + = +- ++ + \ + + +@@ -473,7 +474,7 @@ + + + +- ++ + + + " +@@ -486,23 +487,23 @@ + + + +- ++ + +- ++ + + +- ++ + + op + + +- ++ + + \ + + + +- ++ + + + +@@ -517,9 +518,113 @@ + + + +- ++ + +- ++ ++ ++ ++ ++ ++ Example PCS ++ ++ The following is an example configuration for a ++ ++ resource using ++ pcs8 ++ ++ ++ pcs resource create p_ ++ ++ ++ ++ : ++ ++ : ++ ++ ++ ++ \ ++ ++ ++ ++ ++ \ ++ ++ ++ ++ ++ ++ ++ --master ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ = ++ ++ \ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ " ++ ++ " ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ op ++ ++ ++ ++ ++ \ ++ ++ ++ ++ ++ ++ ++ ++ ++ =" ++ ++ " ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +1.8.4.2 + diff --git a/SOURCES/bz1083041-virtual-domain-monitor-lxc-fix.patch b/SOURCES/bz1083041-virtual-domain-monitor-lxc-fix.patch new file mode 100644 index 0000000..c2832ed --- /dev/null +++ b/SOURCES/bz1083041-virtual-domain-monitor-lxc-fix.patch @@ -0,0 +1,54 @@ +From 4e2576c0b339537790e253c11d9dfcf99b7b114d Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Tue, 1 Apr 2014 17:28:39 -0400 +Subject: [PATCH] Low: VirtualDomain: Allow monitoring of lxc domains without + libvirtd + +--- + heartbeat/VirtualDomain | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/heartbeat/VirtualDomain b/heartbeat/VirtualDomain +index b0cdd5f..692a2ef 100755 +--- a/heartbeat/VirtualDomain ++++ b/heartbeat/VirtualDomain +@@ -249,15 +249,17 @@ pid_status() + + case "$emulator" in + qemu-kvm|qemu-system-*) ++ rc=$OCF_NOT_RUNNING + ps awx | grep -E "[q]emu-(kvm|system).*-name $DOMAIN_NAME " > /dev/null 2>&1 + if [ $? -eq 0 ]; then +- # domain exists and is running +- ocf_log debug "Virtual domain $DOMAIN_NAME is currently running." + rc=$OCF_SUCCESS +- else +- # domain pid does not exist on local machine +- ocf_log debug "Virtual domain $DOMAIN_NAME is currently not running." +- rc=$OCF_NOT_RUNNING ++ fi ++ ;; ++ libvirt_lxc) ++ rc=$OCF_NOT_RUNNING ++ ps awx | grep -E "[l]ibvirt_lxc.*-name $DOMAIN_NAME " > /dev/null 2>&1 ++ if [ $? -eq 0 ]; then ++ rc=$OCF_SUCCESS + fi + ;; + # This can be expanded to check for additional emulators +@@ -265,6 +267,12 @@ pid_status() + ;; + esac + ++ if [ $rc -eq $OCF_SUCCESS ]; then ++ ocf_log debug "Virtual domain $DOMAIN_NAME is currently running." ++ elif [ $rc -eq $OCF_NOT_RUNNING ]; then ++ ocf_log debug "Virtual domain $DOMAIN_NAME is currently not running." ++ fi ++ + return $rc + } + +-- +1.8.4.2 + diff --git a/SOURCES/bz1083231-fs-wait-module-load.patch b/SOURCES/bz1083231-fs-wait-module-load.patch new file mode 100644 index 0000000..027760f --- /dev/null +++ b/SOURCES/bz1083231-fs-wait-module-load.patch @@ -0,0 +1,116 @@ +From d0ecd287511e49891245c68cd323e8f232aa033b Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Wed, 6 Aug 2014 14:05:18 -0400 +Subject: [PATCH] High: Filesystem: when loading kernel modules wait for + filesystem to initialize + +When the Filesystem agent is managing a filesystem type that +is not present in /proc/filesystems, the agent attempts to +load the kernel module for that filesystem. + +This patch improves on that logic by +1. verifying that modprobe worked +2. give the module a brief period of time to initialize. + +Item 2 is important because there is a brief period +of time between when modprobe returns loading the gfs2 +module, and when gfs2 will show up in the /proc/filesystems +list. Without retrying the search of the /proc/filesystems +file, a gfs2 filesystem may fail to start correctly because +it will look like the filesystem isn't supported. +--- + heartbeat/Filesystem | 71 +++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 53 insertions(+), 18 deletions(-) + +diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem +index 9209818..9892b39 100755 +--- a/heartbeat/Filesystem ++++ b/heartbeat/Filesystem +@@ -450,6 +450,58 @@ is_fsck_needed() { + esac + } + ++fstype_supported() ++{ ++ local support="$FSTYPE" ++ local rc ++ ++ if [ "X${HOSTOS}" != "XOpenBSD" ];then ++ # skip checking /proc/filesystems for obsd ++ return $OCF_SUCCESS ++ fi ++ ++ if [ -z "$FSTYPE" -o "$FSTYPE" = none ]; then ++ : No FSTYPE specified, rely on the system has the right file-system support already ++ return $OCF_SUCCESS ++ fi ++ ++ # support fuse-filesystems (e.g. GlusterFS) ++ case $FSTYPE in ++ glusterfs) support="fuse";; ++ esac ++ ++ grep -w "$support"'$' /proc/filesystems >/dev/null ++ if [ $? -eq 0 ]; then ++ # found the fs type ++ return $OCF_SUCCESS ++ fi ++ ++ # if here, we should attempt to load the module and then ++ # check the if the filesystem support exists again. ++ $MODPROBE $support >/dev/null ++ if [ $? -ne 0 ]; then ++ ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems and failed to load kernal module" ++ return $OCF_ERR_INSTALLED ++ fi ++ ++ # It is possible for the module to load and not be complete initialized ++ # before we check /proc/filesystems again. Give this a few trys before ++ # giving up entirely. ++ for try in $(seq 5); do ++ grep -w "$support"'$' /proc/filesystems >/dev/null ++ if [ $? -eq 0 ] ; then ++ # yes. found the filesystem after doing the modprobe ++ return $OCF_SUCCESS ++ fi ++ ocf_log debug "Unable to find support for $FSTYPE in /proc/filesystems after modprobe, trying again" ++ sleep 1 ++ done ++ ++ ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems" ++ return $OCF_ERR_INSTALLED ++} ++ ++ + # + # START: Start up the filesystem + # +@@ -472,24 +524,7 @@ Filesystem_start() + return $OCF_SUCCESS + fi + +- if [ "X${HOSTOS}" != "XOpenBSD" ];then +- if [ -z "$FSTYPE" -o "$FSTYPE" = none ]; then +- : No FSTYPE specified, rely on the system has the right file-system support already +- else +- local support="$FSTYPE" +- # support fuse-filesystems (e.g. GlusterFS) +- case $FSTYPE in +- glusterfs) support="fuse";; +- esac +- grep -w "$support"'$' /proc/filesystems >/dev/null || +- $MODPROBE $support >/dev/null +- grep -w "$support"'$' /proc/filesystems >/dev/null +- if [ $? -ne 0 ] ; then +- ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems" +- return $OCF_ERR_INSTALLED +- fi +- fi +- fi ++ fstype_supported || exit $OCF_ERR_INSTALLED + + # Check the filesystem & auto repair. + # NOTE: Some filesystem types don't need this step... Please modify +-- +1.8.4.2 + diff --git a/SOURCES/bz1095944-safe-umount-option.patch b/SOURCES/bz1095944-safe-umount-option.patch new file mode 100644 index 0000000..2e25a91 --- /dev/null +++ b/SOURCES/bz1095944-safe-umount-option.patch @@ -0,0 +1,87 @@ +diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem +index 9209818..6a852df 100755 +--- a/heartbeat/Filesystem ++++ b/heartbeat/Filesystem +@@ -196,6 +196,26 @@ Only set this to "true" if you know what you are doing! + + + ++ ++ ++This option allows specifying how to handle processes that are ++currently accessing the mount directory. ++ ++"true" : Default value, kill processes accessing mount point ++"safe" : Kill processes accessing mount point using methods that ++ avoid functions that could potentially block during process ++ detection ++"false" : Do not kill any processes. ++ ++The 'safe' option uses shell logic to walk the /procs/ directory ++for pids using the mount point while the default option uses the ++fuser cli tool. fuser is known to perform operations that can potentially ++block if unresponsive nfs mounts are in use on the system. ++ ++Kill processes before unmount ++ ++ ++ + + + +@@ -701,6 +721,25 @@ Filesystem_notify() { + done + } + ++get_pids() ++{ ++ local dir=$1 ++ local procs ++ local mmap_procs ++ ++ if ocf_is_true "$FORCE_UNMOUNT"; then ++ if [ "X${HOSTOS}" = "XOpenBSD" ];then ++ fstat | grep $dir | awk '{print $3}' ++ else ++ $FUSER -m $dir 2>/dev/null ++ fi ++ elif [ "$FORCE_UNMOUNT" = "safe" ]; then ++ procs=$(find /proc/[0-9]*/ -type l -lname "${dir}/*" -or -lname "${dir}" 2>/dev/null | awk -F/ '{print $3}') ++ mmap_procs=$(grep " ${dir}" /proc/[0-9]*/maps | awk -F/ '{print $3}') ++ echo -e "${procs}\n${mmap_procs}" | sort | uniq ++ fi ++} ++ + signal_processes() { + local dir=$1 + local sig=$2 +@@ -708,15 +747,9 @@ signal_processes() { + # fuser returns a non-zero return code if none of the + # specified files is accessed or in case of a fatal + # error. +- pids=$( +- if [ "X${HOSTOS}" = "XOpenBSD" ];then +- fstat | grep $dir | awk '{print $3}' +- else +- $FUSER -m $dir 2>/dev/null +- fi +- ) ++ pids=$(get_pids "$dir") + if [ -z "$pids" ]; then +- ocf_log info "No processes on $dir were signalled" ++ ocf_log info "No processes on $dir were signalled. force_unmount is set to '$FORCE_UNMOUNT'" + return + fi + for pid in $pids; do +@@ -1002,6 +1035,11 @@ if [ $# -ne 1 ]; then + fi + + # Check the OCF_RESKEY_ environment variables... ++FORCE_UNMOUNT="yes" ++if [ -n "${OCF_RESKEY_force_unmount}" ]; then ++ FORCE_UNMOUNT=$OCF_RESKEY_force_unmount ++fi ++ + DEVICE=$OCF_RESKEY_device + FSTYPE=$OCF_RESKEY_fstype + if [ ! -z "$OCF_RESKEY_options" ]; then diff --git a/SOURCES/bz1097593-LVM-warn-lvmetad.patch b/SOURCES/bz1097593-LVM-warn-lvmetad.patch new file mode 100644 index 0000000..fe2cd1a --- /dev/null +++ b/SOURCES/bz1097593-LVM-warn-lvmetad.patch @@ -0,0 +1,42 @@ +From 4f6ebfc537b2d3671112a54873081685d47066db Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 18 Jul 2014 12:31:55 -0400 +Subject: [PATCH] Low: LVM: Warn users about the danger of lvmetad + +--- + heartbeat/LVM | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/heartbeat/LVM b/heartbeat/LVM +index 4378cd3..27cdfbd 100755 +--- a/heartbeat/LVM ++++ b/heartbeat/LVM +@@ -545,6 +545,25 @@ LVM_validate_all() { + check_binary $AWK + + ## ++ # lvmetad is a daemon that caches lvm metadata to improve the ++ # performance of LVM commands. This daemon should never be used when ++ # volume groups exist that are being managed by the cluster. The lvmetad ++ # daemon introduces a response lag, where certain LVM commands look like ++ # they have completed (like vg activation) when in fact the command ++ # is still in progress by the lvmetad. This can cause reliability issues ++ # when managing volume groups in the cluster. For Example, if you have a ++ # volume group that is a dependency for another application, it is possible ++ # the cluster will think the volume group is activated and attempt to start ++ # the application before volume group is really accesible... lvmetad is bad. ++ ## ++ lvm dumpconfig global/use_lvmetad | grep 'use_lvmetad.*=.*1' > /dev/null 2>&1 ++ if [ $? -eq 0 ]; then ++ # for now warn users that lvmetad is enabled and that they should disable it. In the ++ # future we may want to consider refusing to start, or killing the lvmetad daemon. ++ ocf_log warn "Disable lvmetad in lvm.conf. lvmetad should never be enabled in a clustered environment. Set use_lvmetad=0 and kill the lvmetad process" ++ fi ++ ++ ## + # Off-the-shelf tests... + ## + VGOUT=`vgck ${VOLUME} 2>&1` +-- +1.8.4.2 + diff --git a/SOURCES/bz1105655-virtualdomain-restore-start-stop-default-timeout.patch b/SOURCES/bz1105655-virtualdomain-restore-start-stop-default-timeout.patch new file mode 100644 index 0000000..5b2cb6e --- /dev/null +++ b/SOURCES/bz1105655-virtualdomain-restore-start-stop-default-timeout.patch @@ -0,0 +1,32 @@ +From 458c003e7f6f0caa2e1c7f4386e458a039500427 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Thu, 19 Jun 2014 14:52:36 -0500 +Subject: [PATCH] High: VirtualDomain: restore advertised start and stop + timeout values to a sane value. + +The meta_timeout default value is 90000 milliseconds. That value +was used in the xml output to represent the default start and stop +timeout which is reflected in seconds... not milliseconds. A +90000 second timeout doesn't make sense as a default. +--- + heartbeat/VirtualDomain | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/heartbeat/VirtualDomain b/heartbeat/VirtualDomain +index c44c090..b0cdd5f 100755 +--- a/heartbeat/VirtualDomain ++++ b/heartbeat/VirtualDomain +@@ -167,8 +167,8 @@ Restore state on start/stop + + + +- +- ++ ++ + + + +-- +1.8.4.2 + diff --git a/SOURCES/bz1116166-Low-galera-be-very-generous-in-the-promotion-timeout.patch b/SOURCES/bz1116166-Low-galera-be-very-generous-in-the-promotion-timeout.patch new file mode 100644 index 0000000..8d8394c --- /dev/null +++ b/SOURCES/bz1116166-Low-galera-be-very-generous-in-the-promotion-timeout.patch @@ -0,0 +1,26 @@ +From 54c26715a8eb5688081ea6e26cabe54d9de762d7 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Wed, 30 Jul 2014 13:03:14 -0500 +Subject: [PATCH 6/6] Low: galera: be very generous in the promotion timeout to + allow SST to complete on large databases + +--- + heartbeat/galera | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index a361d7b..994aad0 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -235,7 +235,7 @@ Cluster check user password + + + +- ++ + + + +-- +1.8.4.2 + diff --git a/SOURCES/bz1116166-Low-galera-do-not-advertise-notify-in-the-usage.patch b/SOURCES/bz1116166-Low-galera-do-not-advertise-notify-in-the-usage.patch new file mode 100644 index 0000000..307e269 --- /dev/null +++ b/SOURCES/bz1116166-Low-galera-do-not-advertise-notify-in-the-usage.patch @@ -0,0 +1,41 @@ +From bc1e7bdcedc1bb1bf473787f373261452e37e337 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Wed, 30 Jul 2014 12:59:46 -0500 +Subject: [PATCH 5/6] Low: galera: do not advertise notify in the usage + +--- + heartbeat/galera | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index 386daaf..a361d7b 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -79,7 +79,7 @@ fi + + usage() { + cat < + + +- + + + +@@ -683,7 +682,6 @@ case "$1" in + monitor) galera_monitor;; + promote) galera_promote;; + demote) galera_demote;; +- notify) galera_notify;; + validate-all) exit $OCF_SUCCESS;; + + *) usage +-- +1.8.4.2 + diff --git a/SOURCES/bz1116166-galera-do-not-ignore-check_password.patch b/SOURCES/bz1116166-galera-do-not-ignore-check_password.patch new file mode 100644 index 0000000..a5d4136 --- /dev/null +++ b/SOURCES/bz1116166-galera-do-not-ignore-check_password.patch @@ -0,0 +1,25 @@ +From e5c5c087ecf152bd69f5795024bfc655394c3c18 Mon Sep 17 00:00:00 2001 +From: Andreas Kurz +Date: Thu, 18 Sep 2014 23:06:36 +0200 +Subject: [PATCH 1/6] High: galera: do not ignore specified check_password + +--- + heartbeat/galera | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index 54654f8..386daaf 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -672,7 +672,7 @@ fi + + MYSQL_OPTIONS_CHECK="-nNE --user=${OCF_RESKEY_check_user}" + if [ -n "${OCF_RESKEY_check_passwd}" ]; then +- MYSQL_OPTIONS_CHECK="$MYSQL_OPTIONS_CHECK --password=${MYSQL_PASSWORD}" ++ MYSQL_OPTIONS_CHECK="$MYSQL_OPTIONS_CHECK --password=${OCF_RESKEY_check_passwd}" + fi + + # What kind of method was invoked? +-- +1.8.4.2 + diff --git a/SOURCES/bz1116166-galera-updates.patch b/SOURCES/bz1116166-galera-updates.patch deleted file mode 100644 index 809dc18..0000000 --- a/SOURCES/bz1116166-galera-updates.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/heartbeat/galera b/heartbeat/galera -index 6d8cf12..a3e5c90 100644 ---- a/heartbeat/galera -+++ b/heartbeat/galera -@@ -79,7 +79,7 @@ fi - - usage() { - cat < - - -- -+ - -- - - - -@@ -532,7 +531,7 @@ galera_start() - - is_readonly - if [ $? -ne 0 ]; then -- ocf_log err "Failure. Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." -+ ocf_log err "Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." - return $OCF_ERR_GENERIC - fi - -@@ -672,7 +671,7 @@ fi - - MYSQL_OPTIONS_CHECK="-nNE --user=${OCF_RESKEY_check_user}" - if [ -n "${OCF_RESKEY_check_passwd}" ]; then -- MYSQL_OPTIONS_CHECK="$MYSQL_OPTIONS_CHECK --password=${MYSQL_PASSWORD}" -+ MYSQL_OPTIONS_CHECK="$MYSQL_OPTIONS_CHECK --password=${OCF_RESKEY_check_passwd}" - fi - - # What kind of method was invoked? -@@ -683,7 +682,6 @@ case "$1" in - monitor) galera_monitor;; - promote) galera_promote;; - demote) galera_demote;; -- notify) galera_notify;; - validate-all) exit $OCF_SUCCESS;; - - *) usage diff --git a/SOURCES/bz1118029-iscsi-agents.patch b/SOURCES/bz1118029-iscsi-agents.patch new file mode 100644 index 0000000..056ae43 --- /dev/null +++ b/SOURCES/bz1118029-iscsi-agents.patch @@ -0,0 +1,1536 @@ +From d4a36f47b36f47a847795660653b7fbc5baab706 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 25 Aug 2014 14:55:50 -0500 +Subject: [PATCH 1/4] iscsi agent updates + +--- + heartbeat/iSCSILogicalUnit | 573 ++++++++++++++++++++++----------------- + heartbeat/iSCSITarget | 661 +++++++++++++++++++++++++-------------------- + 2 files changed, 690 insertions(+), 544 deletions(-) + +diff --git a/heartbeat/iSCSILogicalUnit b/heartbeat/iSCSILogicalUnit +index 0ab4722..c4cee0d 100755 +--- a/heartbeat/iSCSILogicalUnit ++++ b/heartbeat/iSCSILogicalUnit +@@ -3,10 +3,10 @@ + # + # iSCSILogicalUnit OCF RA. Exports and manages iSCSI Logical Units. + # +-# (c) 2013 LINBIT, Lars Ellenberg ++# (c) 2013 LINBIT, Lars Ellenberg + # (c) 2009-2010 Florian Haas, Dejan Muhamedagic, +-# and Linux-HA contributors +-# ++# and Linux-HA contributors ++# + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of version 2 of the GNU General Public License as +@@ -36,11 +36,13 @@ + # Defaults + # Set a default implementation based on software installed + if have_binary ietadm; then +- OCF_RESKEY_implementation_default="iet" ++ OCF_RESKEY_implementation_default="iet" + elif have_binary tgtadm; then +- OCF_RESKEY_implementation_default="tgt" ++ OCF_RESKEY_implementation_default="tgt" + elif have_binary lio_node; then +- OCF_RESKEY_implementation_default="lio" ++ OCF_RESKEY_implementation_default="lio" ++elif have_binary targetcli; then ++ OCF_RESKEY_implementation_default="lio-t" + fi + : ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}} + +@@ -91,9 +93,9 @@ an SCSI Target, exported via a daemon that speaks the iSCSI protocol. + + + The iSCSI target daemon implementation. Must be one of "iet", "tgt", +-or "lio". If unspecified, an implementation is selected based on the ++"lio", or "lio-t". If unspecified, an implementation is selected based on the + availability of management utilities, with "iet" being tried first, +-then "tgt", then "lio". ++then "tgt", then "lio", then "lio-t". + + iSCSI target daemon implementation + +@@ -228,12 +230,12 @@ in /sys/kernel/config/target/core/. + + + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + END +@@ -250,108 +252,150 @@ END + } + + iSCSILogicalUnit_start() { +- iSCSILogicalUnit_monitor +- if [ $? = $OCF_SUCCESS ]; then +- return $OCF_SUCCESS +- fi ++ iSCSILogicalUnit_monitor ++ if [ $? = $OCF_SUCCESS ]; then ++ return $OCF_SUCCESS ++ fi + +- local params ++ local params + +- case $OCF_RESKEY_implementation in ++ case $OCF_RESKEY_implementation in + iet) +- params="Path=${OCF_RESKEY_path}" +- # use blockio if path points to a block device, fileio +- # otherwise. +- if [ -b "${OCF_RESKEY_path}" ]; then +- params="${params} Type=blockio" +- else +- params="${params} Type=fileio" +- fi +- # in IET, we have to set LU parameters on creation +- if [ -n "${OCF_RESKEY_scsi_id}" ]; then +- params="${params} ScsiId=${OCF_RESKEY_scsi_id}" +- fi +- if [ -n "${OCF_RESKEY_scsi_sn}" ]; then +- params="${params} ScsiSN=${OCF_RESKEY_scsi_sn}" +- fi +- params="${params} ${OCF_RESKEY_additional_parameters}" +- ocf_run ietadm --op new \ +- --tid=${TID} \ +- --lun=${OCF_RESKEY_lun} \ +- --params ${params// /,} || exit $OCF_ERR_GENERIC +- ;; ++ params="Path=${OCF_RESKEY_path}" ++ # use blockio if path points to a block device, fileio ++ # otherwise. ++ if [ -b "${OCF_RESKEY_path}" ]; then ++ params="${params} Type=blockio" ++ else ++ params="${params} Type=fileio" ++ fi ++ # in IET, we have to set LU parameters on creation ++ if [ -n "${OCF_RESKEY_scsi_id}" ]; then ++ params="${params} ScsiId=${OCF_RESKEY_scsi_id}" ++ fi ++ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then ++ params="${params} ScsiSN=${OCF_RESKEY_scsi_sn}" ++ fi ++ params="${params} ${OCF_RESKEY_additional_parameters}" ++ ocf_run ietadm --op new \ ++ --tid=${TID} \ ++ --lun=${OCF_RESKEY_lun} \ ++ --params ${params// /,} || exit $OCF_ERR_GENERIC ++ ;; + tgt) +- # tgt requires that we create the LU first, then set LU +- # parameters +- params="" +- local var +- local envar +- for var in scsi_id scsi_sn vendor_id product_id; do +- envar="OCF_RESKEY_${var}" +- if [ -n "${!envar}" ]; then +- params="${params} ${var}=${!envar}" ++ # tgt requires that we create the LU first, then set LU ++ # parameters ++ params="" ++ local var ++ local envar ++ for var in scsi_id scsi_sn vendor_id product_id; do ++ envar="OCF_RESKEY_${var}" ++ if [ -n "${!envar}" ]; then ++ params="${params} ${var}=${!envar}" ++ fi ++ done ++ params="${params} ${OCF_RESKEY_additional_parameters}" ++ ++ # cleanup: tgt (as of tgtadm version 1.0.24) does not like an explicit "bsoflags=direct" ++ # when used with "bstype=aio" (which always uses O_DIRECT) ++ [[ $OCF_RESKEY_tgt_bstype/$OCF_RESKEY_tgt_bsoflags = "aio/direct" ]] && OCF_RESKEY_tgt_bsoflags="" ++ ++ tgt_args="" ++ [[ $OCF_RESKEY_tgt_bstype ]] && tgt_args="$tgt_args --bstype=$OCF_RESKEY_tgt_bstype" ++ [[ $OCF_RESKEY_tgt_bsoflags ]] && tgt_args="$tgt_args --bsoflags=$OCF_RESKEY_tgt_bsoflags" ++ [[ $OCF_RESKEY_tgt_device_type ]] && tgt_args="$tgt_args --device-type=$OCF_RESKEY_tgt_device_type" ++ ++ ocf_run tgtadm --lld iscsi --op new --mode logicalunit \ ++ --tid=${TID} \ ++ --lun=${OCF_RESKEY_lun} \ ++ $tgt_args \ ++ --backing-store ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC ++ if [ -z "$params" ]; then ++ return $OCF_SUCCESS ++ else ++ ocf_run tgtadm --lld iscsi --op update --mode logicalunit \ ++ --tid=${TID} \ ++ --lun=${OCF_RESKEY_lun} \ ++ --params ${params// /,} || exit $OCF_ERR_GENERIC ++ fi ++ ;; ++ lio) ++ # For lio, we first have to create a target device, then ++ # add it to the Target Portal Group as an LU. ++ ++ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/udev_path" ++ if [ ! -e "${block_configfs_path}" ]; then ++ ocf_run tcm_node --createdev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \ ++ ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC ++ elif [ -e "$block_configfs_path" ] && [ $(cat "$block_configfs_path") != "${OCF_RESKEY_path}" ]; then ++ ocf_exit_reason "Existing iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} has incorrect path: $(cat "$block_configfs_path") != ${OCF_RESKEY_path}" ++ exit $OCF_ERR_GENERIC ++ else ++ ocf_log info "iscsi iblock already exists: ${block_configfs_path}" + fi +- done +- params="${params} ${OCF_RESKEY_additional_parameters}" + +- # cleanup: tgt (as of tgtadm version 1.0.24) does not like an explicit "bsoflags=direct" +- # when used with "bstype=aio" (which always uses O_DIRECT) +- [[ $OCF_RESKEY_tgt_bstype/$OCF_RESKEY_tgt_bsoflags = "aio/direct" ]] && OCF_RESKEY_tgt_bsoflags="" ++ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then ++ ocf_run tcm_node --setunitserial=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \ ++ ${OCF_RESKEY_scsi_sn} || exit $OCF_ERR_GENERIC ++ fi + +- tgt_args="" +- [[ $OCF_RESKEY_tgt_bstype ]] && tgt_args="$tgt_args --bstype=$OCF_RESKEY_tgt_bstype" +- [[ $OCF_RESKEY_tgt_bsoflags ]] && tgt_args="$tgt_args --bsoflags=$OCF_RESKEY_tgt_bsoflags" +- [[ $OCF_RESKEY_tgt_device_type ]] && tgt_args="$tgt_args --device-type=$OCF_RESKEY_tgt_device_type" ++ lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path" ++ if [ ! -e "${lun_configfs_path}" ]; then ++ ocf_run lio_node --addlun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} \ ++ ${OCF_RESOURCE_INSTANCE} iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC ++ else ++ ocf_log info "iscsi lun already exists: ${lun_configfs_path}" ++ fi + +- ocf_run tgtadm --lld iscsi --op new --mode logicalunit \ +- --tid=${TID} \ +- --lun=${OCF_RESKEY_lun} \ +- $tgt_args \ +- --backing-store ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC +- if [ -z "$params" ]; then +- return $OCF_SUCCESS +- else +- ocf_run tgtadm --lld iscsi --op update --mode logicalunit \ +- --tid=${TID} \ +- --lun=${OCF_RESKEY_lun} \ +- --params ${params// /,} || exit $OCF_ERR_GENERIC +- fi +- ;; +- lio) +- # For lio, we first have to create a target device, then +- # add it to the Target Portal Group as an LU. +- ocf_run tcm_node --createdev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \ +- ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC +- if [ -n "${OCF_RESKEY_scsi_sn}" ]; then +- ocf_run tcm_node --setunitserial=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \ +- ${OCF_RESKEY_scsi_sn} || exit $OCF_ERR_GENERIC +- fi +- ocf_run lio_node --addlun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} \ +- ${OCF_RESOURCE_INSTANCE} iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC +- +- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then +- for initiator in ${OCF_RESKEY_allowed_initiators}; do +- ocf_run lio_node --addlunacl=${OCF_RESKEY_target_iqn} 1 \ +- ${initiator} ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC +- done +- fi +- ;; +- esac +- +- return $OCF_SUCCESS ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ for initiator in ${OCF_RESKEY_allowed_initiators}; do ++ acl_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/acls/${initiator}/lun_${OCF_RESKEY_lun}" ++ if [ ! -e "${acl_configfs_path}" ]; then ++ ocf_run lio_node --addlunacl=${OCF_RESKEY_target_iqn} 1 \ ++ ${initiator} ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ else ++ ocf_log info "iscsi acl already exists: ${acl_configfs_path}" ++ fi ++ done ++ fi ++ ;; ++ lio-t) ++ # For lio, we first have to create a target device, then ++ # add it to the Target Portal Group as an LU. ++ ocf_run targetcli /backstores/block create name=${OCF_RESOURCE_INSTANCE} dev=${OCF_RESKEY_path} write_back=False || exit $OCF_ERR_GENERIC ++ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then ++ echo ${OCF_RESKEY_scsi_sn} > /sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/wwn/vpd_unit_serial ++ fi ++ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/luns create /backstores/block/${OCF_RESOURCE_INSTANCE} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ for initiator in ${OCF_RESKEY_allowed_initiators}; do ++ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls create ${initiator} add_mapped_luns=False || exit $OCF_ERR_GENERIC ++ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/${initiator} create ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ done ++ fi ++ ;; ++ esac ++ ++ # Force the monitor operation to pass before start is considered a success. ++ iSCSILogicalUnit_monitor + } + + iSCSILogicalUnit_stop() { +- iSCSILogicalUnit_monitor +- if [ $? = $OCF_SUCCESS ]; then ++ iSCSILogicalUnit_monitor ++ if [ $? -eq $OCF_NOT_RUNNING ]; then ++ return $OCF_SUCCESS ++ fi ++ + case $OCF_RESKEY_implementation in +- iet) +- # IET allows us to remove LUs while they are in use +- ocf_run ietadm --op delete \ +- --tid=${TID} \ +- --lun=${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ ++ iet) ++ # IET allows us to remove LUs while they are in use ++ ocf_run ietadm --op delete \ ++ --tid=${TID} \ ++ --lun=${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC + ;; +- tgt) ++ tgt) + # tgt will fail to remove an LU while it is in use, + # but at the same time does not allow us to + # selectively shut down a connection that is using a +@@ -359,202 +403,240 @@ iSCSILogicalUnit_stop() { + # decides that the LU is no longer in use, or we get + # timed out by the LRM. + while ! ocf_run -warn tgtadm --lld iscsi --op delete --mode logicalunit \ +- --tid ${TID} \ +- --lun=${OCF_RESKEY_lun}; do +- sleep 1 ++ --tid ${TID} \ ++ --lun=${OCF_RESKEY_lun}; do ++ sleep 1 ++ done ++ ;; ++ lio) ++ ++ acls_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/acls" ++ for initiatorpath in ${acls_configfs_path}/*; do ++ initiator=$(basename "${initiatorpath}") ++ if [ -e "${initiatorpath}/lun_${OCF_RESKEY_lun}" ]; then ++ ocf_log info "deleting acl at ${initiatorpath}/lun_${OCF_RESKEY_lun}" ++ ocf_run lio_node --dellunacl=${OCF_RESKEY_target_iqn} 1 \ ++ ${initiator} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ fi + done ++ lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_#{${OCF_RESKEY_lun}/" ++ if [ -e "${lun_configfs_path}" ]; then ++ ocf_run lio_node --dellun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ fi ++ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path" ++ if [ -e "${block_configfs_path}" ]; then ++ ocf_run tcm_node --freedev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC ++ fi ++ ;; ++ lio-t) ++ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/luns delete ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ for initiator in ${OCF_RESKEY_allowed_initiators}; do ++ if targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/${initiator} status | grep "Mapped LUNs: 0" >/dev/null ; then ++ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/ delete ${initiator} ++ fi ++ done ++ fi ++ ++ ocf_run targetcli /backstores/block delete ${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC + ;; +- lio) +- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then +- for initiator in ${OCF_RESKEY_allowed_initiators}; do +- ocf_run lio_node --dellunacl=${OCF_RESKEY_target_iqn} 1 \ +- ${initiator} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC +- done +- fi +- ocf_run lio_node --dellun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC +- ocf_run tcm_node --freedev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC + esac +- fi +- +- return $OCF_SUCCESS ++ ++ return $OCF_SUCCESS + } + + iSCSILogicalUnit_monitor() { +- case $OCF_RESKEY_implementation in ++ case $OCF_RESKEY_implementation in + iet) +- # Figure out and set the target ID +- TID=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_target_iqn}$/\1/p" < /proc/net/iet/volume` +- if [ -z "${TID}" ]; then +- # Our target is not configured, thus we're not +- # running. +- return $OCF_NOT_RUNNING +- fi +- # FIXME: this looks for a matching LUN and path, but does +- # not actually test for the correct target ID. +- grep -E -q "[[:space:]]+lun:${OCF_RESKEY_lun}.*path:${OCF_RESKEY_path}$" /proc/net/iet/volume && return $OCF_SUCCESS +- ;; ++ # Figure out and set the target ID ++ TID=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_target_iqn}$/\1/p" < /proc/net/iet/volume` ++ if [ -z "${TID}" ]; then ++ # Our target is not configured, thus we're not ++ # running. ++ return $OCF_NOT_RUNNING ++ fi ++ # FIXME: this looks for a matching LUN and path, but does ++ # not actually test for the correct target ID. ++ grep -E -q "[[:space:]]+lun:${OCF_RESKEY_lun}.*path:${OCF_RESKEY_path}$" /proc/net/iet/volume && return $OCF_SUCCESS ++ ;; + tgt) +- # Figure out and set the target ID +- TID=`tgtadm --lld iscsi --op show --mode target \ +- | sed -ne "s/^Target \([[:digit:]]\+\): ${OCF_RESKEY_target_iqn}$/\1/p"` +- if [ -z "$TID" ]; then +- # Our target is not configured, thus we're not +- # running. +- return $OCF_NOT_RUNNING +- fi +- # This only looks for the backing store, but does not test +- # for the correct target ID and LUN. +- tgtadm --lld iscsi --op show --mode target \ +- | grep -E -q "[[:space:]]+Backing store.*: ${OCF_RESKEY_path}$" && return $OCF_SUCCESS +- ;; ++ # Figure out and set the target ID ++ TID=`tgtadm --lld iscsi --op show --mode target \ ++ | sed -ne "s/^Target \([[:digit:]]\+\): ${OCF_RESKEY_target_iqn}$/\1/p"` ++ if [ -z "$TID" ]; then ++ # Our target is not configured, thus we're not ++ # running. ++ return $OCF_NOT_RUNNING ++ fi ++ # This only looks for the backing store, but does not test ++ # for the correct target ID and LUN. ++ tgtadm --lld iscsi --op show --mode target \ ++ | grep -E -q "[[:space:]]+Backing store.*: ${OCF_RESKEY_path}$" && return $OCF_SUCCESS ++ ;; + lio) +- configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path" +- [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS +- ;; +- esac +- +- return $OCF_NOT_RUNNING ++ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path" ++ [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS ++ ++ # if we aren't activated, is a block device still left over? ++ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path" ++ [ -e ${block_configfs_path} ] && ocf_log warn "existing block without an active lun: ${block_configfs_path}" ++ [ -e ${block_configfs_path} ] && return $OCF_ERR_GENERIC ++ ++ ;; ++ lio-t) ++ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/*/udev_path" ++ [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS ++ ;; ++ esac ++ ++ return $OCF_NOT_RUNNING + } + + iSCSILogicalUnit_validate() { +- # Do we have all required variables? +- for var in target_iqn lun path; do ++ # Do we have all required variables? ++ for var in target_iqn lun path; do + param="OCF_RESKEY_${var}" + if [ -z "${!param}" ]; then +- ocf_log error "Missing resource parameter \"$var\"!" +- exit $OCF_ERR_CONFIGURED ++ ocf_exit_reason "Missing resource parameter \"$var\"!" ++ exit $OCF_ERR_CONFIGURED + fi +- done ++ done + +- # Is the configured implementation supported? +- case "$OCF_RESKEY_implementation" in +- "iet"|"tgt"|"lio") +- ;; ++ # Is the configured implementation supported? ++ case "$OCF_RESKEY_implementation" in ++ "iet"|"tgt"|"lio"|"lio-t") ++ ;; + "") +- # The user didn't specify an implementation, and we were +- # unable to determine one from installed binaries (in +- # other words: no binaries for any supported +- # implementation could be found) +- ocf_log error "Undefined iSCSI target implementation" +- exit $OCF_ERR_INSTALLED +- ;; ++ # The user didn't specify an implementation, and we were ++ # unable to determine one from installed binaries (in ++ # other words: no binaries for any supported ++ # implementation could be found) ++ ocf_exit_reason "Undefined iSCSI target implementation" ++ exit $OCF_ERR_INSTALLED ++ ;; + *) +- ocf_log error "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!" +- exit $OCF_ERR_CONFIGURED +- ;; +- esac ++ ocf_exit_reason "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!" ++ exit $OCF_ERR_CONFIGURED ++ ;; ++ esac + +- # Do we have a valid LUN? +- case $OCF_RESKEY_implementation in ++ # Do we have a valid LUN? ++ case $OCF_RESKEY_implementation in + iet) +- # IET allows LUN 0 and up +- [ $OCF_RESKEY_lun -ge 0 ] +- case $? in ++ # IET allows LUN 0 and up ++ [ $OCF_RESKEY_lun -ge 0 ] ++ case $? in + 0) +- # OK +- ;; ++ # OK ++ ;; + 1) +- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be a non-negative integer)." +- exit $OCF_ERR_CONFIGURED +- ;; ++ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be a non-negative integer)." ++ exit $OCF_ERR_CONFIGURED ++ ;; + *) +- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)." +- exit $OCF_ERR_CONFIGURED +- ;; +- esac +- ;; ++ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)." ++ exit $OCF_ERR_CONFIGURED ++ ;; ++ esac ++ ;; + tgt) +- # tgt reserves LUN 0 for its own purposes +- [ $OCF_RESKEY_lun -ge 1 ] +- case $? in ++ # tgt reserves LUN 0 for its own purposes ++ [ $OCF_RESKEY_lun -ge 1 ] ++ case $? in + 0) +- # OK +- ;; ++ # OK ++ ;; + 1) +- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be greater than 0)." +- exit $OCF_ERR_CONFIGURED +- ;; ++ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be greater than 0)." ++ exit $OCF_ERR_CONFIGURED ++ ;; + *) +- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)." +- exit $OCF_ERR_CONFIGURED +- ;; +- esac +- ;; +- esac +- +- # Do we have any configuration parameters that the current +- # implementation does not support? +- local unsupported_params +- local var +- local envar +- case $OCF_RESKEY_implementation in ++ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)." ++ exit $OCF_ERR_CONFIGURED ++ ;; ++ esac ++ ;; ++ esac ++ ++ # Do we have any configuration parameters that the current ++ # implementation does not support? ++ local unsupported_params ++ local var ++ local envar ++ case $OCF_RESKEY_implementation in + iet) +- # IET does not support setting the vendor and product ID +- # (it always uses "IET" and "VIRTUAL-DISK") +- unsupported_params="vendor_id product_id allowed_initiators lio_iblock tgt_bstype tgt_bsoflags tgt_device_type" +- ;; ++ # IET does not support setting the vendor and product ID ++ # (it always uses "IET" and "VIRTUAL-DISK") ++ unsupported_params="vendor_id product_id allowed_initiators lio_iblock tgt_bstype tgt_bsoflags tgt_device_type" ++ ;; + tgt) +- unsupported_params="allowed_initiators lio_iblock" +- ;; ++ unsupported_params="allowed_initiators lio_iblock" ++ ;; + lio) +- unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type" +- ;; +- esac +- for var in ${unsupported_params}; do +- envar=OCF_RESKEY_${var} +- defvar=OCF_RESKEY_${var}_default +- if [ -n "${!envar}" ]; then +- if [[ "${!envar}" != "${!defvar}" ]];then +- case "$__OCF_ACTION" in +- start|validate-all) +- ocf_log warn "Configuration parameter \"${var}\"" \ +- "is not supported by the iSCSI implementation" \ +- "and will be ignored." ;; +- esac +- fi +- fi +- done ++ unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type" ++ ;; ++ lio-t) ++ unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type lio_iblock" ++ ;; ++ esac ++ ++ for var in ${unsupported_params}; do ++ envar=OCF_RESKEY_${var} ++ defvar=OCF_RESKEY_${var}_default ++ if [ -n "${!envar}" ]; then ++ if [[ "${!envar}" != "${!defvar}" ]];then ++ case "$__OCF_ACTION" in ++ start|validate-all) ++ ocf_log warn "Configuration parameter \"${var}\"" \ ++ "is not supported by the iSCSI implementation" \ ++ "and will be ignored." ;; ++ esac ++ fi ++ fi ++ done + +- if ! ocf_is_probe; then +- # Do we have all required binaries? ++ if ! ocf_is_probe; then ++ # Do we have all required binaries? + case $OCF_RESKEY_implementation in +- iet) ++ iet) + check_binary ietadm + ;; +- tgt) ++ tgt) + check_binary tgtadm + ;; +- lio) ++ lio) + check_binary tcm_node + check_binary lio_node + ;; ++ lio-t) ++ check_binary targetcli ++ ;; + esac + +- # Is the required kernel functionality available? ++ # Is the required kernel functionality available? + case $OCF_RESKEY_implementation in +- iet) ++ iet) + [ -d /proc/net/iet ] + if [ $? -ne 0 ]; then +- ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded." +- exit $OCF_ERR_INSTALLED ++ ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded." ++ exit $OCF_ERR_INSTALLED + fi + ;; +- tgt) +- # tgt is userland only ++ tgt) ++ # tgt is userland only + ;; + esac +- fi ++ fi + +- return $OCF_SUCCESS ++ return $OCF_SUCCESS + } + +- + case $1 in +- meta-data) ++meta-data) + meta_data + exit $OCF_SUCCESS + ;; +- usage|help) ++usage|help) + iSCSILogicalUnit_usage + exit $OCF_SUCCESS + ;; +@@ -568,13 +650,14 @@ start) iSCSILogicalUnit_start;; + stop) iSCSILogicalUnit_stop;; + monitor|status) iSCSILogicalUnit_monitor;; + reload) ocf_log err "Reloading..." +- iSCSILogicalUnit_start ++ iSCSILogicalUnit_start + ;; + validate-all) ;; + *) iSCSILogicalUnit_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; + esac ++ + rc=$? + ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" + exit $rc +diff --git a/heartbeat/iSCSITarget b/heartbeat/iSCSITarget +index a988fb2..72ec64a 100755 +--- a/heartbeat/iSCSITarget ++++ b/heartbeat/iSCSITarget +@@ -1,7 +1,7 @@ + #!/bin/bash + # + # +-# iSCSITarget OCF RA. Exports and manages iSCSI targets. ++# iSCSITarget OCF RA. Exports and manages iSCSI targets. + # + # (c) 2009-2010 Florian Haas, Dejan Muhamedagic, + # and Linux-HA contributors +@@ -34,11 +34,13 @@ + # Defaults + # Set a default implementation based on software installed + if have_binary ietadm; then +- OCF_RESKEY_implementation_default="iet" ++ OCF_RESKEY_implementation_default="iet" + elif have_binary tgtadm; then +- OCF_RESKEY_implementation_default="tgt" ++ OCF_RESKEY_implementation_default="tgt" + elif have_binary lio_node; then +- OCF_RESKEY_implementation_default="lio" ++ OCF_RESKEY_implementation_default="lio" ++elif have_binary targetcli; then ++ OCF_RESKEY_implementation_default="lio-t" + fi + : ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}} + +@@ -67,12 +69,12 @@ Units (LUs) exported via a daemon that speaks the iSCSI protocol. + + + The iSCSI target daemon implementation. Must be one of "iet", "tgt", +-or "lio". If unspecified, an implementation is selected based on the ++"lio", or "lio-t". If unspecified, an implementation is selected based on the + availability of management utilities, with "iet" being tried first, +-then "tgt", then "lio". ++then "tgt", then "lio", then "lio-t". + + Specifies the iSCSI target implementation +-("iet", "tgt" or "lio"). ++("iet", "tgt", "lio", or "lio-t"). + + + +@@ -148,11 +150,11 @@ dependent. Neither the name nor the value may contain whitespace. + + + +- +- +- +- +- ++ ++ ++ ++ ++ + + + +@@ -170,182 +172,233 @@ END + } + + iSCSITarget_start() { +- iSCSITarget_monitor +- if [ $? = $OCF_SUCCESS ]; then +- return $OCF_SUCCESS +- fi ++ iSCSITarget_monitor ++ if [ $? = $OCF_SUCCESS ]; then ++ return $OCF_SUCCESS ++ fi + +- local param +- local name +- local value +- local initiator +- local portal ++ local param ++ local name ++ local value ++ local initiator ++ local portal + +- case $OCF_RESKEY_implementation in ++ case $OCF_RESKEY_implementation in + iet) +- local lasttid +- local tid +- if [ "${OCF_RESKEY_tid}" ]; then +- tid="${OCF_RESKEY_tid}" +- else +- # Figure out the last used target ID, add 1 to get the new +- # target ID. +- ocf_take_lock $LOCKFILE +- ocf_release_lock_on_exit $LOCKFILE +- lasttid=`sed -ne "s/tid:\([[:digit:]]\+\) name:.*/\1/p" < /proc/net/iet/volume | sort -n | tail -n1` +- [ -z "${lasttid}" ] && lasttid=0 +- tid=$((++lasttid)) +- fi +- # Create the target. +- ocf_run ietadm --op new \ +- --tid=${tid} \ +- --params Name=${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC +- # Set additional parameters. +- for param in ${OCF_RESKEY_additional_parameters}; do +- name=${param%=*} +- value=${param#*=} +- ocf_run ietadm --op update \ +- --tid=${tid} \ +- --params ${name}=${value} || exit $OCF_ERR_GENERIC +- done +- # Legacy versions of IET allow targets by default, current +- # versions deny. To be safe we manage both the .allow and +- # .deny files. +- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then +- echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.deny +- echo "${OCF_RESKEY_iqn} ${OCF_RESKEY_allowed_initiators// /,}" >> /etc/initiators.allow +- else +- echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.allow +- fi +- # In iet, adding a new user and assigning it to a target +- # is one operation. +- if [ -n "${OCF_RESKEY_incoming_username}" ]; then +- ocf_run ietadm --op new --user \ +- --tid=${tid} \ +- --params=IncomingUser=${OCF_RESKEY_incoming_username},Password=${OCF_RESKEY_incoming_password} \ +- || exit $OCF_ERR_GENERIC +- fi +- ;; ++ local lasttid ++ local tid ++ if [ "${OCF_RESKEY_tid}" ]; then ++ tid="${OCF_RESKEY_tid}" ++ else ++ # Figure out the last used target ID, add 1 to get the new ++ # target ID. ++ ocf_take_lock $LOCKFILE ++ ocf_release_lock_on_exit $LOCKFILE ++ lasttid=`sed -ne "s/tid:\([[:digit:]]\+\) name:.*/\1/p" < /proc/net/iet/volume | sort -n | tail -n1` ++ [ -z "${lasttid}" ] && lasttid=0 ++ tid=$((++lasttid)) ++ fi ++ ++ # Create the target. ++ ocf_run ietadm --op new \ ++ --tid=${tid} \ ++ --params Name=${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC ++ ++ # Set additional parameters. ++ for param in ${OCF_RESKEY_additional_parameters}; do ++ name=${param%=*} ++ value=${param#*=} ++ ocf_run ietadm --op update \ ++ --tid=${tid} \ ++ --params ${name}=${value} || exit $OCF_ERR_GENERIC ++ done ++ ++ # Legacy versions of IET allow targets by default, current ++ # versions deny. To be safe we manage both the .allow and ++ # .deny files. ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.deny ++ echo "${OCF_RESKEY_iqn} ${OCF_RESKEY_allowed_initiators// /,}" >> /etc/initiators.allow ++ else ++ echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.allow ++ fi ++ # In iet, adding a new user and assigning it to a target ++ # is one operation. ++ if [ -n "${OCF_RESKEY_incoming_username}" ]; then ++ ocf_run ietadm --op new --user \ ++ --tid=${tid} \ ++ --params=IncomingUser=${OCF_RESKEY_incoming_username},Password=${OCF_RESKEY_incoming_password} \ ++ || exit $OCF_ERR_GENERIC ++ fi ++ ;; + tgt) +- local tid +- tid="${OCF_RESKEY_tid}" +- # Create the target. +- ocf_run tgtadm --lld iscsi --op new --mode target \ +- --tid=${tid} \ +- --targetname ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC +- # Set parameters. +- for param in ${OCF_RESKEY_additional_parameters}; do +- name=${param%=*} +- value=${param#*=} +- ocf_run tgtadm --lld iscsi --op update --mode target \ +- --tid=${tid} \ +- --name=${name} --value=${value} || exit $OCF_ERR_GENERIC +- done +- # For tgt, we always have to add access per initiator; +- # access to targets is denied by default. If +- # "allowed_initiators" is unset, we must use the special +- # keyword ALL. +- for initiator in ${OCF_RESKEY_allowed_initiators=ALL}; do +- ocf_run tgtadm --lld iscsi --op bind --mode target \ +- --tid=${tid} \ +- --initiator-address=${initiator} || exit $OCF_ERR_GENERIC +- done +- # In tgt, we must first create a user account, then assign +- # it to a target using the "bind" operation. +- if [ -n "${OCF_RESKEY_incoming_username}" ]; then +- ocf_run tgtadm --lld iscsi --mode account --op new \ +- --user=${OCF_RESKEY_incoming_username} \ +- --password=${OCF_RESKEY_incoming_password} || exit $OCF_ERR_GENERIC +- ocf_run tgtadm --lld iscsi --mode account --op bind \ +- --tid=${tid} \ +- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC +- fi +- ;; ++ local tid ++ tid="${OCF_RESKEY_tid}" ++ # Create the target. ++ ocf_run tgtadm --lld iscsi --op new --mode target \ ++ --tid=${tid} \ ++ --targetname ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC ++ ++ # Set parameters. ++ for param in ${OCF_RESKEY_additional_parameters}; do ++ name=${param%=*} ++ value=${param#*=} ++ ocf_run tgtadm --lld iscsi --op update --mode target \ ++ --tid=${tid} \ ++ --name=${name} --value=${value} || exit $OCF_ERR_GENERIC ++ done ++ ++ # For tgt, we always have to add access per initiator; ++ # access to targets is denied by default. If ++ # "allowed_initiators" is unset, we must use the special ++ # keyword ALL. ++ for initiator in ${OCF_RESKEY_allowed_initiators=ALL}; do ++ ocf_run tgtadm --lld iscsi --op bind --mode target \ ++ --tid=${tid} \ ++ --initiator-address=${initiator} || exit $OCF_ERR_GENERIC ++ done ++ ++ # In tgt, we must first create a user account, then assign ++ # it to a target using the "bind" operation. ++ if [ -n "${OCF_RESKEY_incoming_username}" ]; then ++ ocf_run tgtadm --lld iscsi --mode account --op new \ ++ --user=${OCF_RESKEY_incoming_username} \ ++ --password=${OCF_RESKEY_incoming_password} || exit $OCF_ERR_GENERIC ++ ocf_run tgtadm --lld iscsi --mode account --op bind \ ++ --tid=${tid} \ ++ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC ++ fi ++ ;; + lio) +- # lio distinguishes between targets and target portal +- # groups (TPGs). We will always create one TPG, with the +- # number 1. In lio, creating a network portal +- # automatically creates the corresponding target if it +- # doesn't already exist. +- for portal in ${OCF_RESKEY_portals}; do +- ocf_run lio_node --addnp ${OCF_RESKEY_iqn} 1 \ +- ${portal} || exit $OCF_ERR_GENERIC +- done +- # in lio, we can set target parameters by manipulating +- # the appropriate configfs entries +- for param in ${OCF_RESKEY_additional_parameters}; do +- name=${param%=*} +- value=${param#*=} +- configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}" +- if [ -e ${configfs_path} ]; then +- echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC ++ # lio distinguishes between targets and target portal ++ # groups (TPGs). We will always create one TPG, with the ++ # number 1. In lio, creating a network portal ++ # automatically creates the corresponding target if it ++ # doesn't already exist. ++ for portal in ${OCF_RESKEY_portals}; do ++ ocf_run lio_node --addnp ${OCF_RESKEY_iqn} 1 \ ++ ${portal} || exit $OCF_ERR_GENERIC ++ done ++ ++ # in lio, we can set target parameters by manipulating ++ # the appropriate configfs entries ++ for param in ${OCF_RESKEY_additional_parameters}; do ++ name=${param%=*} ++ value=${param#*=} ++ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}" ++ if [ -e ${configfs_path} ]; then ++ echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC ++ else ++ ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored." ++ fi ++ done ++ ++ # lio does per-initiator filtering by default. To disable ++ # this, we need to switch the target to "permissive mode". ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ for initiator in ${OCF_RESKEY_allowed_initiators}; do ++ ocf_run lio_node --addnodeacl ${OCF_RESKEY_iqn} 1 \ ++ ${initiator} || exit $OCF_ERR_GENERIC ++ done + else +- ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored." ++ ocf_run lio_node --permissive ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC ++ # permissive mode enables read-only access by default, ++ # so we need to change that to RW to be in line with ++ # the other implementations. ++ echo 0 > "/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect" ++ if [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect` -ne 0 ]; then ++ ocf_log err "Failed to disable write protection for target ${OCF_RESKEY_iqn}." ++ exit $OCF_ERR_GENERIC ++ fi + fi +- done +- # lio does per-initiator filtering by default. To disable +- # this, we need to switch the target to "permissive mode". +- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then +- for initiator in ${OCF_RESKEY_allowed_initiators}; do +- ocf_run lio_node --addnodeacl ${OCF_RESKEY_iqn} 1 \ +- ${initiator} || exit $OCF_ERR_GENERIC ++ ++ # TODO: add CHAP authentication support when it gets added ++ # back into LIO ++ ocf_run lio_node --disableauth ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC ++ # Finally, we need to enable the target to allow ++ # initiators to connect ++ ocf_run lio_node --enabletpg=${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC ++ ;; ++ lio-t) ++ # lio distinguishes between targets and target portal ++ # groups (TPGs). We will always create one TPG, with the ++ # number 1. In lio, creating a network portal ++ # automatically creates the corresponding target if it ++ # doesn't already exist. ++ for portal in ${OCF_RESKEY_portals}; do ++ ocf_run targetcli /iscsi create ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC ++ if [ $portal != ${OCF_RESKEY_portals_default} ] ; then ++ IFS=':' read -a sep_portal <<< "$portal" ++ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/portals create "${sep_portal[0]}" "${sep_portal[1]}" || exit $OCF_ERR_GENERIC ++ fi + done +- else +- ocf_run lio_node --permissive ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC +- # permissive mode enables read-only access by default, +- # so we need to change that to RW to be in line with +- # the other implementations. +- echo 0 > "/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect" +- if [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect` -ne 0 ]; then +- ocf_log err "Failed to disable write protection for target ${OCF_RESKEY_iqn}." +- exit $OCF_ERR_GENERIC ++ # in lio, we can set target parameters by manipulating ++ # the appropriate configfs entries ++ for param in ${OCF_RESKEY_additional_parameters}; do ++ name=${param%=*} ++ value=${param#*=} ++ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}" ++ if [ -e ${configfs_path} ]; then ++ echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC ++ else ++ ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored." ++ fi ++ done ++ # lio does per-initiator filtering by default. To disable ++ # this, we need to switch the target to "permissive mode". ++ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then ++ for initiator in ${OCF_RESKEY_allowed_initiators}; do ++ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/acls create ${initiator} || exit $OCF_ERR_GENERIC ++ done ++ else ++ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/ set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1 || exit $OCF_ERR_GENERIC + fi +- fi +- # TODO: add CHAP authentication support when it gets added +- # back into LIO +- ocf_run lio_node --disableauth ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC +- # Finally, we need to enable the target to allow +- # initiators to connect +- ocf_run lio_node --enabletpg=${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC +- ;; +- esac +- +- return $OCF_SUCCESS ++ # TODO: add CHAP authentication support when it gets added ++ # back into LIO ++ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/ set attribute authentication=0 || exit $OCF_ERR_GENERIC ++# ocf_run targetcli /iscsi ++ ;; ++ esac ++ ++ iSCSITarget_monitor + } + + iSCSITarget_stop() { +- iSCSITarget_monitor +- if [ $? = $OCF_SUCCESS ]; then ++ iSCSITarget_monitor ++ if [ $? -eq $OCF_NOT_RUNNING ]; then ++ return $OCF_SUCCESS ++ fi ++ + local tid + case $OCF_RESKEY_implementation in +- iet) ++ iet) + # Figure out the target ID + tid=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_iqn}/\1/p" < /proc/net/iet/volume` + if [ -z "${tid}" ]; then +- ocf_log err "Failed to retrieve target ID for IQN ${OCF_RESKEY_iqn}" +- exit $OCF_ERR_GENERIC ++ ocf_log err "Failed to retrieve target ID for IQN ${OCF_RESKEY_iqn}" ++ exit $OCF_ERR_GENERIC + fi + # Close existing connections. There is no other way to + # do this in IET than to parse the contents of + # /proc/net/iet/session. + set -- $(sed -ne '/^tid:'${tid}' /,/^tid/ { +- /^[[:space:]]*sid:\([0-9]\+\)/ { +- s/^[[:space:]]*sid:\([0-9]*\).*/--sid=\1/; h; +- }; +- /^[[:space:]]*cid:\([0-9]\+\)/ { +- s/^[[:space:]]*cid:\([0-9]*\).*/--cid=\1/; G; p; +- }; +- }' < /proc/net/iet/session) ++ /^[[:space:]]*sid:\([0-9]\+\)/ { ++ s/^[[:space:]]*sid:\([0-9]*\).*/--sid=\1/; h; ++ }; ++ /^[[:space:]]*cid:\([0-9]\+\)/ { ++ s/^[[:space:]]*cid:\([0-9]*\).*/--cid=\1/; G; p; ++ }; ++ }' < /proc/net/iet/session) + while [[ -n $2 ]]; do +- # $2 $1 looks like "--sid=X --cid=Y" +- ocf_run ietadm --op delete \ +- --tid=${tid} $2 $1 +- shift 2 ++ # $2 $1 looks like "--sid=X --cid=Y" ++ ocf_run ietadm --op delete \ ++ --tid=${tid} $2 $1 ++ shift 2 + done +- # In iet, unassigning a user from a target and ++ # In iet, unassigning a user from a target and + # deleting the user account is one operation. + if [ -n "${OCF_RESKEY_incoming_username}" ]; then +- ocf_run ietadm --op delete --user \ ++ ocf_run ietadm --op delete --user \ + --tid=${tid} \ + --params=IncomingUser=${OCF_RESKEY_incoming_username} \ + || exit $OCF_ERR_GENERIC +@@ -353,216 +406,226 @@ iSCSITarget_stop() { + # Loop on delete. Keep trying until we time out, if + # necessary. + while true; do +- if ietadm --op delete --tid=${tid}; then +- ocf_log debug "Removed target ${OCF_RESKEY_iqn}." +- break +- else +- ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying." +- sleep 1 +- fi ++ if ietadm --op delete --tid=${tid}; then ++ ocf_log debug "Removed target ${OCF_RESKEY_iqn}." ++ break ++ else ++ ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying." ++ sleep 1 ++ fi + done + # Avoid stale /etc/initiators.{allow,deny} entries + # for this target + if [ -e /etc/initiators.deny ]; then +- ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \ ++ ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \ + -i /etc/initiators.deny + fi + if [ -e /etc/initiators.allow ]; then +- ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \ ++ ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \ + -i /etc/initiators.allow + fi + ;; +- tgt) ++ tgt) + tid="${OCF_RESKEY_tid}" + # Close existing connections. There is no other way to + # do this in tgt than to parse the output of "tgtadm --op + # show". + set -- $(tgtadm --lld iscsi --op show --mode target \ +- | sed -ne '/^Target '${tid}':/,/^Target/ { +- /^[[:space:]]*I_T nexus: \([0-9]\+\)/ { +- s/^.*: \([0-9]*\).*/--sid=\1/; h; +- }; +- /^[[:space:]]*Connection: \([0-9]\+\)/ { +- s/^.*: \([0-9]*\).*/--cid=\1/; G; p; +- }; +- /^[[:space:]]*LUN information:/ q; +- }') ++ | sed -ne '/^Target '${tid}':/,/^Target/ { ++ /^[[:space:]]*I_T nexus: \([0-9]\+\)/ { ++ s/^.*: \([0-9]*\).*/--sid=\1/; h; ++ }; ++ /^[[:space:]]*Connection: \([0-9]\+\)/ { ++ s/^.*: \([0-9]*\).*/--cid=\1/; G; p; ++ }; ++ /^[[:space:]]*LUN information:/ q; ++ }') + while [[ -n $2 ]]; do +- # $2 $1 looks like "--sid=X --cid=Y" +- ocf_run tgtadm --lld iscsi --op delete --mode connection \ ++ # $2 $1 looks like "--sid=X --cid=Y" ++ ocf_run tgtadm --lld iscsi --op delete --mode connection \ + --tid=${tid} $2 $1 +- shift 2 ++ shift 2 + done +- # In tgt, we must first unbind the user account from ++ # In tgt, we must first unbind the user account from + # the target, then remove the account itself. + if [ -n "${OCF_RESKEY_incoming_username}" ]; then +- ocf_run tgtadm --lld iscsi --mode account --op unbind \ +- --tid=${tid} \ +- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC +- ocf_run tgtadm --lld iscsi --mode account --op delete \ +- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC ++ ocf_run tgtadm --lld iscsi --mode account --op unbind \ ++ --tid=${tid} \ ++ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC ++ ocf_run tgtadm --lld iscsi --mode account --op delete \ ++ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC + fi + # Loop on delete. Keep trying until we time out, if + # necessary. + while true; do +- if tgtadm --lld iscsi --op delete --mode target --tid=${tid}; then +- ocf_log debug "Removed target ${OCF_RESKEY_iqn}." +- break +- else +- ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying." +- sleep 1 +- fi ++ if tgtadm --lld iscsi --op delete --mode target --tid=${tid}; then ++ ocf_log debug "Removed target ${OCF_RESKEY_iqn}." ++ break ++ else ++ ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying." ++ sleep 1 ++ fi + done + # In tgt, we don't have to worry about our ACL + # entries. They are automatically removed upon target + # deletion. + ;; +- lio) ++ lio) + # In lio, removing a target automatically removes all + # associated TPGs, network portals, and LUNs. + ocf_run lio_node --deliqn ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC + ;; ++ lio-t) ++ ocf_run targetcli /iscsi delete ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC ++ ;; + esac +- fi + +- return $OCF_SUCCESS ++ return $OCF_SUCCESS + } + + iSCSITarget_monitor() { +- case $OCF_RESKEY_implementation in ++ case $OCF_RESKEY_implementation in + iet) +- grep -Eq "tid:[0-9]+ name:${OCF_RESKEY_iqn}" /proc/net/iet/volume && return $OCF_SUCCESS +- ;; ++ grep -Eq "tid:[0-9]+ name:${OCF_RESKEY_iqn}" /proc/net/iet/volume && return $OCF_SUCCESS ++ ;; + tgt) +- tgtadm --lld iscsi --op show --mode target \ ++ tgtadm --lld iscsi --op show --mode target \ + | grep -Eq "Target [0-9]+: ${OCF_RESKEY_iqn}" && return $OCF_SUCCESS +- ;; +- lio) +- # if we have no configfs entry for the target, it's +- # definitely stopped +- [ -d /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING +- # if the target is there, but its TPG is not enabled, then +- # we also consider it stopped +- [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/enable` -eq 1 ] || return $OCF_NOT_RUNNING +- return $OCF_SUCCESS +- ;; +- esac +- +- return $OCF_NOT_RUNNING ++ ;; ++ lio | lio-t) ++ # if we have no configfs entry for the target, it's ++ # definitely stopped ++ [ -d /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING ++ # if the target is there, but its TPG is not enabled, then ++ # we also consider it stopped ++ [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/enable` -eq 1 ] || return $OCF_NOT_RUNNING ++ return $OCF_SUCCESS ++ ;; ++ esac ++ ++ return $OCF_NOT_RUNNING + } + + iSCSITarget_validate() { +- # Do we have all required variables? +- local required_vars +- case $OCF_RESKEY_implementation in ++ # Do we have all required variables? ++ local required_vars ++ case $OCF_RESKEY_implementation in + iet) +- required_vars="iqn" +- ;; ++ required_vars="iqn" ++ ;; + tgt) +- required_vars="iqn tid" +- ;; +- esac +- for var in ${required_vars}; do +- param="OCF_RESKEY_${var}" +- if [ -z "${!param}" ]; then +- ocf_log error "Missing resource parameter \"$var\"!" +- exit $OCF_ERR_CONFIGURED +- fi +- done ++ required_vars="iqn tid" ++ ;; ++ esac ++ ++ for var in ${required_vars}; do ++ param="OCF_RESKEY_${var}" ++ if [ -z "${!param}" ]; then ++ ocf_exit_reason "Missing resource parameter \"$var\"!" ++ exit $OCF_ERR_CONFIGURED ++ fi ++ done + +- # Is the configured implementation supported? +- case "$OCF_RESKEY_implementation" in +- "iet"|"tgt"|"lio") +- ;; ++ # Is the configured implementation supported? ++ case "$OCF_RESKEY_implementation" in ++ "iet"|"tgt"|"lio"|"lio-t") ++ ;; + "") +- # The user didn't specify an implementation, and we were +- # unable to determine one from installed binaries (in +- # other words: no binaries for any supported +- # implementation could be found) +- ocf_log error "Undefined iSCSI target implementation" +- exit $OCF_ERR_INSTALLED +- ;; ++ # The user didn't specify an implementation, and we were ++ # unable to determine one from installed binaries (in ++ # other words: no binaries for any supported ++ # implementation could be found) ++ ocf_exit_reason "Undefined iSCSI target implementation" ++ exit $OCF_ERR_INSTALLED ++ ;; + *) +- ocf_log error "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!" +- exit $OCF_ERR_CONFIGURED +- ;; +- esac +- +- # Do we have any configuration parameters that the current +- # implementation does not support? +- local unsupported_params +- local var +- local envar +- case $OCF_RESKEY_implementation in ++ ocf_exit_reason "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!" ++ exit $OCF_ERR_CONFIGURED ++ ;; ++ esac ++ ++ # Do we have any configuration parameters that the current ++ # implementation does not support? ++ local unsupported_params ++ local var ++ local envar ++ case $OCF_RESKEY_implementation in + iet|tgt) +- # IET and tgt do not support binding a target portal to a +- # specific IP address. +- unsupported_params="portals" +- ;; +- lio) +- # TODO: Remove incoming_username and incoming_password +- # from this check when LIO 3.0 gets CHAP authentication +- unsupported_params="tid incoming_username incoming_password" +- ;; +- esac +- for var in ${unsupported_params}; do +- envar=OCF_RESKEY_${var} +- defvar=OCF_RESKEY_${var}_default +- if [ -n "${!envar}" ]; then +- if [[ "${!envar}" != "${!defvar}" ]];then +- case "$__OCF_ACTION" in +- start|validate-all) +- ocf_log warn "Configuration parameter \"${var}\"" \ +- "is not supported by the iSCSI implementation" \ +- "and will be ignored." ;; +- esac +- fi +- fi +- done ++ # IET and tgt do not support binding a target portal to a ++ # specific IP address. ++ unsupported_params="portals" ++ ;; ++ lio|lio-t) ++ # TODO: Remove incoming_username and incoming_password ++ # from this check when LIO 3.0 gets CHAP authentication ++ unsupported_params="tid incoming_username incoming_password" ++ ;; ++ esac + +- if ! ocf_is_probe; then +- # Do we have all required binaries? ++ for var in ${unsupported_params}; do ++ envar=OCF_RESKEY_${var} ++ defvar=OCF_RESKEY_${var}_default ++ if [ -n "${!envar}" ]; then ++ if [[ "${!envar}" != "${!defvar}" ]];then ++ case "$__OCF_ACTION" in ++ start|validate-all) ++ ocf_log warn "Configuration parameter \"${var}\"" \ ++ "is not supported by the iSCSI implementation" \ ++ "and will be ignored." ;; ++ esac ++ fi ++ fi ++ done ++ ++ if ! ocf_is_probe; then ++ # Do we have all required binaries? + case $OCF_RESKEY_implementation in +- iet) ++ iet) + check_binary ietadm + ;; +- tgt) ++ tgt) + check_binary tgtadm + ;; +- lio) ++ lio) + check_binary tcm_node + check_binary lio_node + ;; ++ lio-t) ++ check_binary targetcli ++ ;; + esac + +- # Is the required kernel functionality available? ++ # Is the required kernel functionality available? + case $OCF_RESKEY_implementation in +- iet) ++ iet) + [ -d /proc/net/iet ] + if [ $? -ne 0 ]; then +- ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded." +- exit $OCF_ERR_INSTALLED ++ ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded." ++ exit $OCF_ERR_INSTALLED + fi + ;; +- tgt) +- # tgt is userland only ++ tgt) ++ # tgt is userland only + ;; +- lio) +- # lio needs configfs to be mounted ++ lio) ++ # lio needs configfs to be mounted + if ! grep -Eq "^.*/sys/kernel/config[[:space:]]+configfs" /proc/mounts; then +- ocf_log err "configfs not mounted at /sys/kernel/config -- check if required modules are loaded." +- exit $OCF_ERR_INSTALLED ++ ocf_log err "configfs not mounted at /sys/kernel/config -- check if required modules are loaded." ++ exit $OCF_ERR_INSTALLED + fi +- # check for configfs entries created by target_core_mod ++ # check for configfs entries created by target_core_mod + if [ ! -d /sys/kernel/config/target ]; then +- ocf_log err "/sys/kernel/config/target does not exist or is not a directory -- check if required modules are loaded." +- exit $OCF_ERR_INSTALLED ++ ocf_log err "/sys/kernel/config/target does not exist or is not a directory -- check if required modules are loaded." ++ exit $OCF_ERR_INSTALLED + fi + ;; ++ lio-t) ++ #targetcli loads the needed kernel modules ++ ;; + esac +- fi ++ fi + +- return $OCF_SUCCESS ++ return $OCF_SUCCESS + } + + +@@ -585,7 +648,7 @@ start) iSCSITarget_start;; + stop) iSCSITarget_stop;; + monitor|status) iSCSITarget_monitor;; + reload) ocf_log err "Reloading..." +- iSCSITarget_start ++ iSCSITarget_start + ;; + validate-all) ;; + *) iSCSITarget_usage +-- +1.8.4.2 + diff --git a/SOURCES/bz1118029-iscsi-remove-write-back.patch b/SOURCES/bz1118029-iscsi-remove-write-back.patch new file mode 100644 index 0000000..eb600f8 --- /dev/null +++ b/SOURCES/bz1118029-iscsi-remove-write-back.patch @@ -0,0 +1,13 @@ +diff --git a/heartbeat/iSCSILogicalUnit b/heartbeat/iSCSILogicalUnit +index b9c1139..ffd66ff 100755 +--- a/heartbeat/iSCSILogicalUnit ++++ b/heartbeat/iSCSILogicalUnit +@@ -362,7 +362,7 @@ iSCSILogicalUnit_start() { + lio-t) + # For lio, we first have to create a target device, then + # add it to the Target Portal Group as an LU. +- ocf_run targetcli /backstores/block create name=${OCF_RESOURCE_INSTANCE} dev=${OCF_RESKEY_path} write_back=False || exit $OCF_ERR_GENERIC ++ ocf_run targetcli /backstores/block create name=${OCF_RESOURCE_INSTANCE} dev=${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC + if [ -n "${OCF_RESKEY_scsi_sn}" ]; then + echo ${OCF_RESKEY_scsi_sn} > /sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/wwn/vpd_unit_serial + fi diff --git a/SOURCES/bz1118029_iscsi_syntax_fix.patch b/SOURCES/bz1118029_iscsi_syntax_fix.patch new file mode 100644 index 0000000..d636925 --- /dev/null +++ b/SOURCES/bz1118029_iscsi_syntax_fix.patch @@ -0,0 +1,39 @@ +From 3a9d34b37c3959c75b60a3598ed0786e5c48a7b3 Mon Sep 17 00:00:00 2001 +From: jprades +Date: Wed, 17 Sep 2014 17:54:10 -0400 +Subject: [PATCH] High: iSCSILogicalUnit: fixes syntax errors + +--- + heartbeat/iSCSILogicalUnit | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/heartbeat/iSCSILogicalUnit b/heartbeat/iSCSILogicalUnit +index c4cee0d..b9c1139 100755 +--- a/heartbeat/iSCSILogicalUnit ++++ b/heartbeat/iSCSILogicalUnit +@@ -419,11 +419,11 @@ iSCSILogicalUnit_stop() { + ${initiator} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC + fi + done +- lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_#{${OCF_RESKEY_lun}/" ++ lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/" + if [ -e "${lun_configfs_path}" ]; then + ocf_run lio_node --dellun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC + fi +- block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path" ++ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/udev_path" + if [ -e "${block_configfs_path}" ]; then + ocf_run tcm_node --freedev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC + fi +@@ -478,7 +478,7 @@ iSCSILogicalUnit_monitor() { + [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS + + # if we aren't activated, is a block device still left over? +- block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path" ++ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/udev_path" + [ -e ${block_configfs_path} ] && ocf_log warn "existing block without an active lun: ${block_configfs_path}" + [ -e ${block_configfs_path} ] && return $OCF_ERR_GENERIC + +-- +1.8.4.2 + diff --git a/SOURCES/bz1122285-ethmonitor-infiniband.patch b/SOURCES/bz1122285-ethmonitor-infiniband.patch new file mode 100644 index 0000000..1c5411a --- /dev/null +++ b/SOURCES/bz1122285-ethmonitor-infiniband.patch @@ -0,0 +1,466 @@ +From feffc766c48a1010c1bf4f8b1db74795d06dbd50 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 25 Aug 2014 14:57:09 -0500 +Subject: [PATCH 2/4] ethmonitor updates + +--- + heartbeat/ethmonitor | 290 +++++++++++++++++++++++++++++++++------------------ + 1 file changed, 187 insertions(+), 103 deletions(-) + +diff --git a/heartbeat/ethmonitor b/heartbeat/ethmonitor +index b85d7fc..a447391 100755 +--- a/heartbeat/ethmonitor ++++ b/heartbeat/ethmonitor +@@ -1,14 +1,14 @@ + #!/bin/sh + # +-# OCF Resource Agent compliant script. +-# Monitor the vitality of a local network interface. ++# OCF Resource Agent compliant script. ++# Monitor the vitality of a local network interface. + # + # Based on the work by Robert Euhus and Lars Marowsky-Br�e. + # + # Transfered from Ipaddr2 into ethmonitor by Alexander Krauth + # + # Copyright (c) 2011 Robert Euhus, Alexander Krauth, Lars Marowsky-Br�e +-# All Rights Reserved. ++# All Rights Reserved. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of version 2 of the GNU General Public License as +@@ -29,12 +29,12 @@ + # along with this program; if not, write the Free Software Foundation, + # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + # +-# OCF parameters are as below ++# OCF parameters are as below + # + # OCF_RESKEY_interface + # OCF_RESKEY_multiplicator + # OCF_RESKEY_name +-# OCF_RESKEY_repeat_count ++# OCF_RESKEY_repeat_count + # OCF_RESKEY_repeat_interval + # OCF_RESKEY_pktcnt_timeout + # OCF_RESKEY_arping_count +@@ -70,10 +70,13 @@ The resource configuration requires a monitor operation, because the monitor doe + In addition to the resource configuration, you need to configure some location constraints, based on a CIB attribute value. + The name of the attribute value is configured in the 'name' option of this RA. + +-Example constraint configuration: ++Example constraint configuration using crmsh + location loc_connected_node my_resource_grp \ + rule $id="rule_loc_connected_node" -INF: ethmonitor eq 0 + ++Example constraint configuration using pcs. Only allow 'my_resource' to run on nodes where eth0 ethernet device is available. ++pcs constraint location my_resource rule score=-INFINITY ethmonitor-eth0 ne 1 ++ + The ethmonitor works in 3 different modes to test the interface vitality. + 1. call ip to see if the link status is up (if link is down -> error) + 2. call ip and watch the RX counter (if packages come around in a certain time -> success) +@@ -157,14 +160,30 @@ Maximum number of IPs from ARP cache list to check for ARP REQUEST (arping) answ + + + ++ ++ ++For interfaces that are infiniband devices. ++ ++infiniband device ++ ++ ++ ++ ++ ++For infiniband devices, this is the port to monitor. ++ ++infiniband port ++ ++ ++ + + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + END +@@ -173,7 +192,7 @@ END + } + + # +-# Return true, if the interface exists ++# Return true, if the interface exists + # + is_interface() { + # +@@ -181,14 +200,25 @@ is_interface() { + # + local iface=`$IP2UTIL -o -f inet addr show | grep " $1 " \ + | cut -d ' ' -f2 | sort -u | grep -v '^ipsec[0-9][0-9]*$'` +- [ "$iface" != "" ] ++ [ "$iface" != "" ] ++} ++ ++infiniband_status() ++{ ++ local device="$OCF_RESKEY_infiniband_device" ++ ++ if [ -n "$OCF_RESKEY_infiniband_port" ]; then ++ device="${OCF_RESKEY_infiniband_device}:${OCF_RESKEY_infiniband_port}" ++ fi ++ ++ ibstatus ${device} | grep -q ACTIVE + } + + if_init() { + local rc + + if [ X"$OCF_RESKEY_interface" = "X" ]; then +- ocf_log err "Interface name (the interface parameter) is mandatory" ++ ocf_exit_reason "Interface name (the interface parameter) is mandatory" + exit $OCF_ERR_CONFIGURED + fi + +@@ -196,60 +226,67 @@ if_init() { + + if is_interface $NIC + then +- case "$NIC" in +- *:*) ocf_log err "Do not specify a virtual interface : $OCF_RESKEY_interface" +- exit $OCF_ERR_CONFIGURED;; +- *) ;; +- esac ++ case "$NIC" in ++ *:*) ocf_exit_reason "Do not specify a virtual interface : $OCF_RESKEY_interface" ++ exit $OCF_ERR_CONFIGURED;; ++ *) ;; ++ esac + else +- case $__OCF_ACTION in +- validate-all) ocf_log err "Interface $NIC does not exist" +- exit $OCF_ERR_CONFIGURED;; +- *) ocf_log warn "Interface $NIC does not exist" +- ## It might be a bond interface which is temporarily not available, therefore we want to continue here +- ;; +- esac ++ case $__OCF_ACTION in ++ validate-all) ++ ocf_exit_reason "Interface $NIC does not exist" ++ exit $OCF_ERR_CONFIGURED;; ++ *) ++ ## It might be a bond interface which is temporarily not available, therefore we want to continue here ++ ocf_log warn "Interface $NIC does not exist" ++ ;; ++ esac + fi + + : ${OCF_RESKEY_multiplier:="1"} + if ! ocf_is_decimal "$OCF_RESKEY_multiplier"; then +- ocf_log err "Invalid OCF_RESKEY_multiplier [$OCF_RESKEY_multiplier]" ++ ocf_exit_reason "Invalid OCF_RESKEY_multiplier [$OCF_RESKEY_multiplier]" + exit $OCF_ERR_CONFIGURED + fi + + ATTRNAME=${OCF_RESKEY_name:-"ethmonitor-$NIC"} + +- REP_COUNT=${OCF_RESKEY_repeat_count:-5} ++ REP_COUNT=${OCF_RESKEY_repeat_count:-5} + if ! ocf_is_decimal "$REP_COUNT" -o [ $REP_COUNT -lt 1 ]; then +- ocf_log err "Invalid OCF_RESKEY_repeat_count [$REP_COUNT]" ++ ocf_exit_reason "Invalid OCF_RESKEY_repeat_count [$REP_COUNT]" + exit $OCF_ERR_CONFIGURED +- fi ++ fi + REP_INTERVAL_S=${OCF_RESKEY_repeat_interval:-10} + if ! ocf_is_decimal "$REP_INTERVAL_S"; then +- ocf_log err "Invalid OCF_RESKEY_repeat_interval [$REP_INTERVAL_S]" ++ ocf_exit_reason "Invalid OCF_RESKEY_repeat_interval [$REP_INTERVAL_S]" + exit $OCF_ERR_CONFIGURED + fi + : ${OCF_RESKEY_pktcnt_timeout:="5"} + if ! ocf_is_decimal "$OCF_RESKEY_pktcnt_timeout"; then +- ocf_log err "Invalid OCF_RESKEY_pktcnt_timeout [$OCF_RESKEY_pktcnt_timeout]" ++ ocf_exit_reason "Invalid OCF_RESKEY_pktcnt_timeout [$OCF_RESKEY_pktcnt_timeout]" + exit $OCF_ERR_CONFIGURED + fi + : ${OCF_RESKEY_arping_count:="1"} + if ! ocf_is_decimal "$OCF_RESKEY_arping_count"; then +- ocf_log err "Invalid OCF_RESKEY_arping_count [$OCF_RESKEY_arping_count]" ++ ocf_exit_reason "Invalid OCF_RESKEY_arping_count [$OCF_RESKEY_arping_count]" + exit $OCF_ERR_CONFIGURED + fi + : ${OCF_RESKEY_arping_timeout:="1"} + if ! ocf_is_decimal "$OCF_RESKEY_arping_timeout"; then +- ocf_log err "Invalid OCF_RESKEY_arping_timeout [$OCF_RESKEY_arping_count]" ++ ocf_exit_reason "Invalid OCF_RESKEY_arping_timeout [$OCF_RESKEY_arping_count]" + exit $OCF_ERR_CONFIGURED + fi + : ${OCF_RESKEY_arping_cache_entries:="5"} + if ! ocf_is_decimal "$OCF_RESKEY_arping_cache_entries"; then +- ocf_log err "Invalid OCF_RESKEY_arping_cache_entries [$OCF_RESKEY_arping_cache_entries]" ++ ocf_exit_reason "Invalid OCF_RESKEY_arping_cache_entries [$OCF_RESKEY_arping_cache_entries]" + exit $OCF_ERR_CONFIGURED + fi +- return $OCF_SUCCESS ++ ++ if [ -n "$OCF_RESKEY_infiniband_device" ]; then ++ #ibstatus is required if an infiniband_device is provided ++ check_binary ibstatus ++ fi ++ return $OCF_SUCCESS + } + + # get the link status on $NIC +@@ -277,7 +314,7 @@ watch_pkt_counter () { + for n in `seq $(( $OCF_RESKEY_pktcnt_timeout * 10 ))`; do + sleep 0.1 + RX_PACKETS_NEW="`get_rx_packets`" +- ocf_log debug "RX_PACKETS_OLD: $RX_PACKETS_OLD RX_PACKETS_NEW: $RX_PACKETS_NEW" ++ ocf_log debug "RX_PACKETS_OLD: $RX_PACKETS_OLD RX_PACKETS_NEW: $RX_PACKETS_NEW" + if [ "$RX_PACKETS_OLD" -ne "$RX_PACKETS_NEW" ]; then + ocf_log debug "we received some packets." + return 0 +@@ -308,7 +345,7 @@ do_arping () { + } + + # +-# Check the interface depending on the level given as parameter: $OCF_RESKEY_check_level ++# Check the interface depending on the level given as parameter: $OCF_RESKEY_check_level + # + # 09: check for nonempty ARP cache + # 10: watch for packet counter changes +@@ -322,21 +359,47 @@ do_arping () { + # the tests for higher check levels are run. + # + if_check () { ++ local arp_list + # always check link status first + link_status="`get_link_status`" + ocf_log debug "link_status: $link_status (1=up, 0=down)" +- [ $link_status -eq 0 ] && return $OCF_NOT_RUNNING ++ ++ if [ $link_status -eq 0 ]; then ++ ocf_log notice "link_status: DOWN" ++ return $OCF_NOT_RUNNING ++ fi ++ ++ # if this is an infiniband device, try ibstatus script ++ if [ -n "$OCF_RESKEY_infiniband_device" ]; then ++ if infiniband_status; then ++ return $OCF_SUCCESS ++ fi ++ ocf_log info "Infiniband device $OCF_RESKEY_infiniband_device is not available, check ibstatus for more information" ++ return $OCF_NOT_RUNNING ++ fi + + # watch for packet counter changes +- ocf_log debug "watch for packet counter changes" +- watch_pkt_counter && return $OCF_SUCCESS ++ ocf_log debug "watch for packet counter changes" ++ watch_pkt_counter ++ if [ $? -eq 0 ]; then ++ return $OCF_SUCCESS ++ else ++ ocf_log debug "No packets received during packet watch timeout" ++ fi + + # check arping ARP cache entries +- ocf_log debug "check arping ARP cache entries" +- for ip in `get_arp_list`; do ++ ocf_log debug "check arping ARP cache entries" ++ arp_list=`get_arp_list` ++ for ip in `echo $arp_list`; do + do_arping $ip && return $OCF_SUCCESS + done + ++ # if we get here, the ethernet device is considered not running. ++ # provide some logging information ++ if [ -z "$arp_list" ]; then ++ ocf_log info "No ARP cache entries found to arping" ++ fi ++ + # watch for packet counter changes in promiscios mode + # ocf_log debug "watch for packet counter changes in promiscios mode" + # be sure switch off promiscios mode in any case +@@ -362,67 +425,89 @@ END + } + + set_cib_value() { +- local score=`expr $1 \* $OCF_RESKEY_multiplier` +- attrd_updater -n $ATTRNAME -v $score -q +- local rc=$? +- case $rc in +- 0) ocf_log debug "attrd_updater: Updated $ATTRNAME = $score" ;; +- *) ocf_log warn "attrd_updater: Could not update $ATTRNAME = $score: rc=$rc";; +- esac +- return $rc ++ local score=`expr $1 \* $OCF_RESKEY_multiplier` ++ attrd_updater -n $ATTRNAME -v $score -q ++ local rc=$? ++ case $rc in ++ 0) ocf_log debug "attrd_updater: Updated $ATTRNAME = $score" ;; ++ *) ocf_log warn "attrd_updater: Could not update $ATTRNAME = $score: rc=$rc";; ++ esac ++ return $rc + } + + if_monitor() { +- ha_pseudo_resource $OCF_RESOURCE_INSTANCE monitor +- local pseudo_status=$? +- if [ $pseudo_status -ne $OCF_SUCCESS ]; then +- exit $pseudo_status +- fi +- +- local mon_rc=$OCF_NOT_RUNNING +- local attr_rc=$OCF_NOT_RUNNING +- local runs=0 +- local start_time +- local end_time +- local sleep_time +- while [ $mon_rc -ne $OCF_SUCCESS -a $REP_COUNT -gt 0 ] +- do +- start_time=`date +%s%N` +- if_check +- mon_rc=$? +- REP_COUNT=$(( $REP_COUNT - 1 )) +- if [ $mon_rc -ne $OCF_SUCCESS -a $REP_COUNT -gt 0 ]; then +- ocf_log warn "Monitoring of $OCF_RESOURCE_INSTANCE failed, $REP_COUNT retries left." +- end_time=`date +%s%N` +- sleep_time=`echo "scale=9; ( $start_time + ( $REP_INTERVAL_S * 1000000000 ) - $end_time ) / 1000000000" | bc -q 2> /dev/null` +- sleep $sleep_time 2> /dev/null +- runs=$(($runs + 1)) +- fi +- +- if [ $mon_rc -eq $OCF_SUCCESS -a $runs -ne 0 ]; then +- ocf_log info "Monitoring of $OCF_RESOURCE_INSTANCE recovered from error" +- fi +- done +- +- ocf_log debug "Monitoring return code: $mon_rc" +- if [ $mon_rc -eq $OCF_SUCCESS ]; then +- set_cib_value 1 +- attr_rc=$? +- else +- ocf_log err "Monitoring of $OCF_RESOURCE_INSTANCE failed." +- set_cib_value 0 +- attr_rc=$? +- fi +- +- ## The resource should not fail, if the interface is down. It should fail, if the update of the CIB variable has errors. +- ## To react on the interface failure you must use constraints based on the CIB variable value, not on the resource itself. +- exit $attr_rc ++ ha_pseudo_resource $OCF_RESOURCE_INSTANCE monitor ++ local pseudo_status=$? ++ if [ $pseudo_status -ne $OCF_SUCCESS ]; then ++ exit $pseudo_status ++ fi ++ ++ local mon_rc=$OCF_NOT_RUNNING ++ local attr_rc=$OCF_NOT_RUNNING ++ local runs=0 ++ local start_time ++ local end_time ++ local sleep_time ++ while [ $mon_rc -ne $OCF_SUCCESS -a $REP_COUNT -gt 0 ] ++ do ++ start_time=`date +%s%N` ++ if_check ++ mon_rc=$? ++ REP_COUNT=$(( $REP_COUNT - 1 )) ++ if [ $mon_rc -ne $OCF_SUCCESS -a $REP_COUNT -gt 0 ]; then ++ ocf_log warn "Monitoring of $OCF_RESOURCE_INSTANCE failed, $REP_COUNT retries left." ++ end_time=`date +%s%N` ++ sleep_time=`echo "scale=9; ( $start_time + ( $REP_INTERVAL_S * 1000000000 ) - $end_time ) / 1000000000" | bc -q 2> /dev/null` ++ sleep $sleep_time 2> /dev/null ++ runs=$(($runs + 1)) ++ fi ++ ++ if [ $mon_rc -eq $OCF_SUCCESS -a $runs -ne 0 ]; then ++ ocf_log info "Monitoring of $OCF_RESOURCE_INSTANCE recovered from error" ++ fi ++ done ++ ++ ocf_log debug "Monitoring return code: $mon_rc" ++ if [ $mon_rc -eq $OCF_SUCCESS ]; then ++ set_cib_value 1 ++ attr_rc=$? ++ else ++ ocf_log err "Monitoring of $OCF_RESOURCE_INSTANCE failed." ++ set_cib_value 0 ++ attr_rc=$? ++ fi ++ ++ ## The resource should not fail, if the interface is down. It should fail, if the update of the CIB variable has errors. ++ ## To react on the interface failure you must use constraints based on the CIB variable value, not on the resource itself. ++ exit $attr_rc ++} ++ ++if_stop() ++{ ++ attrd_updater -D -n $ATTRNAME ++ ha_pseudo_resource $OCF_RESOURCE_INSTANCE stop + } + ++if_start() ++{ ++ local rc ++ ha_pseudo_resource $OCF_RESOURCE_INSTANCE start ++ rc=$? ++ if [ $rc -ne $OCF_SUCCESS ]; then ++ ocf_exit_reason "Failure to create ethmonitor state file" ++ return $rc ++ fi ++ ++ # perform the first monitor during the start operation ++ if_monitor ++ return $? ++} ++ ++ + if_validate() { +- check_binary $IP2UTIL +- check_binary arping +- if_init ++ check_binary $IP2UTIL ++ check_binary arping ++ if_init + } + + case $__OCF_ACTION in +@@ -436,18 +521,17 @@ esac + if_validate + + case $__OCF_ACTION in +-start) ha_pseudo_resource $OCF_RESOURCE_INSTANCE start ++start) if_start + exit $? + ;; +-stop) attrd_updater -D -n $ATTRNAME +- ha_pseudo_resource $OCF_RESOURCE_INSTANCE stop ++stop) if_stop + exit $? + ;; + monitor|status) if_monitor + exit $? + ;; + validate-all) exit $? +- ;; ++ ;; + *) if_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-Fix-ha_log-drop-global-__ha_log_ignore_stderr_once-h.patch b/SOURCES/bz1128933-Fix-ha_log-drop-global-__ha_log_ignore_stderr_once-h.patch new file mode 100644 index 0000000..04d0c9b --- /dev/null +++ b/SOURCES/bz1128933-Fix-ha_log-drop-global-__ha_log_ignore_stderr_once-h.patch @@ -0,0 +1,71 @@ +From 2364eff6a6837ae4418f1876f7f29459fdeec3bb Mon Sep 17 00:00:00 2001 +From: Lars Ellenberg +Date: Mon, 22 Sep 2014 15:26:59 +0200 +Subject: [PATCH 4/6] Fix: ha_log: drop global __ha_log_ignore_stderr_once hack + +Use a helper function instead, +which understands --ignore-stderr as first parameter. +--- + heartbeat/ocf-shellfuncs.in | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in +index c370fca..fd916e7 100644 +--- a/heartbeat/ocf-shellfuncs.in ++++ b/heartbeat/ocf-shellfuncs.in +@@ -43,14 +43,6 @@ unset LANGUAGE; export LANGUAGE + + __SCRIPT_NAME=`basename $0` + +-# This is internal to shellfuncs. +-# When set, ha_log can be used in a way that guarantees +-# that stderr will not be printed to. This allows us to +-# use ocf_exit_reason to print a string to stderr and use +-# ha_log to print the same string to the other log facilities +-# without having duplicate messages sent to stderr. +-__ha_log_ignore_stderr_once="" +- + if [ -z "$OCF_ROOT" ]; then + : ${OCF_ROOT=@OCF_ROOT_DIR@} + fi +@@ -189,12 +181,11 @@ set_logtag() { + fi + } + +-ha_log() { +- local ignore_stderr="$__ha_log_ignore_stderr_once" ++__ha_log() { ++ local ignore_stderr=false + local loglevel + +- # always reset this variable +- __ha_log_ignore_stderr_once="" ++ [ "x$1" = "x--ignore-stderr" ] && ignore_stderr=true && shift + + [ none = "$HA_LOGFACILITY" ] && HA_LOGFACILITY="" + # if we're connected to a tty, then output to stderr +@@ -257,6 +248,11 @@ ha_log() { + fi + } + ++ha_log() ++{ ++ __ha_log "$@" ++} ++ + ha_debug() { + + if [ "x${HA_debug}" = "x0" ] ; then +@@ -383,8 +379,7 @@ ocf_exit_reason() + + msg=$(printf "${fmt}" "$@") + printf >&2 "%s%s\n" "$cookie" "$msg" +- __ha_log_ignore_stderr_once="true" +- ha_log "ERROR: $msg" ++ __ha_log --ignore-stderr "ERROR: $msg" + } + + # +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-Fix-ocf_exit_reason-implicit-format-string-s-for-sin.patch b/SOURCES/bz1128933-Fix-ocf_exit_reason-implicit-format-string-s-for-sin.patch new file mode 100644 index 0000000..505e207 --- /dev/null +++ b/SOURCES/bz1128933-Fix-ocf_exit_reason-implicit-format-string-s-for-sin.patch @@ -0,0 +1,77 @@ +From de3c26d6333a00210de8d112cdb90dc8c2e19367 Mon Sep 17 00:00:00 2001 +From: Lars Ellenberg +Date: Mon, 22 Sep 2014 14:58:58 +0200 +Subject: [PATCH 3/6] Fix: ocf_exit_reason: implicit format string "%s" for + single argument version + +Also, don't use the $msg as format string, but via "%s%s" "$cookie" "$msg". +Or, depending on presence of % sequences in $msg, +you'd get different output on stderr and via ha_log. + +Without the patch: + + ( OCF_ROOT=$PWD dash -c '. heartbeat/ocf-shellfuncs.in ; ocf_exit_reason "0.x% Bugs less"' ) + dash: 372: printf: % B: invalid directive + ocf-exit-reason:0.x + ( OCF_ROOT=$PWD dash -c '. heartbeat/ocf-shellfuncs.in ; ocf_exit_reason "0.x% bugs less"' ) + ocf-exit-reason:0.xugs less + +With this patch: + + ( OCF_ROOT=$PWD dash -c '. heartbeat/ocf-shellfuncs.in ; ocf_exit_reason "0.x% Bugs less"' ) + ocf-exit-reason:0.x% Bugs less + ( OCF_ROOT=$PWD dash -c '. heartbeat/ocf-shellfuncs.in ; ocf_exit_reason "0.x% bugs less"' ) + ocf-exit-reason:0.x% bugs less +--- + heartbeat/ocf-shellfuncs.in | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in +index 9ba8e26..c370fca 100644 +--- a/heartbeat/ocf-shellfuncs.in ++++ b/heartbeat/ocf-shellfuncs.in +@@ -356,22 +356,33 @@ ocf_log() { + ocf_exit_reason() + { + local cookie="$OCF_EXIT_REASON_PREFIX" +- local fmt="$1" ++ local fmt + local msg + +- if [ $# -lt 1 ]; then +- ocf_log err "Not enough arguments [$#] to ocf_log_exit_msg." +- fi ++ # No argument is likely not intentional. ++ # Just one argument implies a printf format string of just "%s". ++ # "Least surprise" in case some interpolated string from variable ++ # expansion or other contains a percent sign. ++ # More than one argument: first argument is going to be the format string. ++ case $# in ++ 0) ocf_log err "Not enough arguments to ocf_log_exit_msg." ;; ++ 1) fmt="%s" ;; ++ ++ *) fmt=$1 ++ shift ++ case $fmt in ++ *%*) : ;; # ok, does look like a format string ++ *) ocf_log warn "Does not look like format string: [$fmt]" ;; ++ esac ;; ++ esac ++ + if [ -z "$cookie" ]; then + # use a default prefix + cookie="ocf-exit-reason:" + fi + +- shift +- + msg=$(printf "${fmt}" "$@") +- +- printf >&2 "%s${msg}\n" "$cookie" ++ printf >&2 "%s%s\n" "$cookie" "$msg" + __ha_log_ignore_stderr_once="true" + ha_log "ERROR: $msg" + } +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-Fix-shellfuncs-fix-syntax-error-caused-by-exit_reaso.patch b/SOURCES/bz1128933-Fix-shellfuncs-fix-syntax-error-caused-by-exit_reaso.patch new file mode 100644 index 0000000..10e37be --- /dev/null +++ b/SOURCES/bz1128933-Fix-shellfuncs-fix-syntax-error-caused-by-exit_reaso.patch @@ -0,0 +1,26 @@ +From da05792dae917d67b529a27b0605166774bb21b9 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Sun, 21 Sep 2014 11:19:07 -0400 +Subject: [PATCH 2/6] Fix: shellfuncs: fix syntax error caused by exit_reason + support for dash shell. + +--- + heartbeat/ocf-shellfuncs.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in +index ff7c32d..9ba8e26 100644 +--- a/heartbeat/ocf-shellfuncs.in ++++ b/heartbeat/ocf-shellfuncs.in +@@ -356,7 +356,7 @@ ocf_log() { + ocf_exit_reason() + { + local cookie="$OCF_EXIT_REASON_PREFIX" +- local fmt=$1 ++ local fmt="$1" + local msg + + if [ $# -lt 1 ]; then +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-IPaddr2-exit-reason-support.patch b/SOURCES/bz1128933-IPaddr2-exit-reason-support.patch new file mode 100644 index 0000000..fb27adf --- /dev/null +++ b/SOURCES/bz1128933-IPaddr2-exit-reason-support.patch @@ -0,0 +1,185 @@ +From a8adbaa0716f0fa39e41293fe81530686f64e2c8 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 1 Aug 2014 15:31:38 -0400 +Subject: [PATCH] High: IPaddr2: support ocf_exit_reason + +--- + heartbeat/IPaddr2 | 40 +++++++++++++++++++++------------------- + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2 +index b645288..2791ea0 100755 +--- a/heartbeat/IPaddr2 ++++ b/heartbeat/IPaddr2 +@@ -342,12 +342,12 @@ ip_init() { + local rc + + if [ X`uname -s` != "XLinux" ]; then +- ocf_log err "IPaddr2 only supported Linux." ++ ocf_exit_reason "IPaddr2 only supported Linux." + exit $OCF_ERR_INSTALLED + fi + + if [ X"$OCF_RESKEY_ip" = "X" ]; then +- ocf_log err "IP address (the ip parameter) is mandatory" ++ ocf_exit_reason "IP address (the ip parameter) is mandatory" + exit $OCF_ERR_CONFIGURED + fi + +@@ -359,7 +359,7 @@ ip_init() { + then + : YAY! + else +- ocf_log err "You must be root for $__OCF_ACTION operation." ++ ocf_exit_reason "You must be root for $__OCF_ACTION operation." + exit $OCF_ERR_PERM + fi + +@@ -382,14 +382,14 @@ ip_init() { + IP_INC_NO=`expr ${OCF_RESKEY_CRM_meta_clone:-0} + 1` + + if ocf_is_true ${OCF_RESKEY_lvs_support} && [ $IP_INC_GLOBAL -gt 1 ]; then +- ocf_log err "LVS and load sharing do not go together well" ++ ocf_exit_reason "LVS and load sharing do not go together well" + exit $OCF_ERR_CONFIGURED + fi + + if ocf_is_decimal "$IP_INC_GLOBAL" && [ $IP_INC_GLOBAL -gt 0 ]; then + : + else +- ocf_log err "Invalid OCF_RESKEY_incarnations_max_global [$IP_INC_GLOBAL], should be positive integer" ++ ocf_exit_reason "Invalid meta-attribute clone_max [$IP_INC_GLOBAL], should be positive integer" + exit $OCF_ERR_CONFIGURED + fi + +@@ -397,20 +397,20 @@ ip_init() { + if [ $? -ne 0 ];then + FAMILY=inet + if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then +- ocf_log err "IPv4 does not support lvs_ipv6_addrlabel" ++ ocf_exit_reason "IPv4 does not support lvs_ipv6_addrlabel" + exit $OCF_ERR_CONFIGURED + fi + else + FAMILY=inet6 + if ocf_is_true $OCF_RESKEY_lvs_support ;then +- ocf_log err "The IPv6 does not support lvs_support" ++ ocf_exit_reason "The IPv6 does not support lvs_support" + exit $OCF_ERR_CONFIGURED + fi + if ocf_is_true $OCF_RESKEY_lvs_ipv6_addrlabel ;then + if ocf_is_decimal "$OCF_RESKEY_lvs_ipv6_addrlabel_value" && [ $OCF_RESKEY_lvs_ipv6_addrlabel_value -ge 0 ]; then + : + else +- ocf_log err "Invalid lvs_ipv6_addrlabel_value [$OCF_RESKEY_lvs_ipv6_addrlabel_value], should be positive integer" ++ ocf_exit_reason "Invalid lvs_ipv6_addrlabel_value [$OCF_RESKEY_lvs_ipv6_addrlabel_value], should be positive integer" + exit $OCF_ERR_CONFIGURED + fi + fi +@@ -446,7 +446,7 @@ ip_init() { + ocf_log warn "[$FINDIF] failed" + exit $OCF_SUCCESS + else +- ocf_log err "[$FINDIF] failed" ++ ocf_exit_reason "[$FINDIF] failed" + exit $rc + fi + fi +@@ -769,7 +769,8 @@ END + } + + ip_start() { +- if [ -z "$NIC" ]; then # no nic found or specified ++ if [ -z "$NIC" ]; then ++ ocf_exit_reason "No nic found or specified" + exit $OCF_ERR_CONFIGURED + fi + +@@ -799,7 +800,7 @@ ip_start() { + --local-node $IP_INC_NO \ + --hashmode $IP_CIP_HASH + if [ $? -ne 0 ]; then +- ocf_log err "iptables failed" ++ ocf_exit_reason "iptables failed" + exit $OCF_ERR_GENERIC + fi + fi +@@ -822,7 +823,7 @@ ip_start() { + add_interface $OCF_RESKEY_ip $NETMASK ${BRDCAST:-none} $NIC $IFLABEL + + if [ $? -ne 0 ]; then +- ocf_log err "$CMD failed." ++ ocf_exit_reason "$CMD failed." + exit $OCF_ERR_GENERIC + fi + fi +@@ -897,6 +898,7 @@ ip_stop() { + if [ "$ip_del_if" = "yes" ]; then + delete_interface $OCF_RESKEY_ip $NIC $NETMASK + if [ $? -ne 0 ]; then ++ ocf_exit_reason "Unable to remove IP [${OCF_RESKEY_ip} from interface [ $NIC ]" + exit $OCF_ERR_GENERIC + fi + +@@ -940,7 +942,7 @@ set_send_arp_program() { + ARP_SEND_FUN=run_send_ib_arp + ;; + *) +- ocf_log err "unrecognized arp_sender value: $OCF_RESKEY_arp_sender" ++ ocf_exit_reason "unrecognized arp_sender value: $OCF_RESKEY_arp_sender" + exit $OCF_ERR_CONFIGURED + ;; + esac +@@ -975,21 +977,21 @@ ip_validate() { + + if ocf_is_true "$OCF_RESKEY_unique_clone_address" && + ! ocf_is_true "$OCF_RESKEY_CRM_meta_globally_unique"; then +- ocf_log err "unique_clone_address makes sense only with meta globally_unique set" ++ ocf_exit_reason "unique_clone_address makes sense only with meta globally_unique set" + exit $OCF_ERR_CONFIGURED + fi + + if ocf_is_decimal "$OCF_RESKEY_arp_interval" && [ $OCF_RESKEY_arp_interval -gt 0 ]; then + : + else +- ocf_log err "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]" ++ ocf_exit_reason "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]" + exit $OCF_ERR_CONFIGURED + fi + + if ocf_is_decimal "$OCF_RESKEY_arp_count" && [ $OCF_RESKEY_arp_count -gt 0 ]; then + : + else +- ocf_log err "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]" ++ ocf_exit_reason "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]" + exit $OCF_ERR_CONFIGURED + fi + +@@ -1001,13 +1003,13 @@ ip_validate() { + sourceip|sourceip-sourceport|sourceip-sourceport-destport) + ;; + *) +- ocf_log err "Invalid OCF_RESKEY_clusterip_hash [$IP_CIP_HASH]" ++ ocf_exit_reason "Invalid OCF_RESKEY_clusterip_hash [$IP_CIP_HASH]" + exit $OCF_ERR_CONFIGURED + ;; + esac + + if ocf_is_true ${OCF_RESKEY_lvs_support}; then +- ecf_log err "LVS and load sharing not advised to try" ++ ocf_exit_reason "LVS and load sharing not advised to try" + exit $OCF_ERR_CONFIGURED + fi + +@@ -1020,7 +1022,7 @@ ip_validate() { + esac + + if [ $valid -eq 0 ]; then +- ocf_log err "Invalid IF_MAC [$IF_MAC]" ++ ocf_exit_reason "Invalid IF_MAC [$IF_MAC]" + exit $OCF_ERR_CONFIGURED + fi + +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-VirtualDomain-exit-reason-support.patch b/SOURCES/bz1128933-VirtualDomain-exit-reason-support.patch new file mode 100644 index 0000000..dd92efb --- /dev/null +++ b/SOURCES/bz1128933-VirtualDomain-exit-reason-support.patch @@ -0,0 +1,102 @@ +From 0501ed8086e054d9b076719c5bd131edbc95db5b Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 1 Aug 2014 16:06:22 -0400 +Subject: [PATCH] High: VirtualDomain: exit reason support + +--- + heartbeat/VirtualDomain | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/heartbeat/VirtualDomain b/heartbeat/VirtualDomain +index 3a6b6a9..c44c090 100755 +--- a/heartbeat/VirtualDomain ++++ b/heartbeat/VirtualDomain +@@ -356,7 +356,7 @@ VirtualDomain_Start() { + rm -f $snapshotimage + return $OCF_SUCCESS + fi +- ocf_log error "Failed to restore ${DOMAIN_NAME} from state file in ${OCF_RESKEY_snapshot} directory." ++ ocf_exit_reason "Failed to restore ${DOMAIN_NAME} from state file in ${OCF_RESKEY_snapshot} directory." + return $OCF_ERR_GENERIC + fi + +@@ -371,7 +371,7 @@ VirtualDomain_Start() { + virsh $VIRSH_OPTIONS create ${OCF_RESKEY_config} + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log error "Failed to start virtual domain ${DOMAIN_NAME}." ++ ocf_exit_reason "Failed to start virtual domain ${DOMAIN_NAME}." + return $OCF_ERR_GENERIC + fi + +@@ -395,6 +395,7 @@ force_stop() + *"error:"*"domain is not running"*|*"error:"*"domain not found"*) + : ;; # unexpected path to the intended outcome, all is well + [!0]*) ++ ocf_exit_reason "forced stop failed" + return $OCF_ERR_GENERIC ;; + 0*) + while [ $status != $OCF_NOT_RUNNING ]; do +@@ -525,14 +526,14 @@ VirtualDomain_Migrate_To() { + virsh ${VIRSH_OPTIONS} migrate --live $DOMAIN_NAME ${remoteuri} ${migrateuri} + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log err "$DOMAIN_NAME: live migration to ${remoteuri} ${migrateuri} failed: $rc" ++ ocf_exit_reason "$DOMAIN_NAME: live migration to ${remoteuri} ${migrateuri} failed: $rc" + return $OCF_ERR_GENERIC + else + ocf_log info "$DOMAIN_NAME: live migration to ${target_node} succeeded." + return $OCF_SUCCESS + fi + else +- ocf_log err "$DOMAIN_NAME: migrate_to: Not active locally!" ++ ocf_exit_reason "$DOMAIN_NAME: migrate_to: Not active locally!" + return $OCF_ERR_GENERIC + fi + } +@@ -560,7 +561,7 @@ VirtualDomain_Monitor() { + # A monitor script returned a non-success exit + # code. Stop iterating over the list of scripts, log a + # warning message, and propagate $OCF_ERR_GENERIC. +- ocf_log warn "Monitor command \"${script}\" for domain ${DOMAIN_NAME} returned ${script_rc} with output: ${script_output}" ++ ocf_exit_reason "Monitor command \"${script}\" for domain ${DOMAIN_NAME} returned ${script_rc} with output: ${script_output}" + rc=$OCF_ERR_GENERIC + break + else +@@ -582,13 +583,13 @@ VirtualDomain_Validate_All() { + done + + if [ -z $OCF_RESKEY_config ]; then +- ocf_log error "Missing configuration parameter \"config\"." ++ ocf_exit_reason "Missing configuration parameter \"config\"." + return $OCF_ERR_CONFIGURED + fi + + if ocf_is_true $OCF_RESKEY_force_stop; then + if [ -n "$OCF_RESKEY_snapshot" ]; then +- ocf_log error "The 'force_stop' and 'snapshot' options can not be used together." ++ ocf_exit_reason "The 'force_stop' and 'snapshot' options can not be used together." + return $OCF_ERR_CONFIGURED + fi + fi +@@ -601,7 +602,7 @@ VirtualDomain_Validate_All() { + elif [ "$__OCF_ACTION" = "stop" ]; then + ocf_log info "Configuration file $OCF_RESKEY_config not readable, resource considered stopped." + else +- ocf_log error "Configuration file $OCF_RESKEY_config does not exist or is not readable." ++ ocf_exit_reason "Configuration file $OCF_RESKEY_config does not exist or is not readable." + return $OCF_ERR_INSTALLED + fi + fi +@@ -644,7 +645,7 @@ fi + # Retrieve the domain name from the xml file. + DOMAIN_NAME=`egrep '[[:space:]]*.*[[:space:]]*$' ${OCF_RESKEY_config} | sed -e 's/[[:space:]]*\(.*\)<\/name>[[:space:]]*$/\1/' 2>/dev/null` + if [ -z $DOMAIN_NAME ]; then +- ocf_log err "This is unexpected. Cannot determine domain name." ++ ocf_exit_reason "Unable to determine domain name." + exit $OCF_ERR_GENERIC + fi + +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-binary-check-exit-reason-support.patch b/SOURCES/bz1128933-binary-check-exit-reason-support.patch new file mode 100644 index 0000000..3a83c3b --- /dev/null +++ b/SOURCES/bz1128933-binary-check-exit-reason-support.patch @@ -0,0 +1,25 @@ +From 6029211e47a83cec4a6c4e44a967e967cb0b92fb Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 1 Aug 2014 13:13:05 -0400 +Subject: [PATCH] High: ocf-binaries: have 'check_binary' set exit reason + +--- + heartbeat/ocf-binaries.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/heartbeat/ocf-binaries.in b/heartbeat/ocf-binaries.in +index a78a348..cbf70db 100644 +--- a/heartbeat/ocf-binaries.in ++++ b/heartbeat/ocf-binaries.in +@@ -56,7 +56,7 @@ check_binary () { + if ! have_binary "$1"; then + if [ "$OCF_NOT_RUNNING" = 7 ]; then + # Chances are we have a fully setup OCF environment +- ocf_log err "Setup problem: couldn't find command: $1" ++ ocf_exit_reason "Setup problem: couldn't find command: $1" + else + echo "Setup problem: couldn't find command: $1" + fi +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-exit-reason-string-updates.patch b/SOURCES/bz1128933-exit-reason-string-updates.patch new file mode 100644 index 0000000..112adee --- /dev/null +++ b/SOURCES/bz1128933-exit-reason-string-updates.patch @@ -0,0 +1,2118 @@ +From 49546dca4dc4e19743d01576a954eac990c0cde1 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 25 Aug 2014 15:35:45 -0500 +Subject: [PATCH 4/4] exit reason string support for the following agents + +CTDB +Delay +Filesystem +IPsrcaddr +LVM +MailTo +Route +SendArp +Squid +Xinetd +apache +clvm +conntrackd +dhcpd +galera +mysql +mysql-common.sh +named +pgsql +postfix +rsyncd +slapd +symlink +tomcat +--- + heartbeat/CTDB | 24 ++++++++--------- + heartbeat/Delay | 2 +- + heartbeat/Filesystem | 32 +++++++++++----------- + heartbeat/IPsrcaddr | 14 +++++----- + heartbeat/LVM | 32 +++++++++++----------- + heartbeat/MailTo | 4 +-- + heartbeat/Route | 16 +++++------ + heartbeat/SendArp | 4 +-- + heartbeat/Squid | 14 +++++----- + heartbeat/Xinetd | 12 ++++----- + heartbeat/apache | 16 +++++------ + heartbeat/clvm | 14 +++++----- + heartbeat/conntrackd | 14 +++++----- + heartbeat/dhcpd | 24 ++++++++--------- + heartbeat/galera | 26 +++++++++--------- + heartbeat/mysql | 26 +++++++++--------- + heartbeat/mysql-common.sh | 16 +++++------ + heartbeat/named | 16 +++++------ + heartbeat/pgsql | 68 +++++++++++++++++++++++------------------------ + heartbeat/postfix | 22 +++++++-------- + heartbeat/rsyncd | 16 +++++------ + heartbeat/slapd | 24 ++++++++--------- + heartbeat/symlink | 12 ++++----- + heartbeat/tomcat | 16 +++++------ + 24 files changed, 232 insertions(+), 232 deletions(-) + mode change 100644 => 100755 heartbeat/clvm + mode change 100644 => 100755 heartbeat/galera + mode change 100644 => 100755 heartbeat/mysql-common.sh + +diff --git a/heartbeat/CTDB b/heartbeat/CTDB +index 18e6d0f..d1e8d03 100755 +--- a/heartbeat/CTDB ++++ b/heartbeat/CTDB +@@ -520,7 +520,7 @@ ctdb_start() { + mkdir -p $persistent_db_dir 2>/dev/null + for pdbase in $(ls $persistent_db_dir/*.tdb.[0-9] 2>/dev/null$) ; do + /usr/bin/tdbdump $pdbase >/dev/null 2>/dev/null || { +- ocf_log err "Persistent database $pdbase is corrupted! CTDB will not start." ++ ocf_exit_reason "Persistent database $pdbase is corrupted! CTDB will not start." + return $OCF_ERR_GENERIC + } + done +@@ -528,7 +528,7 @@ ctdb_start() { + # Add necessary configuration to smb.conf + init_smb_conf + if [ $? -ne 0 ]; then +- ocf_log err "Failed to update $OCF_RESKEY_smb_conf." ++ ocf_exit_reason "Failed to update $OCF_RESKEY_smb_conf." + return $OCF_ERR_GENERIC + fi + +@@ -563,7 +563,7 @@ ctdb_start() { + # cleanup smb.conf + cleanup_smb_conf + +- ocf_log err "Failed to execute $OCF_RESKEY_ctdbd_binary." ++ ocf_exit_reason "Failed to execute $OCF_RESKEY_ctdbd_binary." + return $OCF_ERR_GENERIC + else + # Wait a bit for CTDB to stabilize +@@ -577,7 +577,7 @@ ctdb_start() { + if [ $? -ne 0 ]; then + # CTDB will be running, kill it before returning + ctdb_stop +- ocf_log err "Can't invoke $OCF_RESKEY_ctdb_binary --socket=$OCF_RESKEY_ctdb_socket status" ++ ocf_exit_reason "Can't invoke $OCF_RESKEY_ctdb_binary --socket=$OCF_RESKEY_ctdb_socket status" + return $OCF_ERR_GENERIC + fi + if ! echo $status | grep -qs 'UNHEALTHY (THIS'; then +@@ -593,7 +593,7 @@ ctdb_start() { + # ctdbd will (or can) actually still be running at this point, so kill it + ctdb_stop + +- ocf_log err "Timeout waiting for CTDB to stabilize" ++ ocf_exit_reason "Timeout waiting for CTDB to stabilize" + return $OCF_ERR_GENERIC + } + +@@ -646,7 +646,7 @@ ctdb_monitor() { + if echo $status | grep -qs 'Connection refused'; then + return $OCF_NOT_RUNNING + else +- ocf_log err "CTDB status call failed: $status" ++ ocf_exit_reason "CTDB status call failed: $status" + return $OCF_ERR_GENERIC + fi + fi +@@ -654,7 +654,7 @@ ctdb_monitor() { + return $OCF_SUCCESS + fi + +- ocf_log err "CTDB status is bad: $status" ++ ocf_exit_reason "CTDB status is bad: $status" + return $OCF_ERR_GENERIC + } + +@@ -667,12 +667,12 @@ ctdb_validate() { + done + + if [ -z "$CTDB_SYSCONFIG" ]; then +- ocf_log err "Can't find CTDB config file (expecting /etc/sysconfig/ctdb, /etc/default/ctdb or similar)" ++ ocf_exit_reason "Can't find CTDB config file (expecting /etc/sysconfig/ctdb, /etc/default/ctdb or similar)" + return $OCF_ERR_INSTALLED + fi + + if ocf_is_true "$OCF_RESKEY_ctdb_manages_samba" && [ ! -f "$OCF_RESKEY_smb_conf" ]; then +- ocf_log err "Samba config file '$OCF_RESKEY_smb_conf' does not exist." ++ ocf_exit_reason "Samba config file '$OCF_RESKEY_smb_conf' does not exist." + return $OCF_ERR_INSTALLED + fi + +@@ -681,19 +681,19 @@ ctdb_validate() { + fi + + if [ ! -f "$OCF_RESKEY_ctdb_config_dir/nodes" ]; then +- ocf_log err "$OCF_RESKEY_ctdb_config_dir/nodes does not exist." ++ ocf_exit_reason "$OCF_RESKEY_ctdb_config_dir/nodes does not exist." + return $OCF_ERR_ARGS + fi + + if [ -z "$OCF_RESKEY_ctdb_recovery_lock" ]; then +- ocf_log err "ctdb_recovery_lock not specified." ++ ocf_exit_reason "ctdb_recovery_lock not specified." + return $OCF_ERR_CONFIGURED + fi + + lock_dir=$(dirname "$OCF_RESKEY_ctdb_recovery_lock") + touch "$lock_dir/$$" 2>/dev/null + if [ $? != 0 ]; then +- ocf_log err "Directory for lock file '$OCF_RESKEY_ctdb_recovery_lock' does not exist, or is not writable." ++ ocf_exit_reason "Directory for lock file '$OCF_RESKEY_ctdb_recovery_lock' does not exist, or is not writable." + return $OCF_ERR_ARGS + fi + rm "$lock_dir/$$" +diff --git a/heartbeat/Delay b/heartbeat/Delay +index f505391..9cfa939 100755 +--- a/heartbeat/Delay ++++ b/heartbeat/Delay +@@ -184,7 +184,7 @@ Delay_Validate_All() { + # _Return_ on validation success + return $OCF_SUCCESS + else +- echo "Some of the instance parameters are invalid" ++ ocf_exit_reason "Some of the instance parameters are invalid" + # _Exit_ on validation failure + exit $OCF_ERR_ARGS + fi +diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem +index 9892b39..3559c93 100755 +--- a/heartbeat/Filesystem ++++ b/heartbeat/Filesystem +@@ -480,7 +480,7 @@ fstype_supported() + # check the if the filesystem support exists again. + $MODPROBE $support >/dev/null + if [ $? -ne 0 ]; then +- ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems and failed to load kernal module" ++ ocf_exit_reason "Couldn't find filesystem $FSTYPE in /proc/filesystems and failed to load kernal module" + return $OCF_ERR_INSTALLED + fi + +@@ -497,7 +497,7 @@ fstype_supported() + sleep 1 + done + +- ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems" ++ ocf_exit_reason "Couldn't find filesystem $FSTYPE in /proc/filesystems" + return $OCF_ERR_INSTALLED + } + +@@ -532,7 +532,7 @@ Filesystem_start() + + if [ $blockdevice = "yes" ]; then + if [ "$DEVICE" != "/dev/null" -a ! -b "$DEVICE" ] ; then +- ocf_log err "Couldn't find device [$DEVICE]. Expected /dev/??? to exist" ++ ocf_exit_reason "Couldn't find device [$DEVICE]. Expected /dev/??? to exist" + exit $OCF_ERR_INSTALLED + fi + +@@ -547,7 +547,7 @@ Filesystem_start() + # NOTE: if any errors at all are detected, it returns non-zero + # if the error is >= 4 then there is a big problem + if [ $? -ge 4 ]; then +- ocf_log err "Couldn't sucessfully fsck filesystem for $DEVICE" ++ ocf_exit_reason "Couldn't sucessfully fsck filesystem for $DEVICE" + return $OCF_ERR_GENERIC + fi + fi +@@ -556,7 +556,7 @@ Filesystem_start() + [ -d "$MOUNTPOINT" ] || + ocf_run mkdir -p $MOUNTPOINT + if [ ! -d "$MOUNTPOINT" ] ; then +- ocf_log err "Couldn't find directory [$MOUNTPOINT] to use as a mount point" ++ ocf_exit_reason "Couldn't find directory [$MOUNTPOINT] to use as a mount point" + exit $OCF_ERR_INSTALLED + fi + +@@ -571,7 +571,7 @@ Filesystem_start() + esac + + if [ $? -ne 0 ]; then +- ocf_log err "Couldn't mount filesystem $DEVICE on $MOUNTPOINT" ++ ocf_exit_reason "Couldn't mount filesystem $DEVICE on $MOUNTPOINT" + if [ -n "$OCFS2_SLES10" ]; then + ocfs2_cleanup + fi +@@ -775,7 +775,7 @@ fs_stop() { + while [ $cnt -gt 0 ]; do + try_umount $SUB && + return $OCF_SUCCESS +- ocf_log err "Couldn't unmount $SUB; trying cleanup with $sig" ++ ocf_exit_reason "Couldn't unmount $SUB; trying cleanup with $sig" + signal_processes $SUB $sig + cnt=$((cnt-1)) + sleep 1 +@@ -826,7 +826,7 @@ Filesystem_stop() + fs_stop $SUB $timeout + rc=$? + if [ $rc -ne $OCF_SUCCESS ]; then +- ocf_log err "Couldn't unmount $SUB, giving up!" ++ ocf_exit_reason "Couldn't unmount $SUB, giving up!" + fi + done + fi +@@ -893,7 +893,7 @@ Filesystem_monitor_10() + dd_opts="iflag=direct bs=4k count=1" + err_output=`dd if=$DEVICE $dd_opts 2>&1 >/dev/null` + if [ $? -ne 0 ]; then +- ocf_log err "Failed to read device $DEVICE" ++ ocf_exit_reason "Failed to read device $DEVICE" + ocf_log err "dd said: $err_output" + return $OCF_ERR_GENERIC + fi +@@ -916,18 +916,18 @@ Filesystem_monitor_20() + [ -d "$status_dir" ] || mkdir -p "$status_dir" + err_output=`echo "${OCF_RESOURCE_INSTANCE}" | dd of=${STATUSFILE} $dd_opts 2>&1` + if [ $? -ne 0 ]; then +- ocf_log err "Failed to write status file ${STATUSFILE}" ++ ocf_exit_reason "Failed to write status file ${STATUSFILE}" + ocf_log err "dd said: $err_output" + return $OCF_ERR_GENERIC + fi + test -f ${STATUSFILE} + if [ $? -ne 0 ]; then +- ocf_log err "Cannot stat the status file ${STATUSFILE}" ++ ocf_exit_reason "Cannot stat the status file ${STATUSFILE}" + return $OCF_ERR_GENERIC + fi + cat ${STATUSFILE} > /dev/null + if [ $? -ne 0 ]; then +- ocf_log err "Cannot read the status file ${STATUSFILE}" ++ ocf_exit_reason "Cannot read the status file ${STATUSFILE}" + return $OCF_ERR_GENERIC + fi + return $OCF_SUCCESS +@@ -945,7 +945,7 @@ Filesystem_monitor() + 10) Filesystem_monitor_10; rc=$?;; + 20) Filesystem_monitor_20; rc=$?;; + *) +- ocf_log err "unsupported monitor level $OCF_CHECK_LEVEL" ++ ocf_exit_reason "unsupported monitor level $OCF_CHECK_LEVEL" + rc=$OCF_ERR_CONFIGURED + ;; + esac +@@ -1057,7 +1057,7 @@ case $OP in + esac + + if [ x = x"$DEVICE" ]; then +- ocf_log err "Please set OCF_RESKEY_device to the device to be managed" ++ ocf_exit_reason "Please set OCF_RESKEY_device to the device to be managed" + exit $OCF_ERR_CONFIGURED + fi + +@@ -1069,7 +1069,7 @@ set_blockdevice_var + # But the output of `mount` and /proc/mounts do not. + if [ -z "$OCF_RESKEY_directory" ]; then + if [ X$OP = "Xstart" -o $blockdevice = "no" ]; then +- ocf_log err "Please specify the directory" ++ ocf_exit_reason "Please specify the directory" + exit $OCF_ERR_CONFIGURED + fi + else +@@ -1136,7 +1136,7 @@ esac + if [ -n "$OCF_RESKEY_CRM_meta_clone" ]; then + case $CLUSTERSAFE in + 0) +- ocf_log err "DANGER! $FSTYPE on $DEVICE is NOT cluster-aware!" ++ ocf_exit_reason "DANGER! $FSTYPE on $DEVICE is NOT cluster-aware!" + ocf_log err "DO NOT RUN IT AS A CLONE!" + ocf_log err "Politely refusing to proceed to avoid data corruption." + exit $OCF_ERR_CONFIGURED +diff --git a/heartbeat/IPsrcaddr b/heartbeat/IPsrcaddr +index e8c0f77..8163c0c 100755 +--- a/heartbeat/IPsrcaddr ++++ b/heartbeat/IPsrcaddr +@@ -111,7 +111,7 @@ END + } + + errorexit() { +- ocf_log err "$*" ++ ocf_exit_reason "$*" + exit $OCF_ERR_GENERIC + } + +@@ -253,7 +253,7 @@ CheckIP() { + ( [ $1 -le 254 ] && [ $2 -le 254 ] && [ $3 -le 254 ] && [ $4 -le 254 ] ) + then + if [ $1 -eq 127 ]; then +- ocf_log err "IP address [$ip] is a loopback address, thus can not be preferred source address" ++ ocf_exit_reason "IP address [$ip] is a loopback address, thus can not be preferred source address" + exit $OCF_ERR_CONFIGURED + fi + else +@@ -368,7 +368,7 @@ ip_status() { + + case $IF in + lo*) +- ocf_log err "IP address [$BASEIP] is served by loopback, thus can not be preferred source address" ++ ocf_exit_reason "IP address [$BASEIP] is served by loopback, thus can not be preferred source address" + exit $OCF_ERR_CONFIGURED + ;; + *)return $OCF_SUCCESS;; +@@ -394,7 +394,7 @@ srca_validate_all() { + if CheckIP "$ipaddress"; then + : + else +- ocf_log err "Invalid IP address [$ipaddress]" ++ ocf_exit_reason "Invalid IP address [$ipaddress]" + exit $OCF_ERR_CONFIGURED + fi + +@@ -406,7 +406,7 @@ srca_validate_all() { + if ip_status "$ipaddress"; then + : + else +- ocf_log err "We are not serving [$ipaddress], hence can not make it a preferred source address" ++ ocf_exit_reason "We are not serving [$ipaddress], hence can not make it a preferred source address" + exit $OCF_ERR_INSTALLED + fi + } +@@ -434,7 +434,7 @@ if + [ -z "$OCF_RESKEY_ipaddress" ] + then + # usage +- ocf_log err "Please set OCF_RESKEY_ipaddress to the preferred source IP address!" ++ ocf_exit_reason "Please set OCF_RESKEY_ipaddress to the preferred source IP address!" + exit $OCF_ERR_CONFIGURED + fi + +@@ -447,7 +447,7 @@ fi + findif_out=`$FINDIF -C` + rc=$? + [ $rc -ne 0 ] && { +- ocf_log err "[$FINDIF -C] failed" ++ ocf_exit_reason "[$FINDIF -C] failed" + exit $rc + } + +diff --git a/heartbeat/LVM b/heartbeat/LVM +index 27cdfbd..58cbe83 100755 +--- a/heartbeat/LVM ++++ b/heartbeat/LVM +@@ -183,8 +183,8 @@ verify_tags_environment() + # guarantee our tag will be filtered on startup + ## + if ! lvm dumpconfig activation/volume_list; then +- ocf_log err "LVM: Improper setup detected" +- ocf_log err "The volume_list filter must be initialized in lvm.conf for exclusive activation without clvmd" ++ ocf_log err "LVM: Improper setup detected" ++ ocf_exit_reason "The volume_list filter must be initialized in lvm.conf for exclusive activation without clvmd" + return $OCF_ERR_GENERIC + fi + +@@ -195,7 +195,7 @@ verify_tags_environment() + ## + if lvm dumpconfig activation/volume_list | grep -e "\"@$OUR_TAG\"" -e "\"${OCF_RESKEY_volgrpname}\""; then + ocf_log err "LVM: Improper setup detected" +- ocf_log err "The volume_list in lvm.conf must not contain the cluster tag, \"$OUR_TAG\", or volume group, $OCF_RESKEY_volgrpname" ++ ocf_exit_reason "The volume_list in lvm.conf must not contain the cluster tag, \"$OUR_TAG\", or volume group, $OCF_RESKEY_volgrpname" + return $OCF_ERR_GENERIC + fi + +@@ -283,7 +283,7 @@ strip_tags() + done + + if [ ! -z `vgs -o tags --noheadings $OCF_RESKEY_volgrpname | tr -d ' '` ]; then +- ocf_log err "Failed to remove ownership tags from $OCF_RESKEY_volgrpname" ++ ocf_exit_reason "Failed to remove ownership tags from $OCF_RESKEY_volgrpname" + return $OCF_ERR_GENERIC + fi + +@@ -310,7 +310,7 @@ set_tags() + + vgchange --addtag $OUR_TAG $OCF_RESKEY_volgrpname + if [ $? -ne 0 ]; then +- ocf_log err "Failed to add ownership tag to $OCF_RESKEY_volgrpname" ++ ocf_exit_reason "Failed to add ownership tag to $OCF_RESKEY_volgrpname" + return $OCF_ERR_GENERIC + fi + +@@ -341,7 +341,7 @@ LVM_status() { + test "`cd /dev/$1 && ls`" != "" + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log err "VG $1 with no logical volumes is not supported by this RA!" ++ ocf_exit_reason "VG $1 with no logical volumes is not supported by this RA!" + fi + fi + +@@ -354,7 +354,7 @@ LVM_status() { + # If vg is running, make sure the correct tag is present. Otherwise we + # can not guarantee exclusive activation. + if ! check_tags; then +- ocf_log err "WARNING: $OCF_RESKEY_volgrpname is active without the cluster tag, \"$OUR_TAG\"" ++ ocf_exit_reason "WARNING: $OCF_RESKEY_volgrpname is active without the cluster tag, \"$OUR_TAG\"" + rc=$OCF_ERR_GENERIC + fi + +@@ -423,7 +423,7 @@ retry_exclusive_start() + return $OCF_ERR_GENERIC;; + *) + if ! lvchange -an $OCF_RESKEY_volgrpname/$1; then +- ocf_log err "Unable to perform required deactivation of $OCF_RESKEY_volgrpname/$1 before starting" ++ ocf_exit_reason "Unable to perform required deactivation of $OCF_RESKEY_volgrpname/$1 before starting" + return $OCF_ERR_GENERIC + fi + ;; +@@ -482,7 +482,7 @@ LVM_start() { + : OK Volume $vg activated just fine! + return $OCF_SUCCESS + else +- ocf_log err "LVM: $vg did not activate correctly" ++ ocf_exit_reason "LVM: $vg did not activate correctly" + return $OCF_NOT_RUNNING + fi + } +@@ -511,7 +511,7 @@ LVM_stop() { + ocf_run vgchange $vgchange_options $vg + res=$? + if LVM_status $vg; then +- ocf_log err "LVM: $vg did not stop correctly" ++ ocf_exit_reason "LVM: $vg did not stop correctly" + res=1 + fi + +@@ -568,7 +568,7 @@ LVM_validate_all() { + ## + VGOUT=`vgck ${VOLUME} 2>&1` + if [ $? -ne 0 ]; then +- ocf_log err "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" ++ ocf_exit_reason "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" + exit $OCF_ERR_GENERIC + fi + +@@ -581,7 +581,7 @@ LVM_validate_all() { + VGOUT=`vgdisplay -v ${VOLUME} 2>&1` + fi + if [ $? -ne 0 ]; then +- ocf_log err "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" ++ ocf_exit_reason "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" + exit $OCF_ERR_GENERIC + fi + +@@ -597,7 +597,7 @@ LVM_validate_all() { + # Having cloned lvm resources with exclusive vg activation makes no sense at all. + ## + if ocf_is_clone; then +- ocf_log_err "cloned lvm resources can not be activated exclusively" ++ ocf_exit_reason "cloned lvm resources can not be activated exclusively" + exit $OCF_ERR_CONFIGURED + fi + +@@ -616,7 +616,7 @@ LVM_validate_all() { + # verify is clvmd running + ## + if ! ps -C clvmd > /dev/null 2>&1; then +- ocf_log err "$OCF_RESKEY_volgrpname has the cluster attribute set, but 'clvmd' is not running" ++ ocf_exit_reason "$OCF_RESKEY_volgrpname has the cluster attribute set, but 'clvmd' is not running" + exit $OCF_ERR_GENERIC + fi + ;; +@@ -653,7 +653,7 @@ esac + if + [ -z "$OCF_RESKEY_volgrpname" ] + then +- ocf_log err "You must identify the volume group name!" ++ ocf_exit_reason "You must identify the volume group name!" + exit $OCF_ERR_CONFIGURED + fi + +@@ -680,7 +680,7 @@ rc=$? + if + ( [ $rc -ne 0 ] || [ -z "$LVM_VERSION" ] ) + then +- ocf_log err "LVM: $1 could not determine LVM version. Try 'vgchange --version' manually and modify $0 ?" ++ ocf_exit_reason "LVM: $1 could not determine LVM version. Try 'vgchange --version' manually and modify $0 ?" + exit $OCF_ERR_INSTALLED + fi + LVM_MAJOR="${LVM_VERSION%%.*}" +diff --git a/heartbeat/MailTo b/heartbeat/MailTo +index acf6730..3936c39 100755 +--- a/heartbeat/MailTo ++++ b/heartbeat/MailTo +@@ -131,7 +131,7 @@ MailToStatus () { + + MailToValidateAll () { + if [ -z "$MAILCMD" ]; then +- ocf_log err "MAILCMD not set: complain to the packager" ++ ocf_exit_reason "MAILCMD not set: complain to the packager" + exit $OCF_ERR_INSTALLED + fi + check_binary "$MAILCMD" +@@ -169,7 +169,7 @@ esac + if + [ -z "$OCF_RESKEY_email" ] + then +- ocf_log err "At least 1 Email address has to be given!" ++ ocf_exit_reason "At least 1 Email address has to be given!" + exit $OCF_ERR_CONFIGURED + fi + +diff --git a/heartbeat/Route b/heartbeat/Route +index 9a49a26..cfed2b0 100755 +--- a/heartbeat/Route ++++ b/heartbeat/Route +@@ -174,7 +174,7 @@ route_start() { + ocf_log info "${OCF_RESOURCE_INSTANCE} Added network route: $route_spec" + return $OCF_SUCCESS + else +- ocf_log error "${OCF_RESOURCE_INSTANCE} Failed to add network route: $route_spec" ++ ocf_exit_reason "${OCF_RESOURCE_INSTANCE} Failed to add network route: $route_spec" + fi + return $OCF_ERR_GENERIC + } +@@ -189,7 +189,7 @@ route_stop() { + ocf_log info "${OCF_RESOURCE_INSTANCE} Removed network route: $route_spec" + return $OCF_SUCCESS + else +- ocf_log error "${OCF_RESOURCE_INSTANCE} Failed to remove network route: $route_spec" ++ ocf_exit_reason "${OCF_RESOURCE_INSTANCE} Failed to remove network route: $route_spec" + fi + ;; + $OCF_NOT_RUNNING) +@@ -224,24 +224,24 @@ route_validate() { + # If we're running as a clone, are the clone meta attrs OK? + if [ "${OCF_RESKEY_CRM_meta_clone}" ]; then + if [ "${OCF_RESKEY_CRM_meta_clone_node_max}" != 1 ]; then +- ocf_log error "Misconfigured clone parameters. Must set meta attribute \"clone_node_max\" to 1, got ${OCF_RESKEY_CRM_meta_clone_node_max}." ++ ocf_exit_reason "Misconfigured clone parameters. Must set meta attribute \"clone_node_max\" to 1, got ${OCF_RESKEY_CRM_meta_clone_node_max}." + return $OCF_ERR_ARGS + fi + fi + # Did we get a destination? + if [ -z "${OCF_RESKEY_destination}" ]; then +- ocf_log error "Missing required parameter \"destination\"." ++ ocf_exit_reason "Missing required parameter \"destination\"." + return $OCF_ERR_ARGS + fi + # Did we get either a device or a gateway address? + if [ -z "${OCF_RESKEY_device}" -a -z "${OCF_RESKEY_gateway}" ]; then +- ocf_log error "Must specifiy either \"device\", or \"gateway\", or both." ++ ocf_exit_reason "Must specifiy either \"device\", or \"gateway\", or both." + return $OCF_ERR_ARGS + fi + # If a device has been configured, is it available on this system? + if [ -n "${OCF_RESKEY_device}" ]; then + if ! ip link show ${OCF_RESKEY_device} >/dev/null 2>&1; then +- ocf_log error "Network device ${OCF_RESKEY_device} appears not to be available on this system." ++ ocf_exit_reason "Network device ${OCF_RESKEY_device} appears not to be available on this system." + # OCF_ERR_ARGS prevents the resource from running anywhere at all, + # maybe another node has the interface? + # OCF_ERR_INSTALLED just prevents starting on this particular node. +@@ -256,7 +256,7 @@ route_validate() { + # this system? + if [ -n "${OCF_RESKEY_source}" ]; then + if ! ip address show | grep -w ${OCF_RESKEY_source} >/dev/null 2>&1; then +- ocf_log error "Source address ${OCF_RESKEY_source} appears not to be available on this system." ++ ocf_exit_reason "Source address ${OCF_RESKEY_source} appears not to be available on this system." + # same reason as with _device: + return $OCF_ERR_INSTALLED + fi +@@ -264,7 +264,7 @@ route_validate() { + # If a gateway address has been configured, is it reachable? + if [ -n "${OCF_RESKEY_gateway}" ]; then + if ! ip route get ${OCF_RESKEY_gateway} >/dev/null 2>&1; then +- ocf_log error "Gateway address ${OCF_RESKEY_gateway} is unreachable." ++ ocf_exit_reason "Gateway address ${OCF_RESKEY_gateway} is unreachable." + # same reason as with _device: + return $OCF_ERR_INSTALLED + fi +diff --git a/heartbeat/SendArp b/heartbeat/SendArp +index 675070c..b67404f 100755 +--- a/heartbeat/SendArp ++++ b/heartbeat/SendArp +@@ -166,10 +166,10 @@ sendarp_start() { + # and wait-ing would be equal to not running in + # background + ($SENDARP $ARGS || +- ocf_log err "Could not send gratuitous arps") & ++ ocf_exit_reason "Could not send gratuitous arps") & + else + $SENDARP $ARGS || { +- ocf_log err "Could not send gratuitous arps" ++ ocf_exit_reason "Could not send gratuitous arps" + rc=$OCF_ERR_GENERIC + } + fi +diff --git a/heartbeat/Squid b/heartbeat/Squid +index 28e2db5..70c7c3d 100755 +--- a/heartbeat/Squid ++++ b/heartbeat/Squid +@@ -216,7 +216,7 @@ are_pids_sane() + if [[ "${SQUID_PIDS[1]}" = "${SQUID_PIDS[2]}" ]]; then + return $OCF_SUCCESS + else +- ocf_log err "$SQUID_NAME:Pid unmatch" ++ ocf_exit_reason "$SQUID_NAME:Pid unmatch" + return $OCF_ERR_GENERIC + fi + } +@@ -253,7 +253,7 @@ monitor_squid() + "${SQUID_PIDS[0]},${SQUID_PIDS[1]},${SQUID_PIDS[2]}" + (( trialcount = trialcount + 1 )) + if (( trialcount > SQUID_CONFIRM_TRIALCOUNT )); then +- ocf_log err "$SQUID_NAME:Inconsistency of processes remains unsolved" ++ ocf_exit_reason "$SQUID_NAME:Inconsistency of processes remains unsolved" + return $OCF_ERR_GENERIC + fi + sleep 1 +@@ -348,7 +348,7 @@ fi + + SQUID_CONF="${OCF_RESKEY_squid_conf}" + if [[ -z "$SQUID_CONF" ]]; then +- ocf_log err "SQUID_CONF is not defined" ++ ocf_exit_reason "SQUID_CONF is not defined" + exit $OCF_ERR_CONFIGURED + fi + +@@ -374,23 +374,23 @@ fi + + SQUID_EXE="${OCF_RESKEY_squid_exe}" + if [[ -z "$SQUID_EXE" ]]; then +- ocf_log err "SQUID_EXE is not defined" ++ ocf_exit_reason "SQUID_EXE is not defined" + exit $OCF_ERR_CONFIGURED + fi + if [[ ! -x "$SQUID_EXE" ]]; then +- ocf_log err "$SQUID_EXE is not found" ++ ocf_exit_reason "$SQUID_EXE is not found" + exit $OCF_ERR_CONFIGURED + fi + + SQUID_PIDFILE="${OCF_RESKEY_squid_pidfile}" + if [[ -z "$SQUID_PIDFILE" ]]; then +- ocf_log err "SQUID_PIDFILE is not defined" ++ ocf_exit_reason "SQUID_PIDFILE is not defined" + exit $OCF_ERR_CONFIGURED + fi + + SQUID_PORT="${OCF_RESKEY_squid_port}" + if [[ -z "$SQUID_PORT" ]]; then +- ocf_log err "SQUID_PORT is not defined" ++ ocf_exit_reason "SQUID_PORT is not defined" + exit $OCF_ERR_CONFIGURED + fi + +diff --git a/heartbeat/Xinetd b/heartbeat/Xinetd +index ee2c4fa..212648e 100755 +--- a/heartbeat/Xinetd ++++ b/heartbeat/Xinetd +@@ -89,11 +89,11 @@ hup_inetd () { + if kill -s HUP $pid; then + ocf_log info "asked xinetd to reload by sending SIGHUP to process $pid!" + else +- ocf_log err "could not send SIGHUP to process $pid!" ++ ocf_exit_reason "could not send SIGHUP to process $pid!" + exit $OCF_ERR_GENERIC + fi + else +- ocf_log err "xinetd process not found!" ++ ocf_exit_reason "xinetd process not found!" + exit $OCF_ERR_GENERIC + fi + } +@@ -161,7 +161,7 @@ xup_usage () { + + xup_validate_all () { + if [ ! -f "$SVCDEF" ]; then +- ocf_log err "service $service missing $SVCDEF" ++ ocf_exit_reason "service $service missing $SVCDEF" + return $OCF_ERR_INSTALLED + fi + return $OCF_SUCCESS +@@ -185,7 +185,7 @@ case "$1" in + esac + + if [ -z "$OCF_RESKEY_service" ]; then +- ocf_log err "please define \"service\" parameter" ++ ocf_exit_reason "please define \"service\" parameter" + if [ "$1" = "start" ]; then + exit $OCF_ERR_CONFIGURED + else +@@ -195,7 +195,7 @@ fi + + # Is xinetd running at all + if [ -z "`get_xinetd_pid`" ]; then +- ocf_log err "xinetd not running, we manage just xinetd services, not the daemon itself" ++ ocf_exit_reason "xinetd not running, we manage just xinetd services, not the daemon itself" + case "$1" in + stop) exit $OCF_SUCCESS;; + start|monitor|status) exit $OCF_ERR_INSTALLED;; +@@ -204,7 +204,7 @@ fi + + # Make sure the OCF_RESKEY_service is a valid xinetd service name + if [ ! -f $SVCDEF ]; then +- ocf_log err "service definition $SVCDEF not found!" ++ ocf_exit_reason "service definition $SVCDEF not found!" + if [ "$1" = "start" ]; then + exit $OCF_ERR_INSTALLED + else +diff --git a/heartbeat/apache b/heartbeat/apache +index bee2f97..e7d570f 100755 +--- a/heartbeat/apache ++++ b/heartbeat/apache +@@ -272,7 +272,7 @@ apache_stop() { + kill_stop $ApachePID + + if ProcessRunning $ApachePID; then +- ocf_log info "$CMD still running ($ApachePID). Killing pid failed." ++ ocf_exit_reason "$CMD still running ($ApachePID). Killing pid failed." + ret=$OCF_ERR_GENERIC + fi + fi +@@ -303,7 +303,7 @@ apache_monitor_10() { + return $OCF_SUCCESS + else + if ! ocf_is_probe; then +- ocf_log err "Failed to access httpd status page." ++ ocf_exit_reason "Failed to access httpd status page." + fi + return $OCF_ERR_GENERIC + fi +@@ -359,7 +359,7 @@ apache_monitor_basic() { + fi + + if ! ocf_is_probe; then +- ocf_log err "Failed to access httpd status page." ++ ocf_exit_reason "Failed to access httpd status page." + fi + return $OCF_ERR_GENERIC + } +@@ -372,7 +372,7 @@ apache_monitor() { + + ourhttpclient=`findhttpclient` # we'll need one + if [ -z "$ourhttpclient" ]; then +- ocf_log err "could not find a http client; make sure that either wget or curl is available" ++ ocf_exit_reason "could not find a http client; make sure that either wget or curl is available" + return $OCF_ERR_INSTALLED + fi + +@@ -574,25 +574,25 @@ apache_validate_all() { + # We are sure to succeed here, since we forced $PORT to be valid in GetParams() + : OK + else +- ocf_log err "Port number $PORT is invalid!" ++ ocf_exit_reason "Port number $PORT is invalid!" + return $OCF_ERR_INSTALLED + fi + + case $STATUSURL in + http://*) ;; + *) +- ocf_log err "Invalid STATUSURL $STATUSURL" ++ ocf_exit_reason "Invalid STATUSURL $STATUSURL" + return $OCF_ERR_CONFIGURED ;; + esac + + if [ ! -x $HTTPD ]; then +- ocf_log err "HTTPD $HTTPD not found or is not an executable!" ++ ocf_exit_reason "HTTPD $HTTPD not found or is not an executable!" + return $OCF_ERR_INSTALLED + fi + + if [ ! -f $CONFIGFILE ]; then + # We are sure to succeed here, since we have parsed $CONFIGFILE before getting here +- ocf_log err "Configuration file $CONFIGFILE not found!" ++ ocf_exit_reason "Configuration file $CONFIGFILE not found!" + return $OCF_ERR_INSTALLED + fi + +diff --git a/heartbeat/clvm b/heartbeat/clvm +old mode 100644 +new mode 100755 +index 20bb40c..bb2b61c +--- a/heartbeat/clvm ++++ b/heartbeat/clvm +@@ -160,7 +160,7 @@ check_process() + return $OCF_NOT_RUNNING;; + *) + rm -f "$pidfile" > /dev/null 2>&1 +- ocf_log err "Error encountered detecting pid status of $binary" ++ ocf_exit_reason "Error encountered detecting pid status of $binary" + return $OCF_ERR_GENERIC;; + esac + } +@@ -171,7 +171,7 @@ clvmd_status() + local mirror_rc + clvmd_validate + if [ $? -ne $OCF_SUCCESS ]; then +- ocf_log error "Unable to monitor, Environment validation failed." ++ ocf_exit_reason "Unable to monitor, Environment validation failed." + return $? + fi + +@@ -251,7 +251,7 @@ clvmd_stop() + ocf_log info "Deactivating clustered VG(s):" + ocf_run ${LVM_VGCHANGE} -anl $LVM_VGS + if [ $? -ne 0 ]; then +- ocf_log error "Failed to deactivate volume groups, cluster vglist = $LVM_VGS" ++ ocf_exit_reason "Failed to deactivate volume groups, cluster vglist = $LVM_VGS" + return $OCF_ERR_GENERIC + fi + fi +@@ -259,14 +259,14 @@ clvmd_stop() + ocf_log info "Signaling $DAEMON to exit" + killall -TERM $DAEMON + if [ $? != 0 ]; then +- ocf_log error "Failed to signal -TERM to $DAEMON" ++ ocf_exit_reason "Failed to signal -TERM to $DAEMON" + return $OCF_ERR_GENERIC + fi + + wait_for_process $DAEMON $CLVMD_TIMEOUT + rc=$? + if [ $rc -ne $OCF_SUCCESS ]; then +- ocf_log error "$DAEMON failed to exit" ++ ocf_exit_reason "$DAEMON failed to exit" + return $rc + fi + +@@ -304,7 +304,7 @@ start_process() + ocf_run $binary_path $opts + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log error "Failed to launch $binary_path, exit code $rc" ++ ocf_exit_reason "Failed to launch $binary_path, exit code $rc" + exit $OCF_ERR_GENERIC + fi + fi +@@ -332,7 +332,7 @@ clvmd_start() + + clvmd_validate + if [ $? -ne $OCF_SUCCESS ]; then +- ocf_log error "Unable to start, Environment validation failed." ++ ocf_exit_reason "Unable to start, Environment validation failed." + return $? + fi + +diff --git a/heartbeat/conntrackd b/heartbeat/conntrackd +index 32eab6b..84ea360 100755 +--- a/heartbeat/conntrackd ++++ b/heartbeat/conntrackd +@@ -98,7 +98,7 @@ meta_expect() + # [, not [[, or it won't work ;) + [ $val $op $expect ] && return + fi +- ocf_log err "meta parameter misconfigured, expected $what $op $expect, but found ${val:-unset}." ++ ocf_exit_reason "meta parameter misconfigured, expected $what $op $expect, but found ${val:-unset}." + exit $OCF_ERR_CONFIGURED + } + +@@ -123,7 +123,7 @@ conntrackd_monitor() { + # now see if it acceppts queries + if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -s > /dev/null 2>&1; then + rc=$OCF_ERR_GENERIC +- ocf_log err "conntrackd is running but not responding to queries" ++ ocf_exit_reason "conntrackd is running but not responding to queries" + fi + if conntrackd_is_master; then + rc=$OCF_RUNNING_MASTER +@@ -154,7 +154,7 @@ conntrackd_start() { + conntrackd_set_master_score $slave_score + # -n = request resync from the others + if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -n; then +- ocf_log err "$OCF_RESKEY_binary -C $OCF_RESKEY_config -n failed during start." ++ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -n failed during start." + rc=$OCF_ERR_GENERIC + else + rc=$OCF_SUCCESS +@@ -170,7 +170,7 @@ conntrackd_start() { + ha_pseudo_resource $statefile stop + ;; + $OCF_ERR_GENERIC) +- ocf_log err "conntrackd start failed" ++ ocf_exit_reason "conntrackd start failed" + rc=$OCF_ERR_GENERIC + break + ;; +@@ -208,7 +208,7 @@ conntrackd_stop() { + conntrackd_validate_all() { + check_binary "$OCF_RESKEY_binary" + if ! [ -e "$OCF_RESKEY_config" ]; then +- ocf_log err "Config FILE $OCF_RESKEY_config does not exist" ++ ocf_exit_reason "Config FILE $OCF_RESKEY_config does not exist" + return $OCF_ERR_INSTALLED + fi + meta_expect master-node-max = 1 +@@ -227,7 +227,7 @@ conntrackd_promote() { + # -B = send a bulk update on the line + for parm in c f R B; do + if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm; then +- ocf_log err "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during promote." ++ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during promote." + rc=$OCF_ERR_GENERIC + break + fi +@@ -245,7 +245,7 @@ conntrackd_demote() { + # -n = request a resync from the others + for parm in t n; do + if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm; then +- ocf_log err "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during demote." ++ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during demote." + rc=$OCF_ERR_GENERIC + break + fi +diff --git a/heartbeat/dhcpd b/heartbeat/dhcpd +index 835a788..67b529e 100755 +--- a/heartbeat/dhcpd ++++ b/heartbeat/dhcpd +@@ -189,17 +189,17 @@ dhcpd_validate_all() { + # chroot mode is enabled. + if ocf_is_true $OCF_RESKEY_chrooted ; then + if ! test -e "$OCF_RESKEY_chrooted_path"; then +- ocf_log err "Path $OCF_RESKEY_chrooted_path does not exist." ++ ocf_exit_reason "Path $OCF_RESKEY_chrooted_path does not exist." + return $OCF_ERR_INSTALLED + fi + + if test -n "$OCF_RESKEY_chrooted_path/$OCF_RESKEY_config" -a ! -r "$OCF_RESKEY_chrooted_path/$OCF_RESKEY_config"; then +- ocf_log err "Configuration file $OCF_RESKEY_chrooted_path/$OCF_RESKEY_config doesn't exist" ++ ocf_exit_reason "Configuration file $OCF_RESKEY_chrooted_path/$OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + else + if test -n "$OCF_RESKEY_config" -a ! -r "$OCF_RESKEY_config"; then +- ocf_log err "Configuration file $OCF_RESKEY_config doesn't exist" ++ ocf_exit_reason "Configuration file $OCF_RESKEY_config doesn't exist" + return $OCF_ERR_INSTALLED + fi + fi +@@ -207,7 +207,7 @@ dhcpd_validate_all() { + fi + + if ! getent passwd $OCF_RESKEY_user >/dev/null 2>&1; then +- ocf_log err "User $OCF_RESKEY_user doesn't exist" ++ ocf_exit_reason "User $OCF_RESKEY_user doesn't exist" + return $OCF_ERR_INSTALLED + fi + +@@ -264,7 +264,7 @@ dhcpd_initialize_chroot() { + ## If there is no conf file, we can't initialize the chrooted + ## environment, return with "program not configured" + if ! [ -f $OCF_RESKEY_config ] ; then +- ocf_log err "dhcpd has not been configured." ++ ocf_exit_reason "dhcpd has not been configured." + return $OCF_ERR_CONFIGURED + fi + +@@ -283,7 +283,7 @@ dhcpd_initialize_chroot() { + if [ -e $i ] ; then + DEFAULT_FILE_LIST="$DEFAULT_FILE_LIST $i" + else +- ocf_log err "include file $i does not exist" ++ ocf_exit_reason "include file $i does not exist" + return $OCF_ERR_INSTALLED + fi + done +@@ -299,7 +299,7 @@ dhcpd_initialize_chroot() { + + # Next, we copy the configuration file into place. + cp -aL "$i" "$OCF_RESKEY_chrooted_path/${i%/*}/" > /dev/null 2>&1 || +- { ocf_log err "could not copy $i to chroot jail"; return $OCF_ERR_GENERIC; } ++ { ocf_exit_reason "could not copy $i to chroot jail"; return $OCF_ERR_GENERIC; } + done + + libdir=$(basename $(echo /var/lib/dhcp/lib*)) +@@ -328,7 +328,7 @@ dhcpd_initialize_chroot() { + for i in $cplibs ; do + if [ -s "$i" ]; then + cp -pL "$i" "/var/lib/dhcp/$libdir/" || +- { ocf_log err "could not copy $i to chroot jail"; return $OCF_ERR_GENERIC; } ++ { ocf_exit_reason "could not copy $i to chroot jail"; return $OCF_ERR_GENERIC; } + fi + done + +@@ -339,7 +339,7 @@ dhcpd_initialize_chroot() { + dhcpd_initialize() { + ## If there is no conf file, we can't start a dhcp service. + if ! [ -f $OCF_RESKEY_config ] ; then +- ocf_log err "dhcpd has not been configured." ++ ocf_exit_reason "dhcpd has not been configured." + return $OCF_ERR_CONFIGURED + fi + +@@ -392,10 +392,10 @@ dhcpd_start() { + # Only initialize the chrooted path(s) if chroot mode is enabled. + if ocf_is_true $OCF_RESKEY_chrooted ; then + dhcpd_initialize_chroot || +- { ocf_log err "Could not fully initialize the chroot environment." ; return $OCF_ERR_INSTALLED; } ++ { ocf_exit_reason "Could not fully initialize the chroot environment." ; return $OCF_ERR_INSTALLED; } + else + dhcpd_initialize || +- { ocf_log err "Could not fully initialize the runtime environment." ; return $OCF_ERR_INSTALLED; } ++ { ocf_exit_reason "Could not fully initialize the runtime environment." ; return $OCF_ERR_INSTALLED; } + fi + + dhcpd_validate_all || exit +@@ -501,7 +501,7 @@ dhcpd_stop () { + + #If still up + if dhcpd_monitor 2>&1; then +- ocf_log err "dhcpd is still up! Trying kill -s KILL" ++ ocf_log notice "dhcpd is still up! Trying kill -s KILL" + + kill -s SIGKILL `cat $PIDF` + fi +diff --git a/heartbeat/galera b/heartbeat/galera +old mode 100644 +new mode 100755 +index 6d8cf12..54654f8 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -318,7 +318,7 @@ is_primary() + fi + + if [ -z "$cluster_status" ]; then +- ocf_log err "Unable to retrieve wsrep_cluster_status, verify check_user '$OCF_RESKEY_check_user' has permissions to view status" ++ ocf_exit_reason "Unable to retrieve wsrep_cluster_status, verify check_user '$OCF_RESKEY_check_user' has permissions to view status" + else + ocf_log info "Galera instance wsrep_cluster_status=${cluster_status}" + fi +@@ -441,7 +441,7 @@ galera_promote() + ocf_log info "Node <${NODENAME}> is bootstrapping the cluster" + extra_opts="--wsrep-cluster-address=gcomm://" + else +- ocf_log err "Failure, Attempted to promote Master instance of $OCF_RESOURCE_INSTANCE before bootstrap node has been detected." ++ ocf_exit_reason "Failure, Attempted to promote Master instance of $OCF_RESOURCE_INSTANCE before bootstrap node has been detected." + return $OCF_ERR_GENERIC + fi + +@@ -451,7 +451,7 @@ galera_promote() + mysql_common_stop + rc=$? + if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then +- ocf_log err "Failed to stop read-only galera instance during promotion to Master" ++ ocf_exit_reason "Failed to stop read-only galera instance during promotion to Master" + return $rc + fi + +@@ -467,19 +467,19 @@ galera_promote() + galera_monitor + rc=$? + if [ $rc != $OCF_SUCCESS -a $rc != $OCF_RUNNING_MASTER ]; then +- ocf_log err "Failed initial monitor action" ++ ocf_exit_reason "Failed initial monitor action" + return $rc + fi + + is_readonly + if [ $? -eq 0 ]; then +- ocf_log err "Failure. Master instance started in read-only mode, check configuration." ++ ocf_exit_reason "Failure. Master instance started in read-only mode, check configuration." + return $OCF_ERR_GENERIC + fi + + is_primary + if [ $? -ne 0 ]; then +- ocf_log err "Failure. Master instance started, but is not in Primary mode." ++ ocf_exit_reason "Failure. Master instance started, but is not in Primary mode." + return $OCF_ERR_GENERIC + fi + +@@ -505,7 +505,7 @@ galera_demote() + mysql_common_stop + rc=$? + if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then +- ocf_log err "Failed to stop Master galera instance during demotion to Master" ++ ocf_exit_reason "Failed to stop Master galera instance during demotion to Master" + return $rc + fi + +@@ -523,7 +523,7 @@ galera_start() + + echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME + if [ $? -ne 0 ]; then +- ocf_log err "local node <${NODENAME}> must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>to start this galera instance" ++ ocf_exit_reason "local node <${NODENAME}> must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>to start this galera instance" + return $OCF_ERR_CONFIGURED + fi + +@@ -532,7 +532,7 @@ galera_start() + + is_readonly + if [ $? -ne 0 ]; then +- ocf_log err "Failure. Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." ++ ocf_exit_reason "Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." + return $OCF_ERR_GENERIC + fi + +@@ -579,7 +579,7 @@ galera_monitor() + + echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME + if [ $? -ne 0 ]; then +- ocf_log err "local node <${NODENAME}> is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" ++ ocf_exit_reason "local node <${NODENAME}> is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" + return $OCF_ERR_GENERIC + fi + +@@ -587,7 +587,7 @@ galera_monitor() + if [ $? -ne 0 ]; then + is_primary + if [ $? -ne 0 ]; then +- ocf_log err "local node <${NODENAME}> is neither in primary mode nor in read_only mode. Unknown state." ++ ocf_exit_reason "local node <${NODENAME}> is neither in primary mode nor in read_only mode. Unknown state." + return $OCF_ERR_GENERIC + fi + +@@ -629,12 +629,12 @@ galera_stop() + galera_validate() + { + if ! ocf_is_ms; then +- ocf_log err "Galera must be configured as a multistate Master/Slave resource." ++ ocf_exit_reason "Galera must be configured as a multistate Master/Slave resource." + return $OCF_ERR_CONFIGURED + fi + + if [ -z "$OCF_RESKEY_wsrep_cluster_address" ]; then +- ocf_log err "Galera must be configured with a wsrep_cluster_address value." ++ ocf_exit_reason "Galera must be configured with a wsrep_cluster_address value." + return $OCF_ERR_CONFIGURED + fi + +diff --git a/heartbeat/mysql b/heartbeat/mysql +index 41287d0..3170065 100755 +--- a/heartbeat/mysql ++++ b/heartbeat/mysql +@@ -394,7 +394,7 @@ get_slave_info() { + else + # Instance produced an empty "SHOW SLAVE STATUS" output -- + # instance is not a slave +- ocf_log err "check_slave invoked on an instance that is not a replication slave." ++ ocf_exit_reason "check_slave invoked on an instance that is not a replication slave." + return $OCF_ERR_GENERIC + fi + +@@ -415,7 +415,7 @@ check_slave() { + # Whoa. Replication ran into an error. This slave has + # diverged from its master. Make sure this resource + # doesn't restart in place. +- ocf_log err "MySQL instance configured for replication, but replication has failed." ++ ocf_exit_reason "MySQL instance configured for replication, but replication has failed." + ocf_log err "See $tmpfile for details" + + # Just pull the reader VIP away, killing MySQL here would be pretty evil +@@ -454,7 +454,7 @@ check_slave() { + # We don't have a replication SQL thread running. Not a + # good thing. Try to recoved by restarting the SQL thread + # and remove reader vip. Prevent MySQL restart. +- ocf_log err "MySQL Slave SQL threads currently not running." ++ ocf_exit_reason "MySQL Slave SQL threads currently not running." + ocf_log err "See $tmpfile for details" + + # Remove reader vip +@@ -472,7 +472,7 @@ check_slave() { + # We're supposed to bail out if we lag too far + # behind. Let's check our lag. + if [ $secs_behind -gt $OCF_RESKEY_max_slave_lag ]; then +- ocf_log err "MySQL Slave is $secs_behind seconds behind master (allowed maximum: $OCF_RESKEY_max_slave_lag)." ++ ocf_exit_reason "MySQL Slave is $secs_behind seconds behind master (allowed maximum: $OCF_RESKEY_max_slave_lag)." + ocf_log err "See $tmpfile for details" + + # Remove reader vip +@@ -507,7 +507,7 @@ check_slave() { + # instance is not a slave + # TODO: Needs to handle when get_slave_info will return too many connections error + rm -f $tmpfile +- ocf_log err "check_slave invoked on an instance that is not a replication slave." ++ ocf_exit_reason "check_slave invoked on an instance that is not a replication slave." + exit $OCF_ERR_GENERIC + fi + } +@@ -596,7 +596,7 @@ unset_master(){ + ocf_run $MYSQL $MYSQL_OPTIONS_REPL \ + -e "STOP SLAVE IO_THREAD" + if [ $? -gt 0 ]; then +- ocf_log err "Error stopping slave IO thread" ++ ocf_exit_reason "Error stopping slave IO thread" + exit $OCF_ERR_GENERIC + fi + +@@ -620,14 +620,14 @@ unset_master(){ + ocf_run $MYSQL $MYSQL_OPTIONS_REPL \ + -e "STOP SLAVE" + if [ $? -gt 0 ]; then +- ocf_log err "Error stopping rest slave threads" ++ ocf_exit_reason "Error stopping rest slave threads" + exit $OCF_ERR_GENERIC + fi + + ocf_run $MYSQL $MYSQL_OPTIONS_REPL \ + -e "RESET SLAVE;" + if [ $? -gt 0 ]; then +- ocf_log err "Failed to reset slave" ++ ocf_exit_reason "Failed to reset slave" + exit $OCF_ERR_GENERIC + fi + } +@@ -737,7 +737,7 @@ mysql_monitor() { + rc=$? + + if [ $rc -ne 0 ]; then +- ocf_log err "Failed to select from $test_table"; ++ ocf_exit_reason "Failed to select from $test_table"; + return $OCF_ERR_GENERIC; + fi + fi +@@ -800,7 +800,7 @@ mysql_start() { + set_master + start_slave + if [ $? -ne 0 ]; then +- ocf_log err "Failed to start slave" ++ ocf_exit_reason "Failed to start slave" + return $OCF_ERR_GENERIC + fi + else +@@ -823,7 +823,7 @@ mysql_start() { + mysql_monitor + rc=$? + if [ $rc != $OCF_SUCCESS -a $rc != $OCF_RUNNING_MASTER ]; then +- ocf_log err "Failed initial monitor action" ++ ocf_exit_reason "Failed initial monitor action" + return $rc + fi + +@@ -921,7 +921,7 @@ mysql_notify() { + + start_slave + if [ $? -ne 0 ]; then +- ocf_log err "Failed to start slave" ++ ocf_exit_reason "Failed to start slave" + return $OCF_ERR_GENERIC + fi + fi +@@ -933,7 +933,7 @@ mysql_notify() { + ocf_log info "post-demote notification for $demote_host" + set_read_only on + if [ $? -ne 0 ]; then +- ocf_log err "Failed to set read-only"; ++ ocf_exit_reason "Failed to set read-only"; + return $OCF_ERR_GENERIC; + fi + +diff --git a/heartbeat/mysql-common.sh b/heartbeat/mysql-common.sh +old mode 100644 +new mode 100755 +index 5b6a991..a02f8cd +--- a/heartbeat/mysql-common.sh ++++ b/heartbeat/mysql-common.sh +@@ -98,24 +98,24 @@ mysql_common_validate() + check_binary $OCF_RESKEY_client_binary + + if [ ! -f $OCF_RESKEY_config ]; then +- ocf_log err "Config $OCF_RESKEY_config doesn't exist"; ++ ocf_exit_reason "Config $OCF_RESKEY_config doesn't exist"; + return $OCF_ERR_INSTALLED; + fi + + if [ ! -d $OCF_RESKEY_datadir ]; then +- ocf_log err "Datadir $OCF_RESKEY_datadir doesn't exist"; ++ ocf_exit_reason "Datadir $OCF_RESKEY_datadir doesn't exist"; + return $OCF_ERR_INSTALLED; + fi + + getent passwd $OCF_RESKEY_user >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then +- ocf_log err "User $OCF_RESKEY_user doesn't exit"; ++ ocf_exit_reason "User $OCF_RESKEY_user doesn't exit"; + return $OCF_ERR_INSTALLED; + fi + + getent group $OCF_RESKEY_group >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then +- ocf_log err "Group $OCF_RESKEY_group doesn't exist"; ++ ocf_exit_reason "Group $OCF_RESKEY_group doesn't exist"; + return $OCF_ERR_INSTALLED; + fi + +@@ -162,7 +162,7 @@ mysql_common_prepare_dirs() + $MYSQL_BINDIR/mysql_install_db --datadir=$OCF_RESKEY_datadir + rc=$? + if [ $rc -ne 0 ] ; then +- ocf_log err "Initialization failed: $rc"; ++ ocf_exit_reason "Initialization failed: $rc"; + exit $OCF_ERR_GENERIC + fi + chown -R $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_datadir +@@ -187,7 +187,7 @@ mysql_common_prepare_dirs() + # user + for dir in $pid_dir $socket_dir; do + if ! su -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then +- ocf_log err "Directory $dir is not writable by $OCF_RESKEY_user" ++ ocf_exit_reason "Directory $dir is not writable by $OCF_RESKEY_user" + exit $OCF_ERR_PERM; + fi + done +@@ -213,7 +213,7 @@ mysql_common_start() + while [ $start_wait = 1 ]; do + if ! ps $pid > /dev/null 2>&1; then + wait $pid +- ocf_log err "MySQL server failed to start (pid=$pid) (rc=$?), please check your installation" ++ ocf_exit_reason "MySQL server failed to start (pid=$pid) (rc=$?), please check your installation" + return $OCF_ERR_GENERIC + fi + mysql_common_status info +@@ -244,7 +244,7 @@ mysql_common_stop() + /bin/kill $pid > /dev/null + rc=$? + if [ $rc != 0 ]; then +- ocf_log err "MySQL couldn't be stopped" ++ ocf_exit_reason "MySQL couldn't be stopped" + return $OCF_ERR_GENERIC + fi + # stop waiting +diff --git a/heartbeat/named b/heartbeat/named +index ede22df..2c34a15 100755 +--- a/heartbeat/named ++++ b/heartbeat/named +@@ -211,21 +211,21 @@ named_validate_all() { + if ocf_is_probe; then + ocf_log info "Configuration file ${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config} not readable during probe." + else +- ocf_log err "Configuration file ${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config} doesn't exist" ++ ocf_exit_reason "Configuration file ${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config} doesn't exist" + return $OCF_ERR_INSTALLED + fi + fi + + getent passwd $OCF_RESKEY_named_user >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then +- ocf_log err "User $OCF_RESKEY_named_user doesn't exist"; ++ ocf_exit_reason "User $OCF_RESKEY_named_user doesn't exist"; + return $OCF_ERR_INSTALLED; + fi + + if [ -z "$OCF_RESKEY_monitor_request" -o \ + -z "$OCF_RESKEY_monitor_response" -o \ + -z "$OCF_RESKEY_monitor_ip" ]; then +- ocf_log err "None of monitor_request, monitor_response, and monitor_ip can be empty" ++ ocf_exit_reason "None of monitor_request, monitor_response, and monitor_ip can be empty" + return $OCF_ERR_CONFIGURED + fi + +@@ -309,7 +309,7 @@ named_monitor() { + + if [ $? -ne 0 ] || ! echo $output | grep -q '.* has .*address '"$OCF_RESKEY_monitor_response" + then +- ocf_log err "named didn't answer properly for $OCF_RESKEY_monitor_request." ++ ocf_exit_reason "named didn't answer properly for $OCF_RESKEY_monitor_request." + ocf_log err "Expected: $OCF_RESKEY_monitor_response." + ocf_log err "Got: $output" + return $OCF_ERR_GENERIC +@@ -356,7 +356,7 @@ named_start() { + + if ! ${OCF_RESKEY_named} -u ${OCF_RESKEY_named_user} $root_dir_opt ${OCF_RESKEY_named_options} + then +- ocf_log err "named failed to start." ++ ocf_exit_reason "named failed to start." + return $OCF_ERR_GENERIC + fi + +@@ -368,7 +368,7 @@ named_start() { + echo $pid > ${OCF_RESKEY_named_pidfile} + fi + else +- ocf_log err "named failed to start. Probably error in configuration." ++ ocf_exit_reason "named failed to start. Probably error in configuration." + return $OCF_ERR_GENERIC + fi + +@@ -420,7 +420,7 @@ named_stop () { + + #If still up + if named_status 2>&1; then +- ocf_log err "named is still up! Killing" ++ ocf_exit_reason "named is still up! Killing" + kill -9 `cat ${OCF_RESKEY_named_pidfile}` + fi + +@@ -460,7 +460,7 @@ then + fi + + if [ `id -u` -ne 0 ]; then +- ocf_log err "$0 must be run as root" ++ ocf_exit_reason "$0 must be run as root" + exit $OCF_ERR_GENERIC + fi + +diff --git a/heartbeat/pgsql b/heartbeat/pgsql +index aea97da..794f85e 100755 +--- a/heartbeat/pgsql ++++ b/heartbeat/pgsql +@@ -495,7 +495,7 @@ pgsql_real_start() { + # Check if we need to create a log file + if ! check_log_file $OCF_RESKEY_logfile + then +- ocf_log err "PostgreSQL can't write to the log file: $OCF_RESKEY_logfile" ++ ocf_exit_reason "PostgreSQL can't write to the log file: $OCF_RESKEY_logfile" + return $OCF_ERR_PERM + fi + +@@ -533,7 +533,7 @@ pgsql_real_start() { + # Probably started..... + ocf_log info "PostgreSQL start command sent." + else +- ocf_log err "Can't start PostgreSQL." ++ ocf_exit_reason "Can't start PostgreSQL." + return $OCF_ERR_GENERIC + fi + +@@ -565,7 +565,7 @@ pgsql_replication_start() { + fi + + if [ -f $PGSQL_LOCK ]; then +- ocf_log err "My data may be inconsistent. You have to remove $PGSQL_LOCK file to force start." ++ ocf_exit_reason "My data may be inconsistent. You have to remove $PGSQL_LOCK file to force start." + return $OCF_ERR_GENERIC + fi + +@@ -595,7 +595,7 @@ pgsql_promote() { + local rc + + if ! is_replication; then +- ocf_log err "Not in a replication mode." ++ ocf_exit_reason "Not in a replication mode." + return $OCF_ERR_CONFIGURED + fi + rm -f ${XLOG_NOTE_FILE}.* +@@ -618,7 +618,7 @@ pgsql_promote() { + pgsql_real_start + rc=$? + if [ $rc -ne $OCF_RUNNING_MASTER ]; then +- ocf_log err "Can't start PostgreSQL as primary on promote." ++ ocf_exit_reason "Can't start PostgreSQL as primary on promote." + if [ $rc -ne $OCF_SUCCESS ]; then + change_pgsql_status "$NODENAME" "STOP" + fi +@@ -629,7 +629,7 @@ pgsql_promote() { + if [ $? -eq 0 ]; then + ocf_log info "PostgreSQL promote command sent." + else +- ocf_log err "Can't promote PostgreSQL." ++ ocf_exit_reason "Can't promote PostgreSQL." + return $OCF_ERR_GENERIC + fi + +@@ -640,7 +640,7 @@ pgsql_promote() { + if [ $rc -eq $OCF_RUNNING_MASTER ]; then + break; + elif [ $rc -eq $OCF_ERR_GENERIC ]; then +- ocf_log err "Can't promote PostgreSQL." ++ ocf_exit_reason "Can't promote PostgreSQL." + return $rc + fi + sleep 1 +@@ -660,7 +660,7 @@ pgsql_demote() { + local rc + + if ! is_replication; then +- ocf_log err "Not in a replication mode." ++ ocf_exit_reason "Not in a replication mode." + return $OCF_ERR_CONFIGURED + fi + +@@ -861,7 +861,7 @@ pgsql_real_monitor() { + t) ocf_log debug "PostgreSQL is running as a hot standby." + return $OCF_SUCCESS;; + +- *) ocf_log err "$CHECK_MS_SQL output is $output" ++ *) ocf_exit_reason "$CHECK_MS_SQL output is $output" + return $OCF_ERR_GENERIC;; + esac + fi +@@ -966,7 +966,7 @@ pgsql_pre_promote() { + cmp_location=`printf "$master_baseline\n$my_master_baseline\n" |\ + sort | head -1` + if [ "$cmp_location" != "$my_master_baseline" ]; then +- ocf_log err "My data is newer than new master's one. New master's location : $master_baseline" ++ ocf_exit_reason "My data is newer than new master's one. New master's location : $master_baseline" + $CRM_FAILCOUNT -r $OCF_RESOURCE_INSTANCE -U $NODENAME -v INFINITY + return $OCF_ERR_GENERIC + fi +@@ -1149,7 +1149,7 @@ have_master_right() { + + show_xlog_location + if [ $? -ne 0 ]; then +- ocf_log err "Failed to show my xlog location." ++ ocf_exit_reason "Failed to show my xlog location." + exit $OCF_ERR_GENERIC + fi + +@@ -1288,7 +1288,7 @@ set_async_mode_all() { + ocf_log info "Set all nodes into async mode." + runasowner -q err "echo \"synchronous_standby_names = ''\" > \"$REP_MODE_CONF\"" + if [ $? -ne 0 ]; then +- ocf_log err "Can't set all nodes into async mode." ++ ocf_exit_reason "Can't set all nodes into async mode." + return 1 + fi + return 0 +@@ -1339,7 +1339,7 @@ reload_conf() { + if [ $? -eq 0 ]; then + ocf_log info "Reload configuration file." + else +- ocf_log err "Can't reload configuration file." ++ ocf_exit_reason "Can't reload configuration file." + return 1 + fi + +@@ -1359,7 +1359,7 @@ user_recovery_conf() { + make_recovery_conf() { + runasowner "touch $RECOVERY_CONF" + if [ $? -ne 0 ]; then +- ocf_log err "Can't create recovery.conf." ++ ocf_exit_reason "Can't create recovery.conf." + return 1 + fi + +@@ -1492,11 +1492,11 @@ report_psql_error() + + ocf_log $loglevel "PostgreSQL $OCF_RESKEY_pgdb isn't running" + if [ $rc -eq 1 ]; then +- ocf_log err "Fatal error (out of memory, file not found, etc.) occurred while executing the psql command." ++ ocf_exit_reason "Fatal error (out of memory, file not found, etc.) occurred while executing the psql command." + elif [ $rc -eq 2 ]; then + ocf_log $loglevel "Connection error (connection to the server went bad and the session was not interactive) occurred while executing the psql command." + elif [ $rc -eq 3 ]; then +- ocf_log err "Script error (the variable ON_ERROR_STOP was set) occurred while executing the psql command." ++ ocf_exit_reason "Script error (the variable ON_ERROR_STOP was set) occurred while executing the psql command." + fi + } + +@@ -1536,7 +1536,7 @@ node_exist() { + + check_binary2() { + if ! have_binary "$1"; then +- ocf_log err "Setup problem: couldn't find command: $1" ++ ocf_exit_reason "Setup problem: couldn't find command: $1" + return 1 + fi + return 0 +@@ -1550,7 +1550,7 @@ check_config() { + ocf_log info "Configuration file is $1 not readable during probe." + rc=1 + else +- ocf_log err "Configuration file $1 doesn't exist" ++ ocf_exit_reason "Configuration file $1 doesn't exist" + rc=2 + fi + fi +@@ -1576,7 +1576,7 @@ pgsql_validate_all() { + + getent passwd $OCF_RESKEY_pgdba >/dev/null 2>&1 + if [ ! $? -eq 0 ]; then +- ocf_log err "User $OCF_RESKEY_pgdba doesn't exist"; ++ ocf_exit_reason "User $OCF_RESKEY_pgdba doesn't exist"; + return $OCF_ERR_INSTALLED; + fi + +@@ -1584,46 +1584,46 @@ pgsql_validate_all() { + ocf_log info "Don't check $OCF_RESKEY_pgdata during probe" + else + if ! runasowner "test -w $OCF_RESKEY_pgdata"; then +- ocf_log err "Directory $OCF_RESKEY_pgdata is not writable by $OCF_RESKEY_pgdba" ++ ocf_exit_reason "Directory $OCF_RESKEY_pgdata is not writable by $OCF_RESKEY_pgdba" + return $OCF_ERR_PERM; + fi + fi + + if [ -n "$OCF_RESKEY_monitor_user" -a ! -n "$OCF_RESKEY_monitor_password" ] + then +- ocf_log err "monitor password can't be empty" ++ ocf_exit_reason "monitor password can't be empty" + return $OCF_ERR_CONFIGURED + fi + + if [ ! -n "$OCF_RESKEY_monitor_user" -a -n "$OCF_RESKEY_monitor_password" ] + then +- ocf_log err "monitor_user has to be set if monitor_password is set" ++ ocf_exit_reason "monitor_user has to be set if monitor_password is set" + return $OCF_ERR_CONFIGURED + fi + + if is_replication || [ "$OCF_RESKEY_rep_mode" = "slave" ]; then + version=`cat $OCF_RESKEY_pgdata/PG_VERSION` + if [ `printf "$version\n9.1" | sort -n | head -1` != "9.1" ]; then +- ocf_log err "Replication mode needs PostgreSQL 9.1 or higher." ++ ocf_exit_reason "Replication mode needs PostgreSQL 9.1 or higher." + return $OCF_ERR_INSTALLED + fi + if [ ! -n "$OCF_RESKEY_master_ip" ]; then +- ocf_log err "master_ip can't be empty." ++ ocf_exit_reason "master_ip can't be empty." + return $OCF_ERR_CONFIGURED + fi + fi + + if is_replication; then + if ! ocf_is_ms; then +- ocf_log err "Replication(rep_mode=async or sync) requires Master/Slave configuration." ++ ocf_exit_reason "Replication(rep_mode=async or sync) requires Master/Slave configuration." + return $OCF_ERR_CONFIGURED + fi + if [ ! "$OCF_RESKEY_rep_mode" = "sync" -a ! "$OCF_RESKEY_rep_mode" = "async" ]; then +- ocf_log err "Invalid rep_mode : $OCF_RESKEY_rep_mode" ++ ocf_exit_reason "Invalid rep_mode : $OCF_RESKEY_rep_mode" + return $OCF_ERR_CONFIGURED + fi + if [ ! -n "$NODE_LIST" ]; then +- ocf_log err "node_list can't be empty." ++ ocf_exit_reason "node_list can't be empty." + return $OCF_ERR_CONFIGURED + fi + if [ $check_config_rc -eq 0 ]; then +@@ -1641,14 +1641,14 @@ pgsql_validate_all() { + fi + fi + if ! mkdir -p $OCF_RESKEY_tmpdir || ! chown $OCF_RESKEY_pgdba $OCF_RESKEY_tmpdir || ! chmod 700 $OCF_RESKEY_tmpdir; then +- ocf_log err "Can't create directory $OCF_RESKEY_tmpdir or it is not readable by $OCF_RESKEY_pgdba" ++ ocf_exit_reason "Can't create directory $OCF_RESKEY_tmpdir or it is not readable by $OCF_RESKEY_pgdba" + return $OCF_ERR_PERM + fi + fi + + if [ "$OCF_RESKEY_rep_mode" = "slave" ]; then + if ocf_is_ms; then +- ocf_log err "Replication(rep_mode=slave) does not support Master/Slave configuration." ++ ocf_exit_reason "Replication(rep_mode=slave) does not support Master/Slave configuration." + return $OCF_ERR_CONFIGURED + fi + fi +@@ -1683,24 +1683,24 @@ check_log_file() { + check_socket_dir() { + if [ ! -d "$OCF_RESKEY_socketdir" ]; then + if ! mkdir "$OCF_RESKEY_socketdir"; then +- ocf_log err "Can't create directory $OCF_RESKEY_socketdir" ++ ocf_exit_reason "Can't create directory $OCF_RESKEY_socketdir" + exit $OCF_ERR_PERM + fi + + if ! chown $OCF_RESKEY_pgdba:`getent passwd \ + $OCF_RESKEY_pgdba | cut -d ":" -f 4` "$OCF_RESKEY_socketdir" + then +- ocf_log err "Can't change ownership for $OCF_RESKEY_socketdir" ++ ocf_exit_reason "Can't change ownership for $OCF_RESKEY_socketdir" + exit $OCF_ERR_PERM + fi + + if ! chmod 2775 "$OCF_RESKEY_socketdir"; then +- ocf_log err "Can't change permissions for $OCF_RESKEY_socketdir" ++ ocf_exit_reason "Can't change permissions for $OCF_RESKEY_socketdir" + exit $OCF_ERR_PERM + fi + else + if ! runasowner "touch $OCF_RESKEY_socketdir/test.$$"; then +- ocf_log err "$OCF_RESKEY_pgdba can't create files in $OCF_RESKEY_socketdir" ++ ocf_exit_reason "$OCF_RESKEY_pgdba can't create files in $OCF_RESKEY_socketdir" + exit $OCF_ERR_PERM + fi + rm $OCF_RESKEY_socketdir/test.$$ +@@ -1782,7 +1782,7 @@ US=`id -u -n` + + if [ $US != root -a $US != $OCF_RESKEY_pgdba ] + then +- ocf_log err "$0 must be run as root or $OCF_RESKEY_pgdba" ++ ocf_exit_reason "$0 must be run as root or $OCF_RESKEY_pgdba" + exit $OCF_ERR_GENERIC + fi + +diff --git a/heartbeat/postfix b/heartbeat/postfix +index 8619af6..72fc371 100755 +--- a/heartbeat/postfix ++++ b/heartbeat/postfix +@@ -134,7 +134,7 @@ postfix_start() + ret=$? + + if [ $ret -ne 0 ]; then +- ocf_log err "Postfix returned error: " $ret ++ ocf_exit_reason "Postfix returned error: " $ret + return $OCF_ERR_GENERIC + fi + +@@ -165,7 +165,7 @@ postfix_stop() + ret=$? + + if [ $ret -ne 0 ]; then +- ocf_log err "Postfix returned an error while stopping: " $ret ++ ocf_exit_reason "Postfix returned an error while stopping: " $ret + return $OCF_ERR_GENERIC + fi + +@@ -181,14 +181,14 @@ postfix_stop() + # escalate to abort if we did not stop by now + # @TODO shall we loop here too? + if postfix_running info; then +- ocf_log err "Postfix failed to stop. Escalating to 'abort'." ++ ocf_exit_reason "Postfix failed to stop. Escalating to 'abort'." + + $binary $OPTIONS abort >/dev/null 2>&1; ret=$? + sleep 5 + + # postfix abort did not succeed + if postfix_running; then +- ocf_log err "Postfix failed to abort." ++ ocf_exit_reason "Postfix failed to abort." + return $OCF_ERR_GENERIC + fi + fi +@@ -238,14 +238,14 @@ postfix_validate_all() + # skip in-depth directory checks if config file isn't readable during probe + dir_check=false + else +- ocf_log err "Postfix configuration directory '$config_dir' does not exist or is not readable." ++ ocf_exit_reason "Postfix configuration directory '$config_dir' does not exist or is not readable." + return $OCF_ERR_INSTALLED + fi + fi + + alternate_config_directories=`postconf -h alternate_config_directories 2>/dev/null | grep "$config_dir/\?"` + if [ "x$alternate_config_directories" = "x" ]; then +- ocf_log err "Postfix main configuration must contain correct 'alternate_config_directories' parameter." ++ ocf_exit_reason "Postfix main configuration must contain correct 'alternate_config_directories' parameter." + return $OCF_ERR_INSTALLED + fi + fi +@@ -257,7 +257,7 @@ postfix_validate_all() + if ocf_is_probe; then + ocf_log info "Postfix queue directory '$queue_dir' not readable during probe." + else +- ocf_log err "Postfix queue directory '$queue_dir' does not exist or is not readable." ++ ocf_exit_reason "Postfix queue directory '$queue_dir' does not exist or is not readable." + return $OCF_ERR_INSTALLED + fi + fi +@@ -266,14 +266,14 @@ postfix_validate_all() + data_dir=`postconf $OPTION_CONFIG_DIR -h data_directory 2>/dev/null` + data_dir_count=`echo "$data_dir" | tr ',' ' ' | wc -w` + if [ $data_dir_count -gt 1 ]; then +- ocf_log err "Postfix data directory '$orig_data_dir' cannot be set to multiple directories." ++ ocf_exit_reason "Postfix data directory '$orig_data_dir' cannot be set to multiple directories." + return $OCF_ERR_INSTALLED + fi + if [ ! -d "$data_dir" ]; then + if ocf_is_probe; then + ocf_log info "Postfix data directory '$data_dir' not readable during probe." + else +- ocf_log err "Postfix data directory '$data_dir' does not exist or is not readable." ++ ocf_exit_reason "Postfix data directory '$data_dir' does not exist or is not readable." + return $OCF_ERR_INSTALLED + fi + fi +@@ -287,7 +287,7 @@ postfix_validate_all() + if ocf_is_probe; then + ocf_log info "Directory '$dir' is not writable by user '$user' during probe." + else +- ocf_log err "Directory '$dir' is not writable by user '$user'." ++ ocf_exit_reason "Directory '$dir' is not writable by user '$user'." + return $OCF_ERR_PERM; + fi + fi +@@ -300,7 +300,7 @@ postfix_validate_all() + $binary $OPTIONS check >/dev/null 2>&1 + ret=$? + if [ $ret -ne 0 ]; then +- ocf_log err "Postfix 'check' failed: " $ret ++ ocf_exit_reason "Postfix 'check' failed: " $ret + return $OCF_ERR_GENERIC + fi + fi +diff --git a/heartbeat/rsyncd b/heartbeat/rsyncd +index b8cdeb7..dfbbea8 100755 +--- a/heartbeat/rsyncd ++++ b/heartbeat/rsyncd +@@ -127,7 +127,7 @@ rsyncd_status() + return $OCF_ERR_GENERIC + fi + else +- ocf_log err "PID file empty!" ++ ocf_exit_reason "PID file empty!" + return $OCF_ERR_GENERIC + fi + fi +@@ -145,7 +145,7 @@ rsyncd_start() + if [ $retVal -eq $OCF_SUCCESS ]; then + exit $OCF_SUCCESS + elif [ $retVal -ne $OCF_NOT_RUNNING ]; then +- ocf_log err "Error. Unknown status." ++ ocf_exit_reason "Error. Unknown status." + exit $OCF_ERR_GENERIC + fi + +@@ -164,11 +164,11 @@ rsyncd_start() + if grep -v "^#" "$CONF_FILE" | grep "pid file" > /dev/null ; then + $COMMAND; + if [ $? -ne 0 ]; then +- ocf_log err "Error. rsycn daemon returned error $?." ++ ocf_exit_reason "Error. rsycn daemon returned error $?." + exit $OCF_ERR_GENERIC + fi + else +- ocf_log err "Error. \"pid file\" entry required in the rsyncd config file by rsyncd OCF RA." ++ ocf_exit_reason "Error. \"pid file\" entry required in the rsyncd config file by rsyncd OCF RA." + return $OCF_ERR_GENERIC + fi + +@@ -186,7 +186,7 @@ rsyncd_stop() + if [ $? -ne 0 ]; then + kill -s KILL $PID + if [ $? -ne 0 ]; then +- ocf_log err "Error. Could not stop rsync daemon." ++ ocf_exit_reason "Error. Could not stop rsync daemon." + return $OCF_ERR_GENERIC + fi + fi +@@ -205,18 +205,18 @@ rsyncd_monitor() + rsyncd_validate_all() + { + if [ -n "$OCF_RESKEY_binpath" -a ! -x "$OCF_RESKEY_binpath" ]; then +- ocf_log err "Binary path $OCF_RESKEY_binpath does not exist." ++ ocf_exit_reason "Binary path $OCF_RESKEY_binpath does not exist." + exit $OCF_ERR_ARGS + fi + if [ -n "$OCF_RESKEY_conffile" -a ! -f "$OCF_RESKEY_conffile" ]; then +- ocf_log err "Config file $OCF_RESKEY_conffile does not exist." ++ ocf_exit_reason "Config file $OCF_RESKEY_conffile does not exist." + exit $OCF_ERR_ARGS + fi + + if grep -v "^#" "$CONF_FILE" | grep "pid file" > /dev/null ; then + : + else +- ocf_log err "Error. \"pid file\" entry required in the rsyncd config file by rsyncd OCF RA." ++ ocf_exit_reason "Error. \"pid file\" entry required in the rsyncd config file by rsyncd OCF RA." + return $OCF_ERR_GENERIC + fi + +diff --git a/heartbeat/slapd b/heartbeat/slapd +index ffb40e8..c26b16f 100755 +--- a/heartbeat/slapd ++++ b/heartbeat/slapd +@@ -268,7 +268,7 @@ slapd_pid() + return $OCF_SUCCESS + fi + +- ocf_log err "slapd pid file '$pid_file' empty." ++ ocf_exit_reason "slapd pid file '$pid_file' empty." + return $OCF_ERR_GENERIC + fi + +@@ -316,7 +316,7 @@ slapd_start() + elif [ -f "$config" ]; then + options="$options -f $config" + else +- ocf_log err "slapd configuration '$config' does not exist." ++ ocf_exit_reason "slapd configuration '$config' does not exist." + return $OCF_ERR_INSTALLED + fi + +@@ -331,7 +331,7 @@ slapd_start() + fi + + if [ $rc -ne 0 ]; then +- ocf_log err "slapd returned error." ++ ocf_exit_reason "slapd returned error." + + return $OCF_ERR_GENERIC + fi +@@ -366,7 +366,7 @@ slapd_stop() + + terminate $pid TERM $OCF_RESKEY_stop_escalate; rc=$? + if [ $rc -ne 0 ]; then +- ocf_log err "slapd failed to stop. Escalating to KILL." ++ ocf_exit_reason "slapd failed to stop. Escalating to KILL." + terminate $pid KILL; rc=$? + fi + +@@ -391,12 +391,12 @@ slapd_monitor() + if [ $state -eq $OCF_NOT_RUNNING ]; then + if [ -z "$1" ];then + if ! ocf_is_probe; then +- ocf_log err "slapd process not found." ++ ocf_exit_reason "slapd process not found." + fi + fi + return $state + elif [ $state -ne $OCF_SUCCESS ]; then +- ocf_log err "slapd returned error." ++ ocf_exit_reason "slapd returned error." + return $state + fi + +@@ -427,7 +427,7 @@ slapd_monitor() + if ocf_is_probe; then + ocf_log info "slapd configuration '$config' does not exist during probe." + else +- ocf_log err "slapd configuration '$config' does not exist." ++ ocf_exit_reason "slapd configuration '$config' does not exist." + return $OCF_ERR_INSTALLED + fi + fi +@@ -447,12 +447,12 @@ slapd_monitor() + ocf_log debug "slapd database with suffix '$suffix' reachable" + ;; + "49") +- ocf_log err "slapd database with suffix '$suffix' unreachable. Invalid credentials." ++ ocf_exit_reason "slapd database with suffix '$suffix' unreachable. Invalid credentials." + return $OCF_ERR_CONFIGURED + ;; + *) + if [ -z "$1" ] || [ -n "$1" -a $rc -ne 1 ]; then +- ocf_log err "slapd database with suffix '$suffix' unreachable. exit code ($rc)" ++ ocf_exit_reason "slapd database with suffix '$suffix' unreachable. exit code ($rc)" + fi + state=$OCF_ERR_GENERIC + ;; +@@ -480,7 +480,7 @@ slapd_validate_all() + if ocf_is_probe; then + ocf_log info "slapd configuration '$config' does not exist during probe." + else +- ocf_log err "slapd configuration '$config' does not exist." ++ ocf_exit_reason "slapd configuration '$config' does not exist." + return $OCF_ERR_INSTALLED + fi + fi +@@ -489,14 +489,14 @@ slapd_validate_all() + if [ -z "$user" ]; then + user=`id -nu 2>/dev/null` + elif ! id "$user" >/dev/null 2>&1; then +- ocf_log err "slapd user '$user' does not exist" ++ ocf_exit_reason "slapd user '$user' does not exist" + return $OCF_ERR_INSTALLED + fi + + if [ -z "$group" ]; then + group=`id -ng 2>/dev/null` + elif ! grep "^$group:" /etc/group >/dev/null 2>&1; then +- ocf_log err "slapd group '$group' does not exist" ++ ocf_exit_reason "slapd group '$group' does not exist" + return $OCF_ERR_INSTALLED + fi + +diff --git a/heartbeat/symlink b/heartbeat/symlink +index 214092d..1e36a9c 100755 +--- a/heartbeat/symlink ++++ b/heartbeat/symlink +@@ -117,7 +117,7 @@ symlink_monitor() { + rc=$OCF_NOT_RUNNING + elif [ ! -L "$OCF_RESKEY_link" ]; then + if [ -z "$OCF_RESKEY_backup_suffix" ]; then +- ocf_log err "$OCF_RESKEY_link exists but is not a symbolic link!" ++ ocf_exit_reason "$OCF_RESKEY_link exists but is not a symbolic link!" + exit $OCF_ERR_INSTALLED + else + ocf_log debug "$OCF_RESKEY_link exists but is not a symbolic link, will be moved to ${OCF_RESKEY_link}${OCF_RESKEY_backup_suffix} on start" +@@ -128,7 +128,7 @@ symlink_monitor() { + rc=$OCF_SUCCESS + else + if [ -z "$OCF_RESKEY_backup_suffix" ]; then +- ocf_log err "$OCF_RESKEY_link does not point to ${OCF_RESKEY_target}!" ++ ocf_exit_reason "$OCF_RESKEY_link does not point to ${OCF_RESKEY_target}!" + exit $OCF_ERR_INSTALLED + else + ocf_log debug "$OCF_RESKEY_link does not point to ${OCF_RESKEY_target}, will be moved to ${OCF_RESKEY_link}${OCF_RESKEY_backup_suffix} on start" +@@ -146,7 +146,7 @@ symlink_start() { + # have errored out. But there is a chance that + # something else put that file there after + # symlink_monitor ran. +- ocf_log err "$OCF_RESKEY_link exists and no backup_suffix is set, won't overwrite." ++ ocf_exit_reason "$OCF_RESKEY_link exists and no backup_suffix is set, won't overwrite." + exit $OCF_ERR_GENERIC + else + ocf_log debug "Found $OCF_RESKEY_link, moving to ${OCF_RESKEY_link}${OCF_RESKEY_backup_suffix}" +@@ -174,7 +174,7 @@ symlink_stop() { + fi + return $OCF_SUCCESS + else +- ocf_log err "Removing $OCF_RESKEY_link failed." ++ ocf_exit_reason "Removing $OCF_RESKEY_link failed." + return $OCF_ERR_GENERIC + fi + else +@@ -184,11 +184,11 @@ symlink_stop() { + + symlink_validate_all() { + if [ "x${OCF_RESKEY_link}" = "x" ]; then +- ocf_log err "Mandatory parameter link is unset" ++ ocf_exit_reason "Mandatory parameter link is unset" + exit $OCF_ERR_CONFIGURED + fi + if [ "x${OCF_RESKEY_target}" = "x" ]; then +- ocf_log err "Mandatory parameter target is unset" ++ ocf_exit_reason "Mandatory parameter target is unset" + exit $OCF_ERR_CONFIGURED + fi + +diff --git a/heartbeat/tomcat b/heartbeat/tomcat +index 23a7e2f..7b67786 100755 +--- a/heartbeat/tomcat ++++ b/heartbeat/tomcat +@@ -157,7 +157,7 @@ rotate_catalina_out() + su - -s /bin/sh $RESOURCE_TOMCAT_USER \ + -c "touch \"$CATALINA_BASE/logs/catalina_$CURRENT_ROTATELOG_SUFFIX.log\"" > /dev/null 2>&1 + if [ $? -ne 0 ]; then +- ocf_log err "$CATALINA_BASE/logs/catalina_$CURRENT_ROTATELOG_SUFFIX.log is not writable." ++ ocf_exit_reason "$CATALINA_BASE/logs/catalina_$CURRENT_ROTATELOG_SUFFIX.log is not writable." + return $OCF_ERR_GENERIC + fi + +@@ -235,7 +235,7 @@ start_tomcat() + if [ $? -eq 0 ]; then + ocf_log debug "Rotate catalina.out succeeded." + else +- ocf_log err "Rotate catalina.out failed. Avoid starting tomcat without catalina.out rotation." ++ ocf_exit_reason "Rotate catalina.out failed. Avoid starting tomcat without catalina.out rotation." + return $OCF_ERR_GENERIC + fi + fi +@@ -534,12 +534,12 @@ validate_all_tomcat() + check_binary $WGET + + if [ -z "${TOMCAT_START_SCRIPT}" ]; then +- ocf_log err "No default tomcat start script detected. Please specify start script location using the 'tomcat_start_script' option" ++ ocf_exit_reason "No default tomcat start script detected. Please specify start script location using the 'tomcat_start_script' option" + rc=$OCF_ERR_CONFIGURED + fi + + if [ -n "$MAX_STOP_TIME" ] && [ "$MAX_STOP_TIME" -lt 0 ]; then +- ocf_log err "max_stop_time must be set to a value greater than 0." ++ ocf_exit_reason "max_stop_time must be set to a value greater than 0." + rc=$OCF_ERR_CONFIGURED + fi + +@@ -550,14 +550,14 @@ validate_all_tomcat() + ocf_log debug "grep port=\"$port\" $CATALINA_BASE/conf/server.xml" + grep "port=\"$port\"" $CATALINA_BASE/conf/server.xml > /dev/null 2>&1 + if [ $? -ne 0 ]; then +- ocf_log err "Your configured status URL specifies a port ($port), but the server does not have a connector listening to that port in $CATALINA_BASE/conf/server.xml" ++ ocf_exit_reason "Your configured status URL specifies a port ($port), but the server does not have a connector listening to that port in $CATALINA_BASE/conf/server.xml" + rc=$OCF_ERR_INSTALLED + fi + fi + + if ocf_is_true ${CATALINA_ROTATE_LOG}; then + if [ ! -x "$ROTATELOGS" ]; then +- ocf_log err "rotatelogs command does not exist." ++ ocf_exit_reason "rotatelogs command does not exist." + rc=$OCF_ERR_INSTALLED + fi + fi +@@ -635,7 +635,7 @@ if [ ! -d "$JAVA_HOME" -o ! -d "$CATALINA_HOME" -o ! -d "$CATALINA_BASE" ]; then + monitor) exit $OCF_NOT_RUNNING;; + status) exit $LSB_STATUS_STOPPED;; + esac +- ocf_log err "JAVA_HOME or CATALINA_HOME or CATALINA_BASE does not exist." ++ ocf_exit_reason "JAVA_HOME or CATALINA_HOME or CATALINA_BASE does not exist." + exit $OCF_ERR_INSTALLED + fi + +@@ -649,7 +649,7 @@ if [ ! -x "$JAVA" ]; then + monitor) exit $OCF_NOT_RUNNING;; + status) exit $LSB_STATUS_STOPPED;; + esac +- ocf_log err "java command does not exist." ++ ocf_exit_reason "java command does not exist." + exit $OCF_ERR_INSTALLED + fi + +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-exportfs-exit-reason-support.patch b/SOURCES/bz1128933-exportfs-exit-reason-support.patch new file mode 100644 index 0000000..95d298b --- /dev/null +++ b/SOURCES/bz1128933-exportfs-exit-reason-support.patch @@ -0,0 +1,43 @@ +From e334f036ab02ec6cdf4cf463e26d4f32e592f15c Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 15 Aug 2014 11:03:36 -0500 +Subject: [PATCH] High: exportfs: support exit reason string + +--- + heartbeat/exportfs | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/heartbeat/exportfs b/heartbeat/exportfs +index 471da24..3f91037 100755 +--- a/heartbeat/exportfs ++++ b/heartbeat/exportfs +@@ -239,7 +239,7 @@ exportfs_monitor () + ocf_log info "Directory ${OCF_RESKEY_directory} is not exported to ${OCF_RESKEY_clientspec} (stopped)." + return $OCF_NOT_RUNNING;; + *) +- ocf_log err "Unable to determine export status for ${OCF_RESKEY_directory}." ++ ocf_exit_reason "Unable to determine export status for ${OCF_RESKEY_directory}." + return $OCF_ERR_GENERIC;; + esac + } +@@ -340,7 +340,7 @@ exportfs_stop () + ocf_log info "Un-exported file system" + return $OCF_SUCCESS + else +- ocf_log err "Failed to un-export file system" ++ ocf_exit_reason "Failed to un-export file system" + exit $OCF_ERR_GENERIC + fi + } +@@ -348,7 +348,7 @@ exportfs_stop () + exportfs_validate_all () + { + if [ ! -d $OCF_RESKEY_directory ]; then +- ocf_log err "$OCF_RESKEY_directory does not exist or is not a directory" ++ ocf_exit_reason "$OCF_RESKEY_directory does not exist or is not a directory" + return $OCF_ERR_INSTALLED + fi + } +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-introducing-exit-reason-support.patch b/SOURCES/bz1128933-introducing-exit-reason-support.patch new file mode 100644 index 0000000..ad2e6cb --- /dev/null +++ b/SOURCES/bz1128933-introducing-exit-reason-support.patch @@ -0,0 +1,98 @@ +From 0dfe07cbd9e74e0f7f3c85a42085972bf24e1d24 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 15 Aug 2014 10:50:06 -0500 +Subject: [PATCH] Introducing exit reason string support + +--- + heartbeat/ocf-shellfuncs.in | 48 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in +index 254da57..ff7c32d 100644 +--- a/heartbeat/ocf-shellfuncs.in ++++ b/heartbeat/ocf-shellfuncs.in +@@ -43,6 +43,14 @@ unset LANGUAGE; export LANGUAGE + + __SCRIPT_NAME=`basename $0` + ++# This is internal to shellfuncs. ++# When set, ha_log can be used in a way that guarantees ++# that stderr will not be printed to. This allows us to ++# use ocf_exit_reason to print a string to stderr and use ++# ha_log to print the same string to the other log facilities ++# without having duplicate messages sent to stderr. ++__ha_log_ignore_stderr_once="" ++ + if [ -z "$OCF_ROOT" ]; then + : ${OCF_ROOT=@OCF_ROOT_DIR@} + fi +@@ -182,12 +190,20 @@ set_logtag() { + } + + ha_log() { ++ local ignore_stderr="$__ha_log_ignore_stderr_once" + local loglevel ++ ++ # always reset this variable ++ __ha_log_ignore_stderr_once="" ++ + [ none = "$HA_LOGFACILITY" ] && HA_LOGFACILITY="" + # if we're connected to a tty, then output to stderr + if tty >/dev/null; then + if [ "x$HA_debug" = "x0" -a "x$loglevel" = xdebug ] ; then + return 0 ++ elif [ "$ignore_stderr" = "true" ]; then ++ # something already printed this error to stderr, so ignore ++ return 0 + fi + if [ "$HA_LOGTAG" ]; then + echo "$HA_LOGTAG: $*" +@@ -226,7 +242,7 @@ ha_log() { + echo "$HA_LOGTAG: "`hadate`"${*}" >> $HA_LOGFILE + fi + if +- [ -z "$HA_LOGFACILITY" -a -z "$HA_LOGFILE" ] ++ [ -z "$HA_LOGFACILITY" -a -z "$HA_LOGFILE" ] && ! [ "$ignore_stderr" = "true" ] + then + : appending to stderr + echo `hadate`"${*}" >&2 +@@ -331,6 +347,36 @@ ocf_log() { + } + + # ++# ocf_exit_reason: print exit error string to stderr ++# Usage: Allows the OCF script to provide a string ++# describing why the exit code was returned. ++# Arguments: reason - required, The string that represents why the error ++# occured. ++# ++ocf_exit_reason() ++{ ++ local cookie="$OCF_EXIT_REASON_PREFIX" ++ local fmt=$1 ++ local msg ++ ++ if [ $# -lt 1 ]; then ++ ocf_log err "Not enough arguments [$#] to ocf_log_exit_msg." ++ fi ++ if [ -z "$cookie" ]; then ++ # use a default prefix ++ cookie="ocf-exit-reason:" ++ fi ++ ++ shift ++ ++ msg=$(printf "${fmt}" "$@") ++ ++ printf >&2 "%s${msg}\n" "$cookie" ++ __ha_log_ignore_stderr_once="true" ++ ha_log "ERROR: $msg" ++} ++ ++# + # ocf_deprecated: Log a deprecation warning + # Usage: ocf_deprecated [param-name] + # Arguments: param-name optional, name of a boolean resource +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-nfsnotify-exit-reason-support.patch b/SOURCES/bz1128933-nfsnotify-exit-reason-support.patch new file mode 100644 index 0000000..2696b3a --- /dev/null +++ b/SOURCES/bz1128933-nfsnotify-exit-reason-support.patch @@ -0,0 +1,52 @@ +From 566544cb98bc4e373ac75fa8c6281ef031a673ca Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 1 Aug 2014 13:13:39 -0400 +Subject: [PATCH] High: nfsnotify: set exit reason strings in nfsnotify agent + +--- + heartbeat/nfsnotify | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/heartbeat/nfsnotify b/heartbeat/nfsnotify +index 2d0bbfc..5f72d58 100755 +--- a/heartbeat/nfsnotify ++++ b/heartbeat/nfsnotify +@@ -152,7 +152,7 @@ check_statd_pidfile() + return $OCF_SUCCESS + fi + +- ocf_log err "$(cat $pidfile) for $binary is no longer running, sm-notify needs to re-notify clients" ++ ocf_exit_reason "$(cat $pidfile) for $binary is no longer running, sm-notify needs to re-notify clients" + return $OCF_ERR_GENERIC + fi + +@@ -179,7 +179,7 @@ write_statd_pid() + return $OCF_NOT_RUNNING;; + *) + rm -f "$pidfile" > /dev/null 2>&1 +- ocf_log err "Error encountered detecting pid status of $binary" ++ ocf_exit_reason "Error encountered detecting pid status of $binary" + return $OCF_ERR_GENERIC;; + esac + } +@@ -243,7 +243,7 @@ v3notify_start() + ocf_log info "sending notifications on default source address." + $SM_NOTIFY_BINARY -f $OCF_RESKEY_notify_args -P $cur_statd + if [ $? -ne 0 ]; then +- ocf_log err "sm-notify failed, view syslog for more information." ++ ocf_exit_reason "sm-notify execution failed, view syslog for more information" + return $OCF_ERR_GENERIC + fi + +@@ -269,7 +269,7 @@ v3notify_start() + ocf_log info "sending notifications with source address $ip" + $SM_NOTIFY_BINARY -f $OCF_RESKEY_notify_args -v $ip -P "$cur_statd" + if [ $? -ne 0 ]; then +- ocf_log err "sm-notify with source host set to, $ip, failed. view syslog for more information" ++ ocf_exit_reason "sm-notify with source host set to [ $ip ] failed. view syslog for more information" + return $OCF_ERR_GENERIC + fi + done +-- +1.8.4.2 + diff --git a/SOURCES/bz1128933-nfssserver-exit-reason-support.patch b/SOURCES/bz1128933-nfssserver-exit-reason-support.patch new file mode 100644 index 0000000..b1b643b --- /dev/null +++ b/SOURCES/bz1128933-nfssserver-exit-reason-support.patch @@ -0,0 +1,97 @@ +From dab933121dfff2b4e9c141c141a196ddc40e9d56 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Fri, 1 Aug 2014 13:21:11 -0400 +Subject: [PATCH] High: nfsserver: support exit string in nfsserver agent + +--- + heartbeat/nfsserver | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver +index ac921f3..de1a802 100755 +--- a/heartbeat/nfsserver ++++ b/heartbeat/nfsserver +@@ -317,7 +317,7 @@ set_exec_mode() + fi + fi + +- ocf_log err "No init script or systemd unit file detected for nfs server" ++ ocf_exit_reason "No init script or systemd unit file detected for nfs server" + exit $OCF_ERR_INSTALLED + } + +@@ -366,7 +366,7 @@ nfsserver_monitor () + v3locking_exec "status" + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log error "NFS server is up, but the locking daemons are down" ++ ocf_exit_reason "NFS server is up, but the locking daemons are down" + rc=$OCF_ERR_GENERIC + fi + return $rc +@@ -682,7 +682,7 @@ nfsserver_start () + v3locking_exec "start" + rc=$? + if [ $rc -ne 0 ]; then +- ocf_log error "Failed to start NFS server locking daemons" ++ ocf_exit_reason "Failed to start NFS server locking daemons" + return $rc + fi + else +@@ -696,7 +696,7 @@ nfsserver_start () + rm -f $fn + + if [ $rc -ne 0 ]; then +- ocf_log err "Failed to start NFS server" ++ ocf_exit_reason "Failed to start NFS server" + return $rc + fi + +@@ -723,16 +723,16 @@ nfsserver_stop () + + v3locking_exec "stop" + if [ $? -ne 0 ]; then +- ocf_log err "Failed to stop NFS locking daemons" ++ ocf_exit_reason "Failed to stop NFS locking daemons" + rc=$OCF_ERR_GENERIC + fi + + if [ $rc -eq 0 ]; then + unbind_tree + ocf_log info "NFS server stopped" +- return $OCF_SUCCESS ++ else ++ ocf_exit_reason "Failed to stop NFS server" + fi +- ocf_log err "Failed to stop NFS server" + return $rc + } + +@@ -746,13 +746,13 @@ nfsserver_validate () + + + if [ -n "$OCF_RESKEY_CRM_meta_clone" ] && [ -n "$OCF_RESKEY_nfs_shared_infodir" ]; then +- ocf_log err "This RA does not support clone mode when a shared info directory is in use." ++ ocf_exit_reason "This RA does not support clone mode when a shared info directory is in use." + exit $OCF_ERR_CONFIGURED + fi + + if [ -n "$OCF_RESKEY_nfs_smnotify_retry_time" ]; then + if ! ocf_is_decimal "$OCF_RESKEY_nfs_smnotify_retry_time"; then +- ocf_log err "Invalid nfs_smnotify_retry_time [$OCF_RESKEY_nfs_smnotify_retry_time]" ++ ocf_exit_reason "Invalid nfs_smnotify_retry_time [$OCF_RESKEY_nfs_smnotify_retry_time]" + exit $OCF_ERR_CONFIGURED + fi + fi +@@ -760,7 +760,7 @@ nfsserver_validate () + case ${OCF_RESKEY_nfs_notify_cmd##*/} in + sm-notify|rpc.statd) ;; + *) +- ocf_log err "Invalid nfs_notify_cmd [$OCF_RESKEY_nfs_notify_cmd]" ++ ocf_exit_reason "Invalid nfs_notify_cmd [$OCF_RESKEY_nfs_notify_cmd]" + exit $OCF_ERR_CONFIGURED + ;; + esac +-- +1.8.4.2 + diff --git a/SOURCES/bz1135026-docker-handle-invalid-monitor-cmd.patch b/SOURCES/bz1135026-docker-handle-invalid-monitor-cmd.patch new file mode 100644 index 0000000..c9e8293 --- /dev/null +++ b/SOURCES/bz1135026-docker-handle-invalid-monitor-cmd.patch @@ -0,0 +1,69 @@ +From c25542d8808640fae7fad39e27e95e83ffde2e31 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 27 Oct 2014 18:22:27 -0400 +Subject: [PATCH] Low: docker: indicate when monitor_cmd is not available after + startup + +--- + heartbeat/docker | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/heartbeat/docker b/heartbeat/docker +index 929b26b..a0dcee4 100755 +--- a/heartbeat/docker ++++ b/heartbeat/docker +@@ -168,15 +168,28 @@ END + monitor_cmd_exec() + { + local rc=$OCF_SUCCESS +- if [ -n "$OCF_RESKEY_monitor_cmd" ]; then +- out=$(echo "$OCF_RESKEY_monitor_cmd" | nsenter --target $(docker inspect --format {{.State.Pid}} ${CONTAINER}) --mount --uts --ipc --net --pid 2>&1) +- rc=$? +- if [ $rc -ne 0 ]; then +- ocf_log info "monitor cmd failed with exit code $rc" +- ocf_log info "stdout/stderr: $out" +- rc=$OCF_ERR_GENERIC ++ local out ++ ++ if [ -z "$OCF_RESKEY_monitor_cmd" ]; then ++ return $rc ++ fi ++ ++ out=$(echo "$OCF_RESKEY_monitor_cmd" | nsenter --target $(docker inspect --format {{.State.Pid}} ${CONTAINER}) --mount --uts --ipc --net --pid 2>&1) ++ rc=$? ++ if [ $rc -ne 0 ]; then ++ ocf_log info "monitor cmd exit code = $rc" ++ ocf_log info "stdout/stderr: $out" ++ ++ if [ $rc -eq 127 ]; then ++ ocf_exit_reason "monitor_cmd, ${OCF_RESKEY_monitor_cmd} , not found within container." ++ # there is no recovering from this, exit immediately ++ exit $OCF_ERR_ARGS + fi ++ rc=$OCF_ERR_GENERIC ++ else ++ ocf_log info "monitor cmd passed: exit code = $rc" + fi ++ + return $rc + } + +@@ -288,6 +301,7 @@ docker_start() + + monitor_cmd_exec + if [ $? -eq $OCF_SUCCESS ]; then ++ ocf_log notice "Container $CONTAINER started successfully" + return $OCF_SUCCESS + fi + +@@ -365,6 +379,7 @@ docker_validate() + fi + + if [ -n "$OCF_RESKEY_monitor_cmd" ]; then ++ ocf_log info "checking for nsenter, which is required when 'monitor_cmd' is specified" + check_binary nsenter + fi + +-- +1.8.4.2 + diff --git a/SOURCES/bz1135026-docker-monitor_cmd-arg.patch b/SOURCES/bz1135026-docker-monitor_cmd-arg.patch new file mode 100644 index 0000000..6a692c2 --- /dev/null +++ b/SOURCES/bz1135026-docker-monitor_cmd-arg.patch @@ -0,0 +1,145 @@ +From 804b68824372f98e23b858f6284160c1f2b0e19f Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Sat, 25 Oct 2014 20:54:14 -0400 +Subject: [PATCH 2/2] High: docker: monitor_cmd option for executing status + script within container + +--- + heartbeat/docker | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 67 insertions(+), 9 deletions(-) + +diff --git a/heartbeat/docker b/heartbeat/docker +index cdf4e82..929b26b 100755 +--- a/heartbeat/docker ++++ b/heartbeat/docker +@@ -106,6 +106,20 @@ it has initialized. + + + ++ ++ ++Specifiy the full path of a command to launch within the container to check ++the health of the container. This command must return 0 to indicate that ++the container is healthy. A non-zero return code will indicate that the ++container has failed and should be recovered. ++ ++The command is executed using nsenter. In the future 'docker exec' will ++be used once it is more widely supported. ++ ++monitor command ++ ++ ++ + + + Kill a container immediately rather than waiting for it to gracefully +@@ -150,6 +164,22 @@ Expects to have a fully populated OCF RA-compliant environment set. + END + } + ++ ++monitor_cmd_exec() ++{ ++ local rc=$OCF_SUCCESS ++ if [ -n "$OCF_RESKEY_monitor_cmd" ]; then ++ out=$(echo "$OCF_RESKEY_monitor_cmd" | nsenter --target $(docker inspect --format {{.State.Pid}} ${CONTAINER}) --mount --uts --ipc --net --pid 2>&1) ++ rc=$? ++ if [ $rc -ne 0 ]; then ++ ocf_log info "monitor cmd failed with exit code $rc" ++ ocf_log info "stdout/stderr: $out" ++ rc=$OCF_ERR_GENERIC ++ fi ++ fi ++ return $rc ++} ++ + container_exists() + { + docker inspect $CONTAINER > /dev/null 2>&1 +@@ -171,7 +201,7 @@ remove_container() + ocf_run docker rm $CONTAINER + } + +-docker_monitor() ++docker_simple_status() + { + local val + +@@ -195,11 +225,25 @@ docker_monitor() + return $OCF_NOT_RUNNING + } + ++docker_monitor() ++{ ++ local rc=0 ++ ++ docker_simple_status ++ rc=$? ++ ++ if [ $rc -ne 0 ]; then ++ return $rc ++ fi ++ ++ monitor_cmd_exec ++} ++ + docker_start() + { + local run_opts="-d --name=${CONTAINER}" + # check to see if the container has already started +- docker_monitor ++ docker_simple_status + if [ $? -eq $OCF_SUCCESS ]; then + return $OCF_SUCCESS + fi +@@ -233,19 +277,29 @@ docker_start() + return $OCF_ERR_GENERIC + fi + +- docker_monitor +- if [ $? -ne $OCF_SUCCESS ]; then +- ocf_exit_reason "Newly created docker container exited after start" +- return $OCF_ERR_GENERIC +- fi + +- return $OCF_SUCCESS ++ # wait for monitor to pass before declaring that the container is started ++ while true; do ++ docker_simple_status ++ if [ $? -ne $OCF_SUCCESS ]; then ++ ocf_exit_reason "Newly created docker container exited after start" ++ return $OCF_ERR_GENERIC ++ fi ++ ++ monitor_cmd_exec ++ if [ $? -eq $OCF_SUCCESS ]; then ++ return $OCF_SUCCESS ++ fi ++ ++ ocf_exit_reason "waiting on monitor_cmd to pass after start" ++ sleep 1 ++ done + } + + docker_stop() + { + local timeout=60 +- docker_monitor ++ docker_simple_status + if [ $? -eq $OCF_NOT_RUNNING ]; then + remove_container + return $OCF_SUCCESS +@@ -310,6 +364,10 @@ docker_validate() + exit $OCF_ERR_CONFIGURED + fi + ++ if [ -n "$OCF_RESKEY_monitor_cmd" ]; then ++ check_binary nsenter ++ fi ++ + image_exists + if [ $? -ne 0 ]; then + ocf_exit_reason "base image, ${OCF_RESKEY_image}, could not be found." +-- +1.8.4.2 + diff --git a/SOURCES/bz1135026-docker-name-arg.patch b/SOURCES/bz1135026-docker-name-arg.patch new file mode 100644 index 0000000..3407414 --- /dev/null +++ b/SOURCES/bz1135026-docker-name-arg.patch @@ -0,0 +1,61 @@ +From 0f1b107a50dd2ba51277f6962dd0c28dfb8976fc Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Sat, 25 Oct 2014 20:23:55 -0400 +Subject: [PATCH 1/2] High: docker: replace 'container' argument with 'name' + +I realized that the 'container' argument means something special in +pacemaker. In order to avoid confusion, the 'container' argument for +this agent has been changed to 'name'. Anyone using 'container' as +an argument right now will not be affected. The option still works, it +is depreciated now though. +--- + heartbeat/docker | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/heartbeat/docker b/heartbeat/docker +index 37a449b..cdf4e82 100755 +--- a/heartbeat/docker ++++ b/heartbeat/docker +@@ -59,7 +59,7 @@ The docker image to base this container off of. + + + +- ++ + + The name to give the created container. By default this will + be that resource's instance name. +@@ -87,6 +87,11 @@ users to do things such as setting a custom entry point and injecting + environment variables into the newly created container. Note the '-d' + option is supplied regardless of this value to force containers to run + in the background. ++ ++NOTE: Do not explicitly specify the --name argument in the run_opts. This ++agent will set --name using either the resource's instance or the name ++provided in the 'name' argument of this agent. ++ + + run options + +@@ -314,8 +319,16 @@ docker_validate() + return $OCF_SUCCESS + } + +-: ${OCF_RESKEY_container=${OCF_RESOURCE_INSTANCE}} +-CONTAINER=$OCF_RESKEY_container ++: ${OCF_RESKEY_name=${OCF_RESOURCE_INSTANCE}} ++ ++if [ -n "$OCF_RESKEY_container" ]; then ++ # we'll keep the container attribute around for a bit in order not to break ++ # any existing deployments. The 'name' attribute is prefered now though. ++ CONTAINER=$OCF_RESKEY_container ++ ocf_log warn "The 'container' attribute is depreciated" ++else ++ CONTAINER=$OCF_RESKEY_name ++fi + + case $__OCF_ACTION in + meta-data) meta_data +-- +1.8.4.2 + diff --git a/SOURCES/bz1135026-docker-stop-fix.patch b/SOURCES/bz1135026-docker-stop-fix.patch new file mode 100644 index 0000000..bd4bc8f --- /dev/null +++ b/SOURCES/bz1135026-docker-stop-fix.patch @@ -0,0 +1,49 @@ +From 05fb27218f3b8a78bff0b0e668c8d38feeb93dca Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Thu, 23 Oct 2014 14:20:14 -0400 +Subject: [PATCH] High: docker: properly remove stale container during stop + when 'reuse' is not enabled + +--- + heartbeat/docker | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/heartbeat/docker b/heartbeat/docker +index 546c423..37a449b 100755 +--- a/heartbeat/docker ++++ b/heartbeat/docker +@@ -157,6 +157,11 @@ remove_container() + return 0 + fi + ++ container_exists ++ if [ $? -ne 0 ]; then ++ # don't attempt to remove a container that doesn't exist ++ return 0 ++ fi + ocf_log notice "Cleaning up inactive container, ${CONTAINER}." + ocf_run docker rm $CONTAINER + } +@@ -210,7 +215,10 @@ docker_start() + if ocf_is_true "$OCF_RESKEY_reuse" && container_exists; then + ocf_log info "starting existing container $CONTAINER." + ocf_run docker start $CONTAINER +- else ++ else ++ # make sure any previous container matching our container name is cleaned up first. ++ # we already know at this point it wouldn't be running ++ remove_container + ocf_log info "running container $CONTAINER for the first time" + ocf_run docker run $run_opts $OCF_RESKEY_image $OCF_RESKEY_run_cmd + fi +@@ -234,6 +242,7 @@ docker_stop() + local timeout=60 + docker_monitor + if [ $? -eq $OCF_NOT_RUNNING ]; then ++ remove_container + return $OCF_SUCCESS + fi + +-- +1.8.4.2 + diff --git a/SOURCES/bz1135026-introducing-docker-agent.patch b/SOURCES/bz1135026-introducing-docker-agent.patch new file mode 100644 index 0000000..aa05b7a --- /dev/null +++ b/SOURCES/bz1135026-introducing-docker-agent.patch @@ -0,0 +1,375 @@ +From 6d4180b5ed46cda544e008b242f024b2ab143a83 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Thu, 23 Oct 2014 09:37:18 -0500 +Subject: [PATCH] introducing docker agent + +--- + doc/man/Makefile.am | 1 + + heartbeat/Makefile.am | 1 + + heartbeat/docker | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 332 insertions(+) + create mode 100755 heartbeat/docker + +diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am +index e97c7e9..ee29756 100644 +--- a/doc/man/Makefile.am ++++ b/doc/man/Makefile.am +@@ -98,6 +98,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ + ocf_heartbeat_conntrackd.7 \ + ocf_heartbeat_db2.7 \ + ocf_heartbeat_dhcpd.7 \ ++ ocf_heartbeat_docker.7 \ + ocf_heartbeat_eDir88.7 \ + ocf_heartbeat_ethmonitor.7 \ + ocf_heartbeat_exportfs.7 \ +diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am +index aab521f..f763533 100644 +--- a/heartbeat/Makefile.am ++++ b/heartbeat/Makefile.am +@@ -65,6 +65,7 @@ ocf_SCRIPTS = ClusterMon \ + conntrackd \ + db2 \ + dhcpd \ ++ docker \ + Delay \ + eDir88 \ + EvmsSCC \ +diff --git a/heartbeat/docker b/heartbeat/docker +new file mode 100755 +index 0000000..546c423 +--- /dev/null ++++ b/heartbeat/docker +@@ -0,0 +1,330 @@ ++#!/bin/sh ++# ++# The docker HA resource agent creates and launches a docker container ++# based off a supplied docker image. Containers managed by this agent ++# are both created and removed upon the agent's start and stop actions. ++# ++# Copyright (c) 2014 David Vossel ++# All Rights Reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it would be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++# ++# Further, this software is distributed without any warranty that it is ++# free of the rightful claim of any third person regarding infringement ++# or the like. Any license provided herein, whether implied or ++# otherwise, applies only to this software file. Patent licenses, if ++# any, provided herein do not apply to combinations of this program with ++# other software, or any other product whatsoever. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write the Free Software Foundation, ++# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++# ++ ++####################################################################### ++# Initialization: ++ ++: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} ++. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ++ ++####################################################################### ++ ++meta_data() ++{ ++ cat < ++ ++ ++1.0 ++ ++ ++The docker HA resource agent creates and launches a docker container ++based off a supplied docker image. Containers managed by this agent ++are both created and removed upon the agent's start and stop actions. ++ ++Docker container resource agent. ++ ++ ++ ++ ++The docker image to base this container off of. ++ ++docker image ++ ++ ++ ++ ++ ++The name to give the created container. By default this will ++be that resource's instance name. ++ ++docker container name ++ ++ ++ ++ ++ ++Allow the image to be pulled from the configured docker registry when ++the image does not exist locally. NOTE, this can drastically increase ++the time required to start the container if the image repository is ++pulled over the network. ++ ++Allow pulling non-local images ++ ++ ++ ++ ++ ++Add options to be appended to the 'docker run' command which is used ++when creating the container during the start action. This option allows ++users to do things such as setting a custom entry point and injecting ++environment variables into the newly created container. Note the '-d' ++option is supplied regardless of this value to force containers to run ++in the background. ++ ++run options ++ ++ ++ ++ ++ ++Specifiy a command to launch within the container once ++it has initialized. ++ ++run command ++ ++ ++ ++ ++ ++Kill a container immediately rather than waiting for it to gracefully ++shutdown ++ ++force kill ++ ++ ++ ++ ++ ++Allow the container to be reused after stopping the container. By default ++containers are removed after stop. With the reuse option containers ++will persist after the container stops. ++ ++reuse container ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++END ++} ++ ++####################################################################### ++REQUIRE_IMAGE_PULL=0 ++ ++docker_usage() ++{ ++ cat < /dev/null 2>&1 ++} ++ ++remove_container() ++{ ++ if ocf_is_true "$OCF_RESKEY_reuse"; then ++ # never remove the container if we have reuse enabled. ++ return 0 ++ fi ++ ++ ocf_log notice "Cleaning up inactive container, ${CONTAINER}." ++ ocf_run docker rm $CONTAINER ++} ++ ++docker_monitor() ++{ ++ local val ++ ++ container_exists ++ if [ $? -ne 0 ]; then ++ return $OCF_NOT_RUNNING ++ fi ++ ++ # retrieve the 'Running' attribute for the container ++ val=$(docker inspect --format {{.State.Running}} $CONTAINER 2>/dev/null) ++ if [ $? -ne 0 ]; then ++ #not running as a result of container not being found ++ return $OCF_NOT_RUNNING ++ fi ++ ++ if ocf_is_true "$val"; then ++ # container exists and is running ++ return $OCF_SUCCESS ++ fi ++ ++ return $OCF_NOT_RUNNING ++} ++ ++docker_start() ++{ ++ local run_opts="-d --name=${CONTAINER}" ++ # check to see if the container has already started ++ docker_monitor ++ if [ $? -eq $OCF_SUCCESS ]; then ++ return $OCF_SUCCESS ++ fi ++ ++ if [ -n "$OCF_RESKEY_run_opts" ]; then ++ run_opts="$run_opts $OCF_RESKEY_run_opts" ++ fi ++ ++ if [ $REQUIRE_IMAGE_PULL -eq 1 ]; then ++ ocf_log notice "Beginning pull of image, ${OCF_RESKEY_image}" ++ docker pull "${OCF_RESKEY_image}" ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "failed to pull image ${OCF_RESKEY_image}" ++ return $OCF_ERR_GENERIC ++ fi ++ fi ++ ++ if ocf_is_true "$OCF_RESKEY_reuse" && container_exists; then ++ ocf_log info "starting existing container $CONTAINER." ++ ocf_run docker start $CONTAINER ++ else ++ ocf_log info "running container $CONTAINER for the first time" ++ ocf_run docker run $run_opts $OCF_RESKEY_image $OCF_RESKEY_run_cmd ++ fi ++ ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "docker failed to launch container" ++ return $OCF_ERR_GENERIC ++ fi ++ ++ docker_monitor ++ if [ $? -ne $OCF_SUCCESS ]; then ++ ocf_exit_reason "Newly created docker container exited after start" ++ return $OCF_ERR_GENERIC ++ fi ++ ++ return $OCF_SUCCESS ++} ++ ++docker_stop() ++{ ++ local timeout=60 ++ docker_monitor ++ if [ $? -eq $OCF_NOT_RUNNING ]; then ++ return $OCF_SUCCESS ++ fi ++ ++ if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then ++ timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000) -10 )) ++ if [ $timeout -lt 10 ]; then ++ timeout=10 ++ fi ++ fi ++ ++ if ocf_is_true "$OCF_RESKEY_force_kill"; then ++ ocf_run docker kill $CONTAINER ++ else ++ ocf_log debug "waiting $timeout second[s] before killing container" ++ ocf_run docker stop -t=$timeout $CONTAINER ++ fi ++ ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "Failed to stop container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}." ++ return $OCF_ERR_GENERIC ++ fi ++ ++ remove_container ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "Failed to remove stopped container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}." ++ return $OCF_ERR_GENERIC ++ fi ++ ++ return $OCF_SUCCESS ++} ++ ++image_exists() ++{ ++ local res=1 ++ ++ ++ echo "${OCF_RESKEY_image}" | grep -q ":" ++ if [ $? -eq 0 ]; then ++ docker images | awk '{print $1 ":" $2}' | grep "^${OCF_RESKEY_image}\$" > /dev/null 2>&1 ++ else ++ docker images | awk '{print $1}' | grep "^${OCF_RESKEY_image}\$" > /dev/null 2>&1 ++ fi ++ if [ $? -eq 0 ]; then ++ return 0 ++ fi ++ if ocf_is_true "$OCF_RESKEY_allow_pull"; then ++ REQUIRE_IMAGE_PULL=1 ++ ocf_log notice "Image (${OCF_RESKEY_image}) does not exist locally but will be pulled during start" ++ return 0 ++ fi ++ # image not found. ++ return 1 ++} ++ ++docker_validate() ++{ ++ check_binary docker ++ if [ -z "$OCF_RESKEY_image" ]; then ++ ocf_exit_reason "'image' option is required" ++ exit $OCF_ERR_CONFIGURED ++ fi ++ ++ image_exists ++ if [ $? -ne 0 ]; then ++ ocf_exit_reason "base image, ${OCF_RESKEY_image}, could not be found." ++ exit $OCF_ERR_CONFIGURED ++ fi ++ ++ return $OCF_SUCCESS ++} ++ ++: ${OCF_RESKEY_container=${OCF_RESOURCE_INSTANCE}} ++CONTAINER=$OCF_RESKEY_container ++ ++case $__OCF_ACTION in ++meta-data) meta_data ++ exit $OCF_SUCCESS;; ++start) ++ docker_validate ++ docker_start;; ++stop) docker_stop;; ++monitor) docker_monitor;; ++validate-all) docker_validate;; ++usage|help) docker_usage ++ exit $OCF_SUCCESS ++ ;; ++*) docker_usage ++ exit $OCF_ERR_UNIMPLEMENTED ++ ;; ++esac ++rc=$? ++ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" ++exit $rc ++ +-- +1.8.4.2 + diff --git a/SOURCES/bz1138871-avoid-check-binary-in-validate.patch b/SOURCES/bz1138871-avoid-check-binary-in-validate.patch new file mode 100644 index 0000000..1cc2b62 --- /dev/null +++ b/SOURCES/bz1138871-avoid-check-binary-in-validate.patch @@ -0,0 +1,43 @@ +From 328b228321e71260f9c0ea4b926b43f208aef158 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Tue, 7 Oct 2014 16:11:28 -0400 +Subject: [PATCH 2/2] High: mysql-common: avoid use of check_binary in common + validation function. + +Since the environment validation exit code needs to be interpreted +differently now for monitor operations, we need to avoid functions like +'check_binary' that exit the process immediately upon failure. Instead +we should use 'have_binary' in this situation. + +This allows the mysql agent to work properly in a scenario where the entire +mysql install resides on shared storage. +--- + heartbeat/mysql-common.sh | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/heartbeat/mysql-common.sh b/heartbeat/mysql-common.sh +index a02f8cd..310f487 100755 +--- a/heartbeat/mysql-common.sh ++++ b/heartbeat/mysql-common.sh +@@ -94,8 +94,16 @@ CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INST + + mysql_common_validate() + { +- check_binary $OCF_RESKEY_binary +- check_binary $OCF_RESKEY_client_binary ++ ++ if ! have_binary "$OCF_RESKEY_binary"; then ++ ocf_exit_reason "Setup problem: couldn't find command: $OCF_RESKEY_binary" ++ return $OCF_ERR_INSTALLED; ++ fi ++ ++ if ! have_binary "$OCF_RESKEY_client_binary"; then ++ ocf_exit_reason "Setup problem: couldn't find command: $OCF_RESKEY_client_binary" ++ return $OCF_ERR_INSTALLED; ++ fi + + if [ ! -f $OCF_RESKEY_config ]; then + ocf_exit_reason "Config $OCF_RESKEY_config doesn't exist"; +-- +1.8.4.2 + diff --git a/SOURCES/bz1138871-mysql-error-validation-fails-monitor.patch b/SOURCES/bz1138871-mysql-error-validation-fails-monitor.patch new file mode 100644 index 0000000..7090170 --- /dev/null +++ b/SOURCES/bz1138871-mysql-error-validation-fails-monitor.patch @@ -0,0 +1,35 @@ +From 6ac8332d16837a3481341316e61962e6f78694dd Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Tue, 7 Oct 2014 16:11:19 -0400 +Subject: [PATCH 1/2] High: mysql: report error when validation fails during + monitor yet pid is still active + +--- + heartbeat/mysql | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/heartbeat/mysql b/heartbeat/mysql +index 6cfe0a0..d895369 100755 +--- a/heartbeat/mysql ++++ b/heartbeat/mysql +@@ -1007,7 +1007,16 @@ LSB_STATUS_STOPPED=3 + if [ $rc -ne 0 ]; then + case "$1" in + stop) ;; +- monitor) exit $OCF_NOT_RUNNING;; ++ monitor) ++ mysql_common_status "info" ++ if [ $? -eq $OCF_SUCCESS ]; then ++ # if validatation fails and pid is active, always treat this as an error ++ ocf_exit_reason "environment validation failed, active pid is in unknown state." ++ exit $OCF_ERR_GENERIC ++ fi ++ # validation failed and pid is not active, it's safe to say this instance is inactive. ++ exit $OCF_NOT_RUNNING;; ++ + status) exit $LSB_STATUS_STOPPED;; + *) exit $rc;; + esac +-- +1.8.4.2 + diff --git a/SOURCES/bz1138871_mysql_stop_fix.patch b/SOURCES/bz1138871_mysql_stop_fix.patch new file mode 100644 index 0000000..2787847 --- /dev/null +++ b/SOURCES/bz1138871_mysql_stop_fix.patch @@ -0,0 +1,26 @@ +From 42a016eb56d79f287190f3abe68c2a7e1b3ca50b Mon Sep 17 00:00:00 2001 +From: John Ruemker +Date: Wed, 17 Sep 2014 18:02:03 -0400 +Subject: [PATCH] High: mysql: do not report success on 'stop' if validation + fails + +--- + heartbeat/mysql | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/heartbeat/mysql b/heartbeat/mysql +index dc862f5..6cfe0a0 100755 +--- a/heartbeat/mysql ++++ b/heartbeat/mysql +@@ -1006,7 +1006,7 @@ rc=$? + LSB_STATUS_STOPPED=3 + if [ $rc -ne 0 ]; then + case "$1" in +- stop) exit $OCF_SUCCESS;; ++ stop) ;; + monitor) exit $OCF_NOT_RUNNING;; + status) exit $LSB_STATUS_STOPPED;; + *) exit $rc;; +-- +1.8.4.2 + diff --git a/SOURCES/bz773395-clvm-autoset-locking-type.patch b/SOURCES/bz773395-clvm-autoset-locking-type.patch new file mode 100644 index 0000000..c1ef716 --- /dev/null +++ b/SOURCES/bz773395-clvm-autoset-locking-type.patch @@ -0,0 +1,41 @@ +From 22203b45ef3c3a66512c60f2a2381cf5e490abf6 Mon Sep 17 00:00:00 2001 +From: David Vossel +Date: Mon, 4 Aug 2014 17:23:47 -0400 +Subject: [PATCH] High: clvm: automatically set lvm.conf's locking_type=3 + +lvm comes with a cli tool we can use to set/unset the +locking type. When clvmd is in use, it is safe to assume +that locking_type=3 (clustered locking) should be in use. +Otherwise there would be no reason to run the clvmd to begin +with. +--- + heartbeat/clvm | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/heartbeat/clvm b/heartbeat/clvm +index 3e7701d..20bb40c 100644 +--- a/heartbeat/clvm ++++ b/heartbeat/clvm +@@ -86,6 +86,7 @@ DAEMON="clvmd" + CMIRROR="cmirrord" + DAEMON_PATH="${sbindir}/clvmd" + CMIRROR_PATH="${sbindir}/cmirrord" ++LVMCONF="${sbindir}/lvmconf" + LOCK_FILE="/var/lock/subsys/$DAEMON" + LVM_VGCHANGE=${sbindir}/vgchange + LVM_VGDISPLAY=${sbindir}/vgdisplay +@@ -342,6 +343,11 @@ clvmd_start() + return $?; + fi + ++ # autoset locking type to clusted when lvmconf tool is available ++ if [ -x "$LVMCONF" ]; then ++ $LVMCONF --enable-cluster > /dev/null 2>&1 ++ fi ++ + # if either of these fail, script will exit OCF_ERR_GENERIC + if ocf_is_true $OCF_RESKEY_with_cmirrord; then + start_process $CMIRROR_PATH +-- +1.8.4.2 + diff --git a/SOURCES/rabbitmq-cluster.patch b/SOURCES/rabbitmq-cluster.patch deleted file mode 100644 index b9c6b5c..0000000 --- a/SOURCES/rabbitmq-cluster.patch +++ /dev/null @@ -1,415 +0,0 @@ -From a06ce7c166f4a7801b1fb7d50c77dead8a0c7a1d Mon Sep 17 00:00:00 2001 -From: David Vossel -Date: Wed, 21 Jan 2015 18:00:18 -0500 -Subject: [PATCH] High: introducing rabbitmq clustering agent - ---- - doc/man/Makefile.am | 1 + - heartbeat/Makefile.am | 1 + - heartbeat/rabbitmq-cluster | 370 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 372 insertions(+) - create mode 100755 heartbeat/rabbitmq-cluster - -diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am -index eafb2d1..62e619a 100644 ---- a/doc/man/Makefile.am -+++ b/doc/man/Makefile.am -@@ -127,6 +127,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ - ocf_heartbeat_postfix.7 \ - ocf_heartbeat_pound.7 \ - ocf_heartbeat_proftpd.7 \ -+ ocf_heartbeat_rabbitmq-cluster.7 \ - ocf_heartbeat_rsyncd.7 \ - ocf_heartbeat_rsyslog.7 \ - ocf_heartbeat_scsi2reservation.7 \ -diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am -index 330b7f7..66dcff2 100644 ---- a/heartbeat/Makefile.am -+++ b/heartbeat/Makefile.am -@@ -106,6 +106,7 @@ ocf_SCRIPTS = ClusterMon \ - pgsql \ - proftpd \ - Pure-FTPd \ -+ rabbitmq-cluster \ - Raid1 \ - Route \ - rsyncd \ -diff --git a/heartbeat/rabbitmq-cluster b/heartbeat/rabbitmq-cluster -new file mode 100755 -index 0000000..b9dcfc3 ---- /dev/null -+++ b/heartbeat/rabbitmq-cluster -@@ -0,0 +1,370 @@ -+#!/bin/sh -+# -+# Copyright (c) 2014 David Vossel -+# All Rights Reserved. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of version 2 of the GNU General Public License as -+# published by the Free Software Foundation. -+# -+# This program is distributed in the hope that it would be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+# -+# Further, this software is distributed without any warranty that it is -+# free of the rightful claim of any third person regarding infringement -+# or the like. Any license provided herein, whether implied or -+# otherwise, applies only to this software file. Patent licenses, if -+# any, provided herein do not apply to combinations of this program with -+# other software, or any other product whatsoever. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write the Free Software Foundation, -+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+# -+ -+####################################################################### -+# Initialization: -+ -+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} -+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs -+ -+####################################################################### -+ -+RMQ_SERVER=/usr/sbin/rabbitmq-server -+RMQ_CTL=/usr/sbin/rabbitmqctl -+RMQ_DATA_DIR="/var/lib/rabbitmq/mnesia" -+RMQ_PID_DIR="/var/run/rabbitmq" -+RMQ_PID_FILE="/var/run/rabbitmq/rmq.pid" -+RMQ_LOG_DIR="/var/log/rabbitmq" -+NODENAME=$(ocf_local_nodename) -+ -+RMQ_CRM_ATTR_COOKIE="rmq-node-attr-${OCF_RESOURCE_INSTANCE}" -+ -+meta_data() { -+ cat < -+ -+ -+1.0 -+ -+ -+Starts cloned rabbitmq cluster instance -+ -+rabbitmq clustered -+ -+ -+ -+ -+Policy string to pass to 'rabbitmqctl set_policy' right after bootstrapping the first rabbitmq instance. -+ -+rabbitmqctl set_policy args -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+END -+} -+ -+####################################################################### -+ -+rmq_usage() { -+ cat < /dev/null 2>&1 -+} -+ -+rmq_local_node() -+{ -+ -+ local node_name=$(rabbitmqctl status 2>&1 | sed -n -e "s/^.*[S|s]tatus of node \(.*\)\s.*$/\1/p" | tr -d "'") -+ -+ if [ -z "$node_name" ]; then -+ node_name=$(cat /etc/rabbitmq/rabbitmq-env.conf 2>/dev/null | grep "\s*RABBITMQ_NODENAME=" | awk -F= '{print $2}') -+ fi -+ -+ echo "$node_name" -+} -+ -+rmq_join_list() -+{ -+ cibadmin -Q 2>/dev/null | grep "$RMQ_CRM_ATTR_COOKIE" | sed -n -e "s/^.*value=.\(.*\)\".*$/\1/p" -+} -+ -+rmq_write_nodename() -+{ -+ local node_name=$(rmq_local_node) -+ -+ if [ -z "$node_name" ]; then -+ ocf_log err "Failed to determine rabbitmq node name, exiting" -+ exit $OCF_ERR_GENERIC -+ fi -+ -+ # store the pcmknode to rmq node mapping as an attribute -+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "$RMQ_CRM_ATTR_COOKIE" -v "$node_name" -+} -+ -+rmq_delete_nodename() -+{ -+ # remove node-name -+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "$RMQ_CRM_ATTR_COOKIE" -D -+} -+ -+prepare_dir () { -+ if [ ! -d ${1} ] ; then -+ mkdir -p ${1} -+ chown -R rabbitmq:rabbitmq ${1} -+ chmod 755 ${1} -+ fi -+} -+ -+remove_pid () { -+ rm -f ${RMQ_PID_FILE} > /dev/null 2>&1 -+} -+ -+rmq_monitor() { -+ local rc -+ -+ $RMQ_CTL cluster_status > /dev/null 2>&1 -+ rc=$? -+ case "$rc" in -+ 0) -+ ocf_log debug "RabbitMQ server is running normally" -+ rmq_write_nodename -+ -+ return $OCF_SUCCESS -+ ;; -+ 2) -+ ocf_log info "RabbitMQ server is not running" -+ rmq_delete_nodename -+ return $OCF_NOT_RUNNING -+ ;; -+ *) -+ ocf_log err "Unexpected return code from '$RMQ_CTL cluster status' exit code: $rc" -+ rmq_delete_nodename -+ return $OCF_ERR_GENERIC -+ ;; -+ esac -+} -+ -+rmq_init_and_wait() -+{ -+ local rc -+ -+ prepare_dir $RMQ_PID_DIR -+ prepare_dir $RMQ_LOG_DIR -+ remove_pid -+ -+ # the server startup script uses this environment variable -+ export RABBITMQ_PID_FILE="$RMQ_PID_FILE" -+ -+ setsid sh -c "$RMQ_SERVER > ${RMQ_LOG_DIR}/startup_log 2> ${RMQ_LOG_DIR}/startup_err" & -+ -+ ocf_log info "Waiting for server to start" -+ $RMQ_CTL wait $RMQ_PID_FILE -+ rc=$? -+ if [ $rc -ne $OCF_SUCCESS ]; then -+ remove_pid -+ ocf_log info "rabbitmq-server start failed: $rc" -+ return $OCF_ERR_GENERIC -+ fi -+ -+ rmq_monitor -+ return $? -+} -+ -+rmq_set_policy() -+{ -+ $RMQ_CTL set_policy $@ > /dev/null 2>&1 -+} -+ -+rmq_start_first() -+{ -+ local rc -+ -+ ocf_log info "Bootstrapping rabbitmq cluster" -+ rmq_wipe_data -+ rmq_init_and_wait -+ rc=$? -+ -+ if [ $rc -eq 0 ]; then -+ rc=$OCF_SUCCESS -+ ocf_log info "cluster bootstrapped" -+ -+ if [ -n "$OCF_RESKEY_set_policy" ]; then -+ # do not quote set_policy, we are passing in arguments -+ rmq_set_policy $OCF_RESKEY_set_policy > /dev/null 2>&1 -+ if [ $? -ne 0 ]; then -+ ocf_log err "Failed to set policy: $OCF_RESKEY_set_policy" -+ rc=$OCF_ERR_GENERIC -+ else -+ ocf_log info "Policy set: $OCF_RESKEY_set_policy" -+ fi -+ fi -+ -+ else -+ ocf_log info "failed to bootstrap cluster. Check SELINUX policy" -+ rc=$OCF_ERR_GENERIC -+ fi -+ -+ return $rc -+} -+ -+rmq_join_existing() -+{ -+ local join_list="$1" -+ local rc=$OCF_ERR_GENERIC -+ -+ ocf_log info "Joining existing cluster with [ $(echo $join_list | tr '\n' ' ') ] nodes." -+ rmq_init_and_wait -+ if [ $? -ne 0 ]; then -+ return $OCF_ERR_GENERIC -+ fi -+ -+ # unconditionally join the cluster -+ $RMQ_CTL stop_app > /dev/null 2>&1 -+ for node in $(echo "$join_list"); do -+ ocf_log info "Attempting to join cluster with target node $node" -+ $RMQ_CTL join_cluster $node -+ if [ $? -eq 0 ]; then -+ ocf_log info "Joined cluster by connecting to node $node, starting app" -+ $RMQ_CTL start_app -+ rc=$? -+ if [ $rc -ne 0 ]; then -+ ocf_log err "'$RMQ_CTL start_app' failed" -+ fi -+ break; -+ fi -+ done -+ -+ if [ "$rc" -ne 0 ]; then -+ ocf_log info "Join process incomplete, shutting down." -+ return $OCF_ERR_GENERIC -+ fi -+ -+ ocf_log info "Successfully joined existing rabbitmq cluster" -+ return $OCF_SUCCESS -+} -+ -+rmq_start() { -+ local join_list="" -+ local rc -+ -+ rmq_monitor -+ if [ $? -eq $OCF_SUCCESS ]; then -+ return $OCF_SUCCESS -+ fi -+ -+ join_list=$(rmq_join_list) -+ -+ # No join list means no active instances are up. This instance -+ # is the first, so it needs to bootstrap the rest -+ if [ -z "$join_list" ]; then -+ rmq_start_first -+ rc=$? -+ return $rc -+ fi -+ -+ # first try to join without wiping mnesia data -+ rmq_join_existing "$join_list" -+ if [ $? -ne 0 ]; then -+ ocf_log info "node failed to join, wiping data directory and trying again" -+ # if the graceful join fails, use the hammer and reset all the data. -+ rmq_stop -+ rmq_wipe_data -+ rmq_join_existing "$join_list" -+ if [ $? -ne 0 ]; then -+ ocf_log info "node failed to join even after reseting local data. Check SELINUX policy" -+ return $OCF_ERR_GENERIC -+ fi -+ fi -+ -+ return $OCF_SUCCESS -+} -+ -+rmq_stop() { -+ rmq_monitor -+ if [ $? -eq $OCF_NOT_RUNNING ]; then -+ return $OCF_SUCCESS -+ fi -+ -+ $RMQ_CTL stop -+ rc=$? -+ -+ if [ $rc -ne 0 ]; then -+ ocf_log err "rabbitmq-server stop command failed: $RMQ_CTL stop, $rc" -+ return $rc -+ fi -+ -+ #TODO add kill logic -+ stop_wait=1 -+ while [ $stop_wait = 1 ]; do -+ rmq_monitor -+ rc=$? -+ if [ "$rc" -eq $OCF_NOT_RUNNING ]; then -+ stop_wait=0 -+ break -+ elif [ "$rc" -ne $OCF_SUCCESS ]; then -+ ocf_log info "rabbitmq-server stop failed: $rc" -+ exit $OCF_ERR_GENERIC -+ fi -+ sleep 1 -+ done -+ -+ remove_pid -+ return $OCF_SUCCESS -+} -+ -+rmq_validate() { -+ check_binary $RMQ_SERVER -+ check_binary $RMQ_CTL -+ -+ # This resource only makes sense as a clone right now. at some point -+ # we may want to verify the following. -+ #TODO verify cloned -+ #TODO verify ordered=true -+ -+ # Given that this resource does the cluster join explicitly, -+ # having a cluster_nodes list in the static config file will -+ # likely conflict with this agent. -+ #TODO verify no cluster list in rabbitmq conf -+ #cat /etc/rabbitmq/rabbitmq.config | grep "cluster_nodes" -+ -+ return $OCF_SUCCESS -+} -+ -+case $__OCF_ACTION in -+meta-data) meta_data -+ exit $OCF_SUCCESS -+ ;; -+start) rmq_start;; -+stop) rmq_stop;; -+monitor) rmq_monitor;; -+validate-all) rmq_validate;; -+usage|help) rmq_usage -+ exit $OCF_SUCCESS -+ ;; -+*) rmq_usage -+ exit $OCF_ERR_UNIMPLEMENTED -+ ;; -+esac -+rc=$? -+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" -+exit $rc -+ --- -1.8.4.2 - diff --git a/SPECS/resource-agents.spec b/SPECS/resource-agents.spec index bd53151..a0c04cc 100644 --- a/SPECS/resource-agents.spec +++ b/SPECS/resource-agents.spec @@ -32,7 +32,7 @@ Name: resource-agents Summary: Open Source HA Reusable Cluster Resource Scripts Version: 3.9.5 -Release: 26%{?dist}.7 +Release: 40%{?dist} License: GPLv2+ and LGPLv2+ URL: https://github.com/ClusterLabs/resource-agents %if 0%{?fedora} || 0%{?centos_version} || 0%{?rhel} @@ -62,12 +62,43 @@ Patch17: bz1029061-virtualdomain-parse-error.patch Patch18: bz1064512-clvmd-agent.patch Patch19: bz1060367-vm-monitor-wo-libvirtd.patch Patch20: bz1060367-vm-monitor-wo-libvirtd_2.patch -Patch21: bz1091101-nfs-updates.patch -Patch22: bz1091101-nfs-error-msg-fix.patch -Patch23: bz1091101-nfs-rquotad-port-option-fix.patch -Patch24: bz1116166-galera-agent.patch -Patch25: bz1116166-galera-updates.patch -Patch26: rabbitmq-cluster.patch +Patch21: bz1116166-galera-agent.patch +Patch22: bz1091101-nfs-updates.patch +Patch23: bz1091101-nfs-error-msg-fix.patch +Patch24: bz1091101-nfs-rquotad-port-option-fix.patch +Patch25: bz1083041-virtual-domain-monitor-lxc-fix.patch +Patch26: bz1083231-fs-wait-module-load.patch +Patch27: bz1097593-LVM-warn-lvmetad.patch +Patch28: bz1105655-virtualdomain-restore-start-stop-default-timeout.patch +Patch29: bz1128933-IPaddr2-exit-reason-support.patch +Patch30: bz1128933-VirtualDomain-exit-reason-support.patch +Patch31: bz1128933-binary-check-exit-reason-support.patch +Patch32: bz1128933-exportfs-exit-reason-support.patch +Patch33: bz1128933-introducing-exit-reason-support.patch +Patch34: bz1128933-nfsnotify-exit-reason-support.patch +Patch35: bz1128933-nfssserver-exit-reason-support.patch +Patch36: bz773395-clvm-autoset-locking-type.patch +Patch37: bz1058102-man-page-updates.patch +Patch38: bz1118029-iscsi-agents.patch +Patch39: bz1122285-ethmonitor-infiniband.patch +Patch40: bz1128933-exit-reason-string-updates.patch +Patch41: bz1095944-safe-umount-option.patch +Patch42: bz1118029_iscsi_syntax_fix.patch +Patch43: bz1138871_mysql_stop_fix.patch +Patch44: bz1116166-Low-galera-do-not-advertise-notify-in-the-usage.patch +Patch45: bz1116166-Low-galera-be-very-generous-in-the-promotion-timeout.patch +Patch46: bz1116166-galera-do-not-ignore-check_password.patch +Patch47: bz1128933-Fix-shellfuncs-fix-syntax-error-caused-by-exit_reaso.patch +Patch48: bz1128933-Fix-ocf_exit_reason-implicit-format-string-s-for-sin.patch +Patch49: bz1128933-Fix-ha_log-drop-global-__ha_log_ignore_stderr_once-h.patch +Patch50: bz1138871-avoid-check-binary-in-validate.patch +Patch51: bz1138871-mysql-error-validation-fails-monitor.patch +Patch52: bz1135026-introducing-docker-agent.patch +Patch53: bz1135026-docker-stop-fix.patch +Patch54: bz1135026-docker-name-arg.patch +Patch55: bz1135026-docker-monitor_cmd-arg.patch +Patch56: bz1135026-docker-handle-invalid-monitor-cmd.patch +Patch57: bz1118029-iscsi-remove-write-back.patch Obsoletes: heartbeat-resources <= %{version} Provides: heartbeat-resources = %{version} @@ -120,6 +151,8 @@ Requires: /usr/sbin/rpc.nfsd /sbin/rpc.statd /usr/sbin/rpc.mountd ## Runtime dependencies required to guarantee heartbeat agents ## are functional %if %{with linuxha} +# ethmonitor requires the bc calculator +Requires: bc # tools needed for Filesystem resource Requires: psmisc # Tools needed for clvm resource. @@ -180,6 +213,37 @@ exit 1 %patch24 -p1 %patch25 -p1 %patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 %build if [ ! -f configure ]; then @@ -189,7 +253,7 @@ fi chmod 755 heartbeat/galera chmod 755 heartbeat/mysql-common.sh chmod 755 heartbeat/nfsnotify -chmod 755 heartbeat/rabbitmq-cluster +chmod 755 heartbeat/docker %if 0%{?fedora} >= 11 || 0%{?centos_version} > 5 || 0%{?rhel} > 5 CFLAGS="$(echo '%{optflags}')" @@ -323,8 +387,6 @@ rm -rf %{buildroot} %exclude /usr/lib/ocf/resource.d/heartbeat/db2 %exclude /usr/lib/ocf/resource.d/heartbeat/eDir88 %exclude /usr/lib/ocf/resource.d/heartbeat/fio -%exclude /usr/lib/ocf/resource.d/heartbeat/iSCSILogicalUnit -%exclude /usr/lib/ocf/resource.d/heartbeat/iSCSITarget %exclude /usr/lib/ocf/resource.d/heartbeat/ids %exclude /usr/lib/ocf/resource.d/heartbeat/iscsi %exclude /usr/lib/ocf/resource.d/heartbeat/jboss @@ -371,8 +433,6 @@ rm -rf %{buildroot} %exclude %{_mandir}/man7/ocf_heartbeat_db2.7.gz %exclude %{_mandir}/man7/ocf_heartbeat_eDir88.7.gz %exclude %{_mandir}/man7/ocf_heartbeat_fio.7.gz -%exclude %{_mandir}/man7/ocf_heartbeat_iSCSILogicalUnit.7.gz -%exclude %{_mandir}/man7/ocf_heartbeat_iSCSITarget.7.gz %exclude %{_mandir}/man7/ocf_heartbeat_ids.7.gz %exclude %{_mandir}/man7/ocf_heartbeat_iscsi.7.gz %exclude %{_mandir}/man7/ocf_heartbeat_jboss.7.gz @@ -427,21 +487,108 @@ ccs_update_schema > /dev/null 2>&1 ||: %changelog +* Fri Dec 19 2014 David Vossel - 3.9.5-40 +- Remove usage of write_back from iSCSILogicalUnit -* Mon Jan 26 2015 David Vossel - 3.9.5-26.7 -- Support for rabbitmq-cluster resource-agent + Resolves: rhbz#1118029 - Resolves: rhbz#1185753 +* Thu Dec 11 2014 David Vossel - 3.9.5-39 +- Updates spec file to include iscsi resources -* Thu Oct 30 2014 David Vossel - 3.9.5-26.6 -- Support for galera resource-agent + Resolves: rhbz#1118029 + +* Mon Oct 27 2014 David Vossel - 3.9.5-38 +- Handle invalid monitor_cmd option for docker resource-agent + + Resolves: rhbz#1135026 + +* Sun Oct 26 2014 David Vossel - 3.9.5-37 +- Rename docker agent's 'container' arg to 'name' to avoid confusion + with pacemaker's metadata 'container' argument. +- Introduce monitor_cmd into docker agent. + + Resolves: rhbz#1135026 + +* Thu Oct 23 2014 David Vossel - 3.9.5-36 +- Fixes cleaning up stale docker containers during stop if + container instance failed. + + Resolves: rhbz#1135026 + +* Thu Oct 23 2014 David Vossel - 3.9.5-35 +- Introduces docker resource-agent for managing docker containers. + The docker agent is being released as tech preview. + + Resolves: rhbz#1135026 + +* Wed Oct 22 2014 David Vossel - 3.9.5-34 +- Fixes mysql agents behavior when monitoring resource instance + when environment validation fails. + + Resolves: rhbz#1138871 + +* Tue Sep 23 2014 David Vossel - 3.9.5-33 +- Merges latest upstream patches for galera agent +- Merges latest upstream patchs for exit reason string + + Resolves: rhbz#1116166 + Resolves: rhbz#1128933 + +* Tue Sep 17 2014 David Vossel - 3.9.5-32 +- Fixes iSCSILogicalUnit syntax error +- Fixes mysql stop operation when db storage is unavailable + + Resolves: rhbz#1118029 + Resolves: rhbz#1138871 + +* Mon Aug 25 2014 David Vossel - 3.9.5-31 +- Man page updates give pcs config examples +- add iscsi agent support +- add infiniband support to ethmonitor +- add resource-agent support of exit reason string +- add safe umount option to Filesystem resource agent + + Resolves: rhbz#1058102 + Resolves: rhbz#1118029 + Resolves: rhbz#1122285 + Resolves: rhbz#1128933 + Resolves: rhbz#1095944 + +* Fri Aug 15 2014 David Vossel - 3.9.5-30 +- Support monitor of lxc without requiring libvirt. +- Wait for filesystem modules to load during start. +- Warn users managing clustered LVM when lvmetad is in use. +- Restore VirtualDomain default start stop timeout values. +- Support exit reason string +- Auto set lvm locking type to clustered when clvmd is in use. + +Resolves: rhbz# 1083041 +Resolves: rhbz# 1083231 +Resolves: rhbz# 1097593 +Resolves: rhbz# 1105655 +Resolves: rhbz# 1128933 +Resolves: rhbz# 773395 + + +* Fri Jul 18 2014 David Vossel - 3.9.5-29 +- Support the check_user and check_passwd galera resource-agent + options. +- Minor NFS agent updates. Resolves: rhbz#1116166 + Resolves: rhbz#1091101 + +* Thu Jul 10 2014 David Vossel - 3.9.5-28 +- Updates to nfs server related agent. +- Introduces nfsnotify for sending NFSv3 NSM state change + notifications allowing NFSv3 clients to reclaim locks. -* Thu Oct 30 2014 David Vossel - 3.9.5-26.5 -- Support NFSv4 Active/Passive use case. + Resolves: rhbz#1091101 - Resolves: rhbz#1158901 +* Wed Jul 09 2014 David Vossel - 3.9.5-27 +- Introducing the galera resource-agent. + + Resolves: rhbz#1116166 * Tue Mar 18 2014 David Vossel - 3.9.5-26 - Handle monitor qemu based VirtualDomain resources without