[Pacemaker] emc symmetrix ocf ra

daniel peess mailinglists at peess.de
Fri Jul 10 08:23:59 EDT 2009


hi ml,

i've attached a emc symmetrix ocf ra symsrdf we've written in a project.
it switches the uni-directional replication of the mirror on startup.

two hacks are still in there:
- to inform the DMMPIO of SLES10sp2 that the block device is now active i had 
  to restart the daemon.
- to shut down the DMMPIO before the switch a had to use the volume group
  name to get to the dynamic chosen multi-path device name.

otherwise this RA works quite nice in production already.

bye,
Daniel Peess

-- 
Dipl.-Ing.(FH) Daniel Peess            Geschaeftsfuehrer: Ralph Dehner
Linux Architect                        Unternehmenssitz: Vohburg
B1 Systems GmbH                        Amtsgericht: Ingolstadt
Mobil: +49-(0)170-9281868              Handelsregister: HRB 3537
EMail: info at b1-systems.de              http://www.b1-systems.de

Adresse: B1 Systems GmbH, Osterfeldstraße 7, 85088 Vohburg
GPG: http://blackhole.pca.dfn.de:11371/pks/lookup?search=0x08DBE2FD
----------------------------------------------------------------------

-------------- next part --------------
#!/bin/bash
## vim: set ts=4 sw=4 sts=0 noet foldmethod=indent:
## purpose: emc symmetrix srdf fail-over replication agent
## copyright (c): B1 Systems GmbH <info at b1-systems.de>, 2009.
## author: daniel peess <peess at b1-systems.de>, 2009.
## license: GPLv3+, http://www.gnu.org/licenses/gpl-3.0.html
## version: 1.0

## TODO: switch from vgdisplay to pvs to get device mapper name.
## TODO: strip the whole multipath handling from this agent?
## TODO: volume group name + symmetrix group as comma separated values?

. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs

PATH="${PATH}:${OCF_RESKEY_sympath}";

mymeta() {
	cat <<EOF
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="MyDummy">
<version>1.0</version>
<longdesc lang="en">
This is a Resource Agent to switch EMC Symmetrix SRDF Replication for Mirror Groups.
</longdesc>
<shortdesc lang="en">EMC Symmetrix SRDF Switch Replication</shortdesc>
<parameters>
	<parameter name="volgroup" required="1" unique="1">
	<longdesc lang="en">Name of LVM Volume Group</longdesc>
	<shortdesc lang="en">volume group</shortdesc>
	<content type="string" default=""/>
	</parameter>
	<parameter name="symgroup" required="1" unique="1">
	<longdesc lang="en">Name of Symmetrix Replication Group</longdesc>
	<shortdesc lang="en">symmetrix group</shortdesc>
	<content type="string" default=""/>
	</parameter>
	<parameter name="sympath" required="1" unique="1">
	<longdesc lang="en">Binary Path of Symmetrix CLI Tools</longdesc>
	<shortdesc lang="en">symcli binary path</shortdesc>
	<content type="string" default="/opt/emc/SYMCLI/V6.5.1/bin"/>
	</parameter>
</parameters>
<actions>
<action name="start"   timeout="240s" />
<action name="stop"    timeout="30s" />
<action name="monitor" timeout="60s" interval="60s" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="30" />
</actions>
</resource-agent>
EOF
echo;
}

myusage() {
	cat <<EOF
usage: $0 {start|stop|monitor|validate-all|meta-data}

Expects to have a fully populated OCF RA-compliant environment set.
EOF
echo;
}

