[Pacemaker] emc symmetrix ocf ra
daniel peess
mailinglists at peess.de
Fri Jul 10 12:23:59 UTC 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: <https://lists.clusterlabs.org/pipermail/pacemaker/attachments/20090710/2802c1c8/attachment-0003.sig>
More information about the Pacemaker
mailing list