Blame SOURCES/bz1064512-clvmd-agent.patch

aba6ec
From 61dd0f9ca20b0f252996b6f610b4473ba83ca97a Mon Sep 17 00:00:00 2001
aba6ec
From: David Vossel <dvossel@redhat.com>
aba6ec
Date: Wed, 12 Feb 2014 12:36:21 -0500
aba6ec
Subject: [PATCH] High: clvm: Introducing clvmd resource agent
aba6ec
aba6ec
---
aba6ec
 doc/man/Makefile.am   |   1 +
aba6ec
 heartbeat/Makefile.am |   1 +
aba6ec
 heartbeat/clvm        | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++
aba6ec
 3 files changed, 398 insertions(+)
aba6ec
 create mode 100755 heartbeat/clvm
aba6ec
aba6ec
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
aba6ec
index 3bf569a..49b5c58 100644
aba6ec
--- a/doc/man/Makefile.am
aba6ec
+++ b/doc/man/Makefile.am
aba6ec
@@ -94,6 +94,7 @@ man_MANS	       = ocf_heartbeat_AoEtarget.7 \
aba6ec
                           ocf_heartbeat_anything.7 \
aba6ec
                           ocf_heartbeat_apache.7 \
aba6ec
                           ocf_heartbeat_asterisk.7 \
aba6ec
+                          ocf_heartbeat_clvm.7 \
aba6ec
                           ocf_heartbeat_conntrackd.7 \
aba6ec
                           ocf_heartbeat_db2.7 \
aba6ec
                           ocf_heartbeat_dhcpd.7 \
aba6ec
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
aba6ec
index bc95f89..2c3056d 100644
aba6ec
--- a/heartbeat/Makefile.am
aba6ec
+++ b/heartbeat/Makefile.am
aba6ec
@@ -61,6 +61,7 @@ ocf_SCRIPTS	     =  ClusterMon		\
aba6ec
 			asterisk		\
aba6ec
 			nginx			\
aba6ec
 			AudibleAlarm		\
aba6ec
+			clvm		\
aba6ec
 			conntrackd		\
aba6ec
 			db2			\
aba6ec
 			dhcpd		\