mystart() {
	echo 'Starting SRDF replication switch for' "${OCF_RESKEY_symgroup}" 'on this node...';

	vgdisplay -v "${OCF_RESKEY_volgroup}" 2>&1 | grep -q 'Volume group.*not found';
	if [ $? -ne 0 ]; then
		echo 'Volume group' "${OCF_RESKEY_volgroup}" 'already active.';
		symrdf -g "$OCF_RESKEY_symgroup" query | grep -q '^DG.*Type.*RDF1';
		if [ $? -eq 0 ]; then
			echo 'and symmetrix mirror underneath in replication read-write mode.';
			exit $OCF_SUCCESS;
		fi;
		echo 'but symmetrix mirror underneath only in *replicated* read-only mode.';
	fi;

	## recover from previous optional crash
	symcfg discover;

	## check if already primary
	symrdf -g "$OCF_RESKEY_symgroup" query >/dev/null;
	if [ $? -ne 0 ]; then
		echo 'symmetrix group' "${OCF_RESKEY_symgroup}" 'non existant';
		exit $OCF_ERR_ARGS;
	fi;

	symrdf -g "$OCF_RESKEY_symgroup" query | grep -q '^DG.*Type.*RDF1';
	if [ $? -ne 0 ]; then
		## initiating 3 steps: failover, swap, establish.
		symrdf -noprompt -g "$OCF_RESKEY_symgroup" failover;
		if [ $? -ne 0 ]; then
			echo;
			echo 'Unable to failover symmetrix group ' "${OCF_RESKEY_symgroup}" '!';
			exit $OCF_ERR_GENERIC;
		fi;

		symrdf -noprompt -g "$OCF_RESKEY_symgroup" swap;
		if [ $? -ne 0 ]; then
			echo;
			echo 'Unable to swap symmetrix group ' "${OCF_RESKEY_symgroup}" '!';
			exit $OCF_ERR_GENERIC;
		fi;

		symrdf -noprompt -g "$OCF_RESKEY_symgroup" establish;
		if [ $? -ne 0 ]; then
			echo;
			echo 'Unable to establish symmetrix group ' "${OCF_RESKEY_symgroup}" '!';
			exit $OCF_ERR_GENERIC;
		fi;

		## query if fail-over really succeeded.
		symrdf -g "$OCF_RESKEY_symgroup" query | grep -q '^DG.*Type.*RDF1';
		if [ $? -ne 0 ]; then
			echo;
			echo 'Symmetrix group' "${OCF_RESKEY_symgroup}" 'still not active.';
			exit $OCF_ERR_GENERIC;
		fi;
	else echo 'Symmetrix Group' "${OCF_RESKEY_symgroup}" 'already active.';
	fi;

	## detect block device status change
	for dev in `syminq|awk '$2~/R1/{print $1}'|cut -d/ -f3`; do
		echo 1 > /sys/block/${dev}/device/rescan;
	done;

	## restart multipath daemon to detect new block devices.
	## TODO: switch to reload or specific device names?
	/etc/init.d/multipathd restart;
	if [ $? -ne 0 ]; then
		echo 'Unable to restart multipath' "${OCF_RESKEY_symgroup}" 'still not active.';
		exit $OCF_ERR_GENERIC;
	fi;
	sleep 2;

	return $OCF_SUCCESS;
}

mystop() {
	echo "Stopping MPIO Device to prevent access..."

	## lvm check is just for getting our mpio device name.
	MPIODEVICE=`vgdisplay -v "${OCF_RESKEY_volgroup}" 2>/dev/null 2>&1`;
	sleep 1;
	MPIODEVICE=`vgdisplay -v "${OCF_RESKEY_volgroup}" 2>/dev/null | awk '/PV Name/{print $3}'`;
	if [ "${MPIODEVICE}DUMMY" = "DUMMY" ]; then
		echo 'MPIO device that belonged to volume group' "${OCF_RESKEY_volgroup}" 'already stopped.';
		return $OCF_SUCCESS;
	fi;
	echo $MPIODEVICE;

	MPIODEVICE=`echo "${MPIODEVICE}" | sed 's!^/dev/!!'`;
	if [ "${MPIODEVICE}DUMMY" = "DUMMY" ]; then
		echo 'Unable to trim path from MPIO device' "${MPIODEVICE}" '!';
		exit $OCF_ERR_GENERIC;
	fi;
	echo $MPIODEVICE;

	MPIONAME=`multipath -ll | awk '/'${MPIODEVICE}'/{print $1}'`;
	if [ "${MPIONAME}DUMMY" = "DUMMY" ]; then
		echo 'Unable to determine MPIO name that belongs to MPIO device ' "${MPIODEVICE}" '!';
		exit $OCF_ERR_GENERIC;
	fi;
	echo $MPIONAME;

	## WARNING: multipath doesn't provide sane return codes, checking by another query.
	multipath -f "${MPIONAME}";
	multipath -ll | grep -q "${MPIONAME}.*${MPIODEVICE}";
	if [ $? -eq 0 ]; then
		echo 'Unable to remove MPIO device ' "${MPIONAME}" ':' "${MPIODEVICE}" '!';
		exit $OCF_ERR_GENERIC;
	fi;

	return $OCF_SUCCESS;
}

