mirror of https://github.com/sipwise/heartbeat.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
6.1 KiB
296 lines
6.1 KiB
#!/bin/sh
|
|
#
|
|
#
|
|
# ICP
|
|
#
|
|
# Description: Manages an ICP Vortex clustered host drive as an HA resource
|
|
#
|
|
#
|
|
# Author: Lars Marowsky-Bree <lmb@suse.de>
|
|
# Support: linux-ha@lists.linux-ha.org
|
|
# License: GNU General Public License (GPL)
|
|
# Copyright: (C) 2002 SuSE Linux AG
|
|
#
|
|
#
|
|
# An example usage in /etc/ha.d/haresources:
|
|
# node1 10.0.0.170 LinuxSCSI::0:0 ICP::c0h1::/dev/sdb1 LVM::myvolname
|
|
#
|
|
# Notice that you will need to get the utility "icpclucon" from the ICP
|
|
# support to use this.
|
|
#
|
|
# See usage() function below for more details...
|
|
#
|
|
# OCF parameters are as below:
|
|
# OCF_RESKEY_driveid
|
|
# OCF_RESKEY_device
|
|
|
|
#######################################################################
|
|
# Initialization:
|
|
|
|
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
|
|
|
|
#######################################################################
|
|
|
|
#
|
|
ICPCLUCON=/usr/sbin/icpclucon
|
|
#
|
|
|
|
usage() {
|
|
methods=`ICP_methods | grep -v methods`
|
|
methods=`echo $methods | tr ' ' '|'`
|
|
cat <<-!
|
|
usage: $0 ($methods)
|
|
|
|
$0 manages an ICP Vortex clustered host drive.
|
|
|
|
The 'start' operation reserves the given host drive.
|
|
The 'stop' operation releses the given host drive.
|
|
The 'status' operation reports whether the host drive is reserved.
|
|
The 'monitor' operation reports whether the host drive is reserved.
|
|
The 'validate-all' operation reports whether OCF instance parameters are valid.
|
|
The 'methods' operation reports on the methods $0 supports
|
|
|
|
!
|
|
}
|
|
|
|
meta_data() {
|
|
cat <<END
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
|
<resource-agent name="ICP">
|
|
<version>1.0</version>
|
|
|
|
<longdesc lang="en">
|
|
Resource script for ICP. It Manages an ICP Vortex clustered host drive as an
|
|
HA resource.
|
|
</longdesc>
|
|
<shortdesc lang="en">ICP resource agent</shortdesc>
|
|
|
|
<parameters>
|
|
<parameter name="driveid" unique="0" required="1">
|
|
<longdesc lang="en">
|
|
The ICP cluster drive ID.
|
|
</longdesc>
|
|
<shortdesc lang="en">ICP cluster drive ID</shortdesc>
|
|
<content type="string" default="" />
|
|
</parameter>
|
|
|
|
<parameter name="device" unique="0" required="1">
|
|
<longdesc lang="en">
|
|
The device name.
|
|
</longdesc>
|
|
<shortdesc lang="en">device</shortdesc>
|
|
<content type="string" default="" />
|
|
</parameter>
|
|
</parameters>
|
|
|
|
<actions>
|
|
<action name="start" timeout="10" />
|
|
<action name="stop" timeout="10" />
|
|
<action name="status" depth="0" timeout="10" interval="10" start-delay="10" />
|
|
<action name="monitor" depth="0" timeout="10" interval="10" start-delay="10" />
|
|
<action name="validate-all" timeout="5" />
|
|
<action name="meta-data" timeout="5" />
|
|
</actions>
|
|
</resource-agent>
|
|
END
|
|
}
|
|
|
|
#
|
|
# methods: What methods/operations do we support?
|
|
#
|
|
ICP_methods() {
|
|
cat <<-!
|
|
start
|
|
stop
|
|
status
|
|
monitor
|
|
methods
|
|
validate-all
|
|
meta-data
|
|
usage
|
|
!
|
|
}
|
|
|
|
ICP_status() {
|
|
local icp_out
|
|
|
|
icp_out=$($ICPCLUCON -v -status $1)
|
|
if [ $? -ne 0 ]; then
|
|
ocf_log "err" "Hostdrive not reserved by us."
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
if expr match "$icp_out" \
|
|
'.*Drive is reserved by this host.*' >/dev/null 2>&1 ; then
|
|
ocf_log "info" "Volume $1 is reserved by us."
|
|
return $OCF_SUCCESS
|
|
elif expr match "$icp_out" \
|
|
'.*Drive is not reserved by any host.*' >/dev/null 2>&1 ; then
|
|
ocf_log "err" "Volume $1 not reserved by any host."
|
|
return $OCF_NOT_RUNNING
|
|
else
|
|
ocf_log "err" "Unknown output from icpclucon. Assuming we do not have a reservation:"
|
|
ocf_log "err" "$icp_out"
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
}
|
|
|
|
ICP_report_status() {
|
|
if ICP_status $1 ; then
|
|
echo "$1: running"
|
|
return $OCF_SUCCESS
|
|
else
|
|
echo "$1: not running"
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
}
|
|
|
|
|
|
#
|
|
# Monitor the host drive - does it really seem to be working?
|
|
#
|
|
#
|
|
ICP_monitor() {
|
|
|
|
if
|
|
ICP_status $1
|
|
then
|
|
return $?
|
|
else
|
|
ocf_log "err" "ICP host drive $1 is offline"
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
|
|
}
|
|
|
|
Clear_bufs() {
|
|
$BLOCKDEV --flushbufs $1
|
|
}
|
|
|
|
#
|
|
# Enable ICP host drive
|
|
#
|
|
ICP_start() {
|
|
|
|
ocf_log "info" "Activating host drive $1"
|
|
ocf_run $ICPCLUCON -v -reserve $1
|
|
if [ $? -ne 0 ]; then
|
|
ocf_log "info" "Forcing reservation of $1"
|
|
ocf_run $ICPCLUCON -v -force $1 || return $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
if
|
|
ICP_status $1
|
|
then
|
|
: OK
|
|
# A reservation isn't as prompt as it should be
|
|
sleep 3
|
|
return $OCF_SUCCESS
|
|
else
|
|
ocf_log "err" "ICP: $1 was not reserved correctly"
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Release the ICP host drive
|
|
#
|
|
ICP_stop() {
|
|
|
|
ocf_log "info" "Releasing ICP host drive $1"
|
|
ocf_run $ICPCLUCON -v -release $1 || return $OCF_ERR_GENERIC
|
|
|
|
ocf_log "info" "Verifying reservation"
|
|
if ICP_status $1 ; then
|
|
ocf_log "err" "ICP: $1 was not released correctly"
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
return $OCF_SUCCESS
|
|
}
|
|
|
|
ICP_validate_all() {
|
|
check_binary $BLOCKDEV
|
|
check_binary $ICPCLUCON
|
|
$ICPCLUCON -v -status $driveid >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
ocf_log err "Invalid driveid $driveid"
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
if [ ! -b $device ]; then
|
|
ocf_log err "Device $device is not a block device"
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
# Do not know how to check the association of $device with $driveid.
|
|
|
|
return $OCF_SUCCESS
|
|
}
|
|
|
|
#
|
|
# 'main' starts here...
|
|
#
|
|
|
|
if
|
|
( [ $# -ne 1 ] )
|
|
then
|
|
usage
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
# These operations do not require OCF instance parameters to be set
|
|
case "$1" in
|
|
|
|
meta-data) meta_data
|
|
exit $OCF_SUCCESS;;
|
|
|
|
methods) ICP_methods
|
|
exit $OCF_SUCCESS;;
|
|
|
|
usage) usage
|
|
exit $OCF_SUCCESS;;
|
|
|
|
*) ;;
|
|
esac
|
|
|
|
if
|
|
[ -z "$OCF_RESKEY_driveid" ]
|
|
then
|
|
ocf_log err "Please specify OCF_RESKEY_driveid"
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
if [ -z "$OCF_RESKEY_device" ]; then
|
|
ocf_log err "Please specify OCF_RESKEY_device"
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
driveid=$OCF_RESKEY_driveid
|
|
device=$OCF_RESKEY_device
|
|
|
|
# What kind of method was invoked?
|
|
case "$1" in
|
|
|
|
start) ICP_validate_all
|
|
ICP_start $driveid
|
|
Clear_bufs $device
|
|
exit $?;;
|
|
|
|
stop) ICP_stop $driveid
|
|
Clear_bufs $device
|
|
exit $?;;
|
|
|
|
status) ICP_report_status $driveid
|
|
exit $?;;
|
|
|
|
monitor) ICP_monitor $driveid
|
|
exit $?;;
|
|
|
|
validate-all) ICP_validate_all
|
|
exit $?;;
|
|
|
|
*) usage
|
|
exit $OCF_ERR_UNIMPLEMENTED;;
|
|
esac
|