aba6ec
diff --git a/heartbeat/clvm b/heartbeat/clvm
aba6ec
new file mode 100755
aba6ec
index 0000000..3e7701d
aba6ec
--- /dev/null
aba6ec
+++ b/heartbeat/clvm
aba6ec
@@ -0,0 +1,396 @@
aba6ec
+#!/bin/bash
aba6ec
+#
aba6ec
+# Copyright (c) 2014 David Vossel <dvossel@redhat.com>
aba6ec
+#                    All Rights Reserved.
aba6ec
+#
aba6ec
+# This program is free software; you can redistribute it and/or modify
aba6ec
+# it under the terms of version 2 of the GNU General Public License as
aba6ec
+# published by the Free Software Foundation.
aba6ec
+#
aba6ec
+# This program is distributed in the hope that it would be useful, but
aba6ec
+# WITHOUT ANY WARRANTY; without even the implied warranty of
aba6ec
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
aba6ec
+#
aba6ec
+# Further, this software is distributed without any warranty that it is
aba6ec
+# free of the rightful claim of any third person regarding infringement
aba6ec
+# or the like.  Any license provided herein, whether implied or
aba6ec
+# otherwise, applies only to this software file.  Patent licenses, if
aba6ec
+# any, provided herein do not apply to combinations of this program with
aba6ec
+# other software, or any other product whatsoever.
aba6ec
+#
aba6ec
+# You should have received a copy of the GNU General Public License
aba6ec
+# along with this program; if not, write the Free Software Foundation,
aba6ec
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
aba6ec
+#
aba6ec
+
aba6ec
+#######################################################################
aba6ec
+# Initialization:
aba6ec
+
aba6ec
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
aba6ec
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
aba6ec
+. ${OCF_FUNCTIONS_DIR}/ocf-directories
aba6ec
+
aba6ec
+#######################################################################
aba6ec
+
aba6ec
+meta_data() {
aba6ec
+	cat <
aba6ec
+
aba6ec
+
aba6ec
+<resource-agent name="clvm" version="0.9">
aba6ec
+<version>1.0</version>
aba6ec
+
aba6ec
+<longdesc lang="en">
aba6ec
+This agent manages the clvmd daemon.
aba6ec
+</longdesc>
aba6ec
+<shortdesc lang="en">clvmd</shortdesc>
aba6ec
+
aba6ec
+<parameters>
aba6ec
+<parameter name="with_cmirrord" unique="0" required="0">
aba6ec
+<longdesc lang="en">
aba6ec
+Start with cmirrord (cluster mirror log daemon).
aba6ec
+</longdesc>
aba6ec
+<shortdesc lang="en">activate cmirrord</shortdesc>
aba6ec
+<content type="boolean" default="false" />
aba6ec
+</parameter>
aba6ec
+
aba6ec
+<parameter name="daemon_options" unique="0">
aba6ec
+<longdesc lang="en">
aba6ec
+Options to clvmd. Refer to clvmd.8 for detailed descriptions.
aba6ec
+</longdesc>
aba6ec
+<shortdesc lang="en">Daemon Options</shortdesc>
aba6ec
+<content type="string" default="-d0"/>
aba6ec
+</parameter>
aba6ec
+</parameters>
aba6ec
+
aba6ec
+<actions>
aba6ec
+<action name="start"        timeout="90" />
aba6ec
+<action name="stop"         timeout="90" />
aba6ec
+<action name="monitor"      timeout="90" interval="30" depth="0" />
aba6ec
+<action name="reload"       timeout="90" />
aba6ec
+<action name="meta-data"    timeout="10" />
aba6ec
+<action name="validate-all"   timeout="20" />
aba6ec
+</actions>
aba6ec
+</resource-agent>
aba6ec
+END
aba6ec
+}
aba6ec
+
aba6ec
+#######################################################################
aba6ec
+
aba6ec
+: ${OCF_RESKEY_daemon_options:="-d0"}
aba6ec
+
aba6ec
+sbindir=$HA_SBIN_DIR
aba6ec
+if [ -z $sbindir ]; then
aba6ec
+	sbindir=/usr/sbin
aba6ec
+fi
aba6ec
+DAEMON="clvmd"
aba6ec
+CMIRROR="cmirrord"
aba6ec
+DAEMON_PATH="${sbindir}/clvmd"
aba6ec
+CMIRROR_PATH="${sbindir}/cmirrord"
aba6ec
+LOCK_FILE="/var/lock/subsys/$DAEMON"
aba6ec
+LVM_VGCHANGE=${sbindir}/vgchange
aba6ec
+LVM_VGDISPLAY=${sbindir}/vgdisplay
aba6ec
+LVM_VGSCAN=${sbindir}/vgscan
aba6ec
+
aba6ec
+# Leaving this in for legacy. We do not want to advertize
aba6ec
+# the abilty to set options in the systconfig exists, we want
aba6ec
+# to expand the OCF style options as necessary instead.
aba6ec
+[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
aba6ec
+[ -f /etc/sysconfig/$DAEMON ] && . /etc/sysconfig/$DAEMON
aba6ec
+
aba6ec
+CLVMD_TIMEOUT="90"
aba6ec
+if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
aba6ec
+	CLVMD_TIMEOUT=$(($OCF_RESKEY_CRM_meta_timeout/1000))
aba6ec
+fi
aba6ec
+
aba6ec
+clvmd_usage()
aba6ec
+{
aba6ec
+	cat <
aba6ec
+usage: $0 {start|stop|monitor|validate-all|meta-data}
aba6ec
+
aba6ec
+Expects to have a fully populated OCF RA-compliant environment set.
aba6ec
+END
aba6ec
+}
aba6ec
+
aba6ec
+clvmd_validate()
aba6ec
+{
aba6ec
+	# check_binary will exit with OCF_ERR_INSTALLED
aba6ec
+	# when binary is missing
aba6ec
+	check_binary "pgrep"
aba6ec
+	check_binary $DAEMON_PATH
aba6ec
+	if ocf_is_true $OCF_RESKEY_with_cmirrord; then
aba6ec
+		check_binary $CMIRROR_PATH
aba6ec
+	fi
aba6ec
+
aba6ec
+	if [ "$__OCF_ACTION" != "monitor" ]; then
aba6ec
+		check_binary "killall"
aba6ec
+		check_binary $LVM_VGCHANGE
aba6ec
+		check_binary $LVM_VGDISPLAY
aba6ec
+		check_binary $LVM_VGSCAN
aba6ec
+	fi
aba6ec
+
aba6ec
+	# Future validation checks here.
aba6ec
+	return $OCF_SUCCESS
aba6ec
+}
aba6ec
+
aba6ec
+check_process()
aba6ec
+{
aba6ec
+	local binary=$1
aba6ec
+	local pidfile="${HA_RSCTMP}/${binary}-${OCF_RESOURCE_INSTANCE}.pid"
aba6ec
+	local pid
aba6ec
+
aba6ec
+	ocf_log debug "Checking status for ${binary}."
aba6ec
+	if [ -e "$pidfile" ]; then
aba6ec
+		cat /proc/$(cat $pidfile)/cmdline 2>/dev/null | grep -a "${binary}" > /dev/null 2>&1
aba6ec
+		if [ $? -eq 0 ];then
aba6ec
+			# shortcut without requiring pgrep to search through all procs
aba6ec
+			return $OCF_SUCCESS
aba6ec
+		fi
aba6ec
+	fi
aba6ec
+
aba6ec
+	pid=$(pgrep ${binary})
aba6ec
+	case $? in
aba6ec
+		0)
aba6ec
+			ocf_log info "PID file (pid:${pid} at $pidfile) created for ${binary}."
aba6ec
+			echo "$pid" > $pidfile
aba6ec
+			return $OCF_SUCCESS;;
aba6ec
+		1)
aba6ec
+			rm -f "$pidfile" > /dev/null 2>&1 
aba6ec
+			ocf_log info "$binary is not running"
aba6ec
+			return $OCF_NOT_RUNNING;;
aba6ec
+		*)
aba6ec
+			rm -f "$pidfile" > /dev/null 2>&1 
aba6ec
+			ocf_log err "Error encountered detecting pid status of $binary"
aba6ec
+			return $OCF_ERR_GENERIC;;
aba6ec
+	esac
aba6ec
+}
aba6ec
+
aba6ec
+clvmd_status()
aba6ec
+{
aba6ec
+	local rc
aba6ec
+	local mirror_rc
aba6ec
+	clvmd_validate
aba6ec
+	if [ $? -ne $OCF_SUCCESS ]; then
aba6ec
+		ocf_log error "Unable to monitor, Environment validation failed."
aba6ec
+		return $?
aba6ec
+	fi
aba6ec
+
aba6ec
+	check_process $DAEMON
aba6ec
+	rc=$?
aba6ec
+	mirror_rc=$rc
aba6ec
+
aba6ec
+	if ocf_is_true $OCF_RESKEY_with_cmirrord; then
aba6ec
+		check_process $CMIRROR
aba6ec
+		mirror_rc=$?
aba6ec
+	fi
aba6ec
+
aba6ec
+	# If these ever don't match, return error to force recovery
aba6ec
+	if [ $mirror_rc -ne $rc ]; then
aba6ec
+		return $OCF_ERR_GENERIC
aba6ec
+	fi
aba6ec
+
aba6ec
+	return $rc
aba6ec
+}
aba6ec
+
aba6ec
+# NOTE: replace this with vgs, once display filter per attr is implemented.
aba6ec
+clustered_vgs() {
aba6ec
+	${LVM_VGDISPLAY} 2>/dev/null | awk 'BEGIN {RS="VG Name"} {if (/Clustered/) print $1;}'
aba6ec
+}
aba6ec
+
aba6ec
+wait_for_process()
aba6ec
+{
aba6ec
+	local binary=$1
aba6ec
+	local timeout=$2
aba6ec
+	local count=0
aba6ec
+
aba6ec
+	ocf_log info "Waiting for $binary to exit"
aba6ec
+	usleep 500000
aba6ec
+	while [ $count -le $timeout ]; do
aba6ec
+		check_process $binary
aba6ec
+		if [ $? -eq $OCF_NOT_RUNNING ]; then
aba6ec
+			ocf_log info "$binary terminated"
aba6ec
+			return $OCF_SUCCESS
aba6ec
+		fi
aba6ec
+		sleep 1
aba6ec
+		count=$((count+1))
aba6ec
+	done
aba6ec
+
aba6ec
+	return $OCF_ERR_GENERIC
aba6ec
+}
aba6ec
+
aba6ec
+time_left()
aba6ec
+{
aba6ec
+	local end=$1
aba6ec
+	local default=$2
aba6ec
+	local now=$SECONDS
aba6ec
+	local result=0
aba6ec
+
aba6ec
+	result=$(( $end - $now ))
aba6ec
+	if [ $result -lt $default ]; then
aba6ec
+		return $default
aba6ec
+	fi
aba6ec
+	return $result
aba6ec
+}
aba6ec
+
aba6ec
+clvmd_stop()
aba6ec
+{
aba6ec
+	local LVM_VGS
aba6ec
+	local rc=$OCF_SUCCESS
aba6ec
+	local end=$(( $SECONDS + $CLVMD_TIMEOUT ))
aba6ec
+
aba6ec
+	clvmd_status
aba6ec
+	if [ $? -eq $OCF_NOT_RUNNING ]; then
aba6ec
+		return $OCF_SUCCESS
aba6ec
+	fi
aba6ec
+
aba6ec
+	check_process $DAEMON
aba6ec
+	if [ $? -ne $OCF_NOT_RUNNING ]; then
aba6ec
+		LVM_VGS="$(clustered_vgs)"
aba6ec
+
aba6ec
+		if [ -n "$LVM_VGS" ]; then
aba6ec
+			ocf_log info "Deactivating clustered VG(s):" 
aba6ec
+			ocf_run ${LVM_VGCHANGE} -anl $LVM_VGS
aba6ec
+			if [ $? -ne 0 ]; then
aba6ec
+				ocf_log error "Failed to deactivate volume groups, cluster vglist = $LVM_VGS" 
aba6ec
+				return $OCF_ERR_GENERIC
aba6ec
+			fi
aba6ec
+		fi
aba6ec
+
aba6ec
+		ocf_log info "Signaling $DAEMON to exit"
aba6ec
+		killall -TERM $DAEMON
aba6ec
+		if [ $? != 0 ]; then
aba6ec
+			ocf_log error "Failed to signal -TERM to $DAEMON"
aba6ec
+			return $OCF_ERR_GENERIC
aba6ec
+		fi
aba6ec
+
aba6ec
+		wait_for_process $DAEMON $CLVMD_TIMEOUT
aba6ec
+		rc=$?
aba6ec
+		if [ $rc -ne $OCF_SUCCESS ]; then
aba6ec
+			ocf_log error "$DAEMON failed to exit"
aba6ec
+			return $rc
aba6ec
+		fi
aba6ec
+
aba6ec
+		rm -f $LOCK_FILE
aba6ec
+	fi
aba6ec
+
aba6ec
+	check_process $CMIRROR
aba6ec
+	if [ $? -ne $OCF_NOT_RUNNING ] && ocf_is_true $OCF_RESKEY_with_cmirrord; then
aba6ec
+		local timeout
aba6ec
+		ocf_log info "Signaling $CMIRROR to exit"
aba6ec
+		killall -INT $CMIRROR
aba6ec
+
aba6ec
+		time_left $end 10; timeout=$?
aba6ec
+		wait_for_process $CMIRROR $timeout
aba6ec
+		rc=$?
aba6ec
+		if [ $rc -ne $OCF_SUCCESS ]; then
aba6ec
+			killall -KILL $CMIRROR
aba6ec
+			time_left $end 10; timeout=$?
aba6ec
+			wait_for_process $CMIRROR $(time_left $end 10)
aba6ec
+			rc=$?
aba6ec
+		fi
aba6ec
+	fi
aba6ec
+
aba6ec
+	return $rc
aba6ec
+}
aba6ec
+
aba6ec
+start_process()
aba6ec
+{
aba6ec
+	local binary_path=$1
aba6ec
+	local opts=$2
aba6ec
+
aba6ec
+	check_process "$(basename $binary_path)"
aba6ec
+	if [ $? -ne $OCF_SUCCESS ]; then
aba6ec
+		ocf_log info "Starting $binary_path: "
aba6ec
+		ocf_run $binary_path $opts
aba6ec
+		rc=$?
aba6ec
+		if [ $rc -ne 0 ]; then
aba6ec
+			ocf_log error "Failed to launch $binary_path, exit code $rc"
aba6ec
+			exit $OCF_ERR_GENERIC
aba6ec
+		fi
aba6ec
+	fi
aba6ec
+
aba6ec
+	return $OCF_SUCCESS
aba6ec
+}
aba6ec
+
aba6ec
+clvmd_activate_all()
aba6ec
+{
aba6ec
+	# Activate all volume groups by leaving the
aba6ec
+	# "volume group name" parameter empty
aba6ec
+	ocf_run ${LVM_VGCHANGE} -aay
aba6ec
+	if [ $? -ne 0 ]; then
aba6ec
+		ocf_log info "Failed to activate VG(s):"
aba6ec
+		clvmd_stop
aba6ec
+		return $OCF_ERR_GENERIC
aba6ec
+	fi
aba6ec
+	return $OCF_SUCCESS
aba6ec
+}
aba6ec
+
aba6ec
+clvmd_start()
aba6ec
+{
aba6ec
+	local rc=0
aba6ec
+	local CLVMDOPTS="-T${CLVMD_TIMEOUT} $OCF_RESKEY_daemon_options"
aba6ec
+
aba6ec
+	clvmd_validate
aba6ec
+	if [ $? -ne $OCF_SUCCESS ]; then
aba6ec
+		ocf_log error "Unable to start, Environment validation failed."
aba6ec
+		return $?
aba6ec
+	fi
aba6ec
+
aba6ec
+	clvmd_status
aba6ec
+	if [ $? -eq $OCF_SUCCESS ]; then
aba6ec
+		ocf_log debug "$DAEMON already started"
aba6ec
+		clvmd_activate_all
aba6ec
+		return $?;
aba6ec
+	fi
aba6ec
+
aba6ec
+	# if either of these fail, script will exit OCF_ERR_GENERIC
aba6ec
+	if ocf_is_true $OCF_RESKEY_with_cmirrord; then
aba6ec
+		start_process $CMIRROR_PATH
aba6ec
+	fi
aba6ec
+	start_process $DAEMON_PATH $CLVMDOPTS
aba6ec
+
aba6ec
+	# Refresh local cache.
aba6ec
+	#
aba6ec
+	# It's possible that new PVs were added to this, or other VGs
aba6ec
+	# while this node was down. So we run vgscan here to avoid
aba6ec
+	# any potential "Missing UUID" messages with subsequent
aba6ec
+	# LVM commands.
aba6ec
+
aba6ec
+	# The following step would be better and more informative to the user:
aba6ec
+	# 'action "Refreshing VG(s) local cache:" ${LVM_VGSCAN}'
aba6ec
+	# but it could show warnings such as:
aba6ec
+	# 'clvmd not running on node x-y-z  Unable to obtain global lock.'
aba6ec
+	# and the action would be shown as FAILED when in reality it didn't.
aba6ec
+	# Ideally vgscan should have a startup mode that would not print
aba6ec
+	# unnecessary warnings.
aba6ec
+
aba6ec
+	${LVM_VGSCAN} > /dev/null 2>&1
aba6ec
+	touch $LOCK_FILE
aba6ec
+
aba6ec
+	clvmd_activate_all
aba6ec
+
aba6ec
+	clvmd_status
aba6ec
+	return $?
aba6ec
+}
aba6ec
+
aba6ec
+case $__OCF_ACTION in
aba6ec
+	meta-data)   meta_data
aba6ec
+		exit $OCF_SUCCESS;;
aba6ec
+
aba6ec
+	start)         clvmd_start;;
aba6ec
+
aba6ec
+	stop)          clvmd_stop;;
aba6ec
+
aba6ec
+	monitor)       clvmd_status;;
aba6ec
+
aba6ec
+	validate-all)  clvmd_validate;;
aba6ec
+
aba6ec
+	usage|help)    clvmd_usage;;
aba6ec
+
aba6ec
+	*)             clvmd_usage
aba6ec
+	               exit $OCF_ERR_UNIMPLEMENTED;;
aba6ec
+esac
aba6ec
+
aba6ec
+rc=$?
aba6ec
+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
aba6ec
+exit $rc
aba6ec
+
aba6ec
-- 
aba6ec
1.8.4.2
aba6ec