mymonitor() {
	## WARNING: the stop operation itself is NOT switching back from SRDF1 to SRDF2!
	## this is ONLY done by the start operation on the active node.
	## therefore stopped status means the VOLUME GROUP is NOT active in this node.

	MPIODEVICE=`vgdisplay -v "${OCF_RESKEY_volgroup}" 2>/dev/null 2>&1`;
	sleep 1;
	MPIODEVICE=`vgdisplay -v "${OCF_RESKEY_volgroup}" 2>/dev/null | awk '/PV Name/{print $3}'`;
	if [ "${MPIODEVICE}DUMMY" = "DUMMY" ]; then
		echo 'MPIO device that belonged to volume group' "${OCF_RESKEY_volgroup}" 'already stopped.';
		return $OCF_NOT_RUNNING;
	fi;

	symrdf -g "$OCF_RESKEY_symgroup" query >/dev/null;
	if [ $? -ne 0 ]; then
		echo 'symmetrix group' "${OCF_RESKEY_symgroup}" 'non existant.';
		exit $OCF_NOT_RUNNING;
	fi;

	symrdf -g "$OCF_RESKEY_symgroup" query | grep -q '^DG.*Type.*RDF1';
	if [ $? -ne 0 ]; then
		echo 'symmetrix group' "${OCF_RESKEY_symgroup}" 'not active.';
		exit $OCF_NOT_RUNNING;
	fi;

	return $OCF_SUCCESS;
}

myvalidate() {
	## check if all variables are there.
	if [ "${OCF_RESKEY_volgroup}DUMMY" = "DUMMY" ]; then
		myusage;
		echo;
		echo 'Missing mandatory parameter $OCF_RESKEY_volgroup';
		exit $OCF_ERR_ARGS;
	fi
	if [ "${OCF_RESKEY_symgroup}DUMMY" = "DUMMY" ]; then
		myusage;
		echo;
		echo 'Missing mandatory parameter $OCF_RESKEY_symgroup';
		exit $OCF_ERR_ARGS;
	fi
	if [ "${OCF_RESKEY_sympath}DUMMY" = "DUMMY" ]; then
		myusage;
		echo;
		echo 'Missing mandatory parameter $OCF_RESKEY_sympath';
		exit $OCF_ERR_ARGS;
	fi

	## check if all cli tools are there.
	for TOOL in awk multipath vgdisplay symrdf symcfg grep; do
		which "${TOOL}" 2>&1 | grep -q '^which: no ';
		if [ $? -eq 0 ]; then
			myusage;
			echo;
			echo 'The command |'"${TOOL}"'| was not found in the current path.';
			exit $OCF_ERR_ARGS;
		fi;
	done;

	return $OCF_SUCCESS;
}

## sole parameter must be the operation.
if [ $# -ne 1 ]; then
	myusage;
	echo;
	echo 'Please pass all attributes as environment variables!';
	echo 'Prefix them with a OCF_RESKEY_xxx string.';
	exit $OCF_ERR_ARGS;
fi

case $__OCF_ACTION in
meta-data)	mymeta
		exit $OCF_SUCCESS
		;;
start)		mystart
		;;
stop)		mystop
		;;
monitor)	mymonitor
		;;
validate-all)	myvalidate
		;;
usage|help)	myusage
		exit $OCF_SUCCESS
		;;
*)		myusage
		exit $OCF_ERR_UNIMPLEMENTED
		;;
esac
exit $?
## EOF

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.clusterlabs.org/pipermail/pacemaker/attachments/20090710/2802c1c8/attachment-0002.sig>


More information about the Pacemaker mailing list