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
7.1 KiB
296 lines
7.1 KiB
#!/bin/sh
|
|
#
|
|
#
|
|
# LinuxSCSI
|
|
#
|
|
# Description: Enables/Disables SCSI devices to protect them from being
|
|
# used by mistake
|
|
#
|
|
#
|
|
# Author: Alan Robertson
|
|
# Support: linux-ha@lists.linux-ha.org
|
|
# License: GNU General Public License (GPL)
|
|
# Copyright: (C) 2002 - 2005 IBM
|
|
#
|
|
# CAVEATS: See the usage message for some important warnings
|
|
#
|
|
# usage: ./LinuxSCSI (start|stop|status|monitor|meta-data|validate-all|methods)
|
|
#
|
|
# OCF parameters are as below:
|
|
# OCF_RESKEY_scsi
|
|
#
|
|
# An example usage in /etc/ha.d/haresources:
|
|
# node1 10.0.0.170 LinuxSCSI:0:0:11
|
|
#
|
|
|
|
#######################################################################
|
|
# Initialization:
|
|
|
|
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
|
|
|
|
#######################################################################
|
|
|
|
zeropat="[ 0]0"
|
|
|
|
PROCSCSI=/proc/scsi/scsi
|
|
|
|
usage() {
|
|
cat <<-!
|
|
usage: $0 (start|stop|status|monitor|meta-data|validate-all|methods)
|
|
|
|
$0 manages the availability of a SCSI device from the point
|
|
of view of the linux kernel. It make Linux believe the
|
|
device has gone away, and it can make it come back again.
|
|
|
|
The purpose of this resource script is to keep admins from
|
|
accidentally messing with a shared disk that is managed by the
|
|
HA subsystem and is currently owned by the other side.
|
|
|
|
To get maximum benefit from this feature, you should (manually)
|
|
disable the resources on boot, and let your HA software enable
|
|
them when it wants to acquire the disk.
|
|
|
|
The kernel code says this is potentially dangerous. DO NOT USE
|
|
IT ON AN ACTIVE DEVICE. If the device is inactive, this script
|
|
will make it stay inactive, when given "off". If you inactivate
|
|
the wrong device, you may have to reboot your machine, and your
|
|
data may take a hit.
|
|
|
|
On the other hand, at least one RAID controller requires the
|
|
use of this technique for it to work correctly in a failover
|
|
environment - so it is believed that it is more stable in this
|
|
usage than the comments in the code imply.
|
|
|
|
Here are the warnings from the kernel source about the "stop"
|
|
operation as of 2.4.10:
|
|
|
|
------------------------------
|
|
Consider this feature pre-BETA.
|
|
CAUTION: This is not for hotplugging your peripherals. As
|
|
SCSI was not designed for this, you could damage your
|
|
hardware and thoroughly confuse the SCSI subsystem.
|
|
|
|
Similar warnings apply to the "start" operation...
|
|
|
|
Consider this feature BETA.
|
|
CAUTION: This is not for hotplugging your peripherals.
|
|
As SCSI was not designed for this you could damage your
|
|
hardware !
|
|
However perhaps it is legal to switch on an already connected
|
|
device. It is perhaps not guaranteed this device doesn't corrupt
|
|
an ongoing data transfer.
|
|
-------------------------
|
|
|
|
So, Caveat Emptor, and test this feature thoroughly on
|
|
your kernel and your configuration with real load on the SCSI
|
|
bus before using it in production!
|
|
|
|
Another potential trouble spot...
|
|
The order in which you bring up LinuxSCSI resources determines which
|
|
SCSI device they show up as on Linux. If you have two SCSI devices
|
|
in different resource groups they will be brought up asyncronously
|
|
resulting in indeterminate device name assignments. This usually
|
|
happens in an active-active configuration.
|
|
|
|
To solve this you probably should use LVM or EVMS to manage these
|
|
volumes. LVM and EVMS solve this problem for you by labels they
|
|
keep in the volumes. If you don't use a reasonable volume manager,
|
|
then you'll have to mount by UUID.
|
|
|
|
!
|
|
}
|
|
|
|
meta_data() {
|
|
cat <<END
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
|
<resource-agent name="LinuxSCSI">
|
|
<version>1.0</version>
|
|
|
|
<longdesc lang="en">
|
|
This is a resource agent for LinuxSCSI. It manages the availability of a
|
|
SCSI device from the point of view of the linux kernel. It make Linux
|
|
believe the device has gone away, and it can make it come back again.
|
|
</longdesc>
|
|
<shortdesc lang="en">LinuxSCSI resource agent</shortdesc>
|
|
|
|
<parameters>
|
|
<parameter name="scsi" unique="0" required="1">
|
|
<longdesc lang="en">
|
|
The SCSI instance to be managed.
|
|
</longdesc>
|
|
<shortdesc lang="en">SCSI instance</shortdesc>
|
|
<content type="string" default="" />
|
|
</parameter>
|
|
</parameters>
|
|
|
|
<actions>
|
|
<action name="start" timeout="10" />
|
|
<action name="stop" timeout="10" />
|
|
<action name="methods" timeout="5" />
|
|
<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="meta-data" timeout="5" />
|
|
<action name="validate-all" timeout="5" />
|
|
</actions>
|
|
</resource-agent>
|
|
END
|
|
}
|
|
|
|
scsi_methods() {
|
|
cat <<-!
|
|
start
|
|
stop
|
|
status
|
|
monitor
|
|
validate-all
|
|
methods
|
|
!
|
|
}
|
|
|
|
|
|
parseinst() {
|
|
lun=0
|
|
case "$1" in
|
|
|
|
[0-9]*:[0-9]*:[0-9]*);;
|
|
|
|
[0-9]*:[0-9]*:[0-9]*:[0-9]*)
|
|
lun=`echo "$1" | cut -d: -f4`;;
|
|
|
|
*) #host=error
|
|
#channel=error
|
|
#target=error
|
|
#lun=error
|
|
ocf_log err "Invalid SCSI instance $1"
|
|
exit $OCF_ERR_ARGS
|
|
esac
|
|
host=`echo "$1" | cut -d: -f1`
|
|
channel=`echo "$1" | cut -d: -f2`
|
|
target=`echo "$1" | cut -d: -f3`
|
|
}
|
|
|
|
#
|
|
# start: Enable the given SCSI device in the kernel
|
|
#
|
|
scsi_start() {
|
|
parseinst "$1"
|
|
# [ $target = error ] && exit 1
|
|
# echo "scsi-add-single-device $host $channel $target $lun" >>$PROCSCSI
|
|
echo "scsi add-single-device $host $channel $target $lun" >>$PROCSCSI
|
|
if
|
|
scsi_status "$1"
|
|
then
|
|
return $OCF_SUCCESS
|
|
else
|
|
ocf_log err "SCSI device $1 not active!"
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
}
|
|
|
|
|
|
#
|
|
# stop: Disable the given SCSI device in the kernel
|
|
#
|
|
scsi_stop() {
|
|
parseinst "$1"
|
|
# [ $target = error ] && exit 1
|
|
echo "scsi remove-single-device $host $channel $target $lun" >>$PROCSCSI
|
|
if
|
|
scsi_status "$1"
|
|
then
|
|
ocf_log err "SCSI device $1 still active!"
|
|
return $OCF_ERR_GENERIC
|
|
else
|
|
return $OCF_SUCCESS
|
|
fi
|
|
}
|
|
|
|
|
|
#
|
|
# status: is the given device now available?
|
|
#
|
|
scsi_status() {
|
|
parseinst "$1"
|
|
# [ $target = error ] && exit 1
|
|
[ $channel -eq 0 ] && channel=$zeropat
|
|
[ $target -eq 0 ] && target=$zeropat
|
|
[ $lun -eq 0 ] && lun=$zeropat
|
|
greppat="Host: *scsi$host *Channel: *$channel *Id: *$target *Lun: *$lun"
|
|
grep -i "$greppat" $PROCSCSI >/dev/null
|
|
if [ $? -eq 0 ]; then
|
|
return $OCF_SUCCESS
|
|
else
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
}
|
|
|
|
#
|
|
# validate_all: Check the OCF instance parameters
|
|
#
|
|
scsi_validate_all() {
|
|
parseinst $instance
|
|
return $OCF_SUCCESS
|
|
}
|
|
|
|
if
|
|
( [ $# -ne 1 ] )
|
|
then
|
|
ocf_log err "Parameter number error."
|
|
usage
|
|
exit $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
#if
|
|
# [ -z "$OCF_RESKEY_scsi" ] && [ "X$1" = "Xmethods" ]
|
|
#then
|
|
# scsi_methods
|
|
# exit #?
|
|
#fi
|
|
case $1 in
|
|
methods) scsi_methods
|
|
exit $OCF_SUCCESS
|
|
;;
|
|
meta-data) meta_data
|
|
exit $OCF_SUCCESS
|
|
;;
|
|
usage) usage
|
|
exit $OCF_SUCCESS
|
|
;;
|
|
*) ;;
|
|
esac
|
|
|
|
if
|
|
[ -z "$OCF_RESKEY_scsi" ]
|
|
then
|
|
ocf_log err "You have to set a valid scsi id at least!"
|
|
# usage
|
|
exit $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
instance=$OCF_RESKEY_scsi
|
|
|
|
case $1 in
|
|
start) scsi_start $instance
|
|
;;
|
|
stop) scsi_stop $instance
|
|
;;
|
|
status|monitor)
|
|
if
|
|
scsi_status $instance
|
|
then
|
|
ocf_log info "SCSI device $instance is running"
|
|
return $OCF_SUCCESS
|
|
else
|
|
ocf_log info "SCSI device $instance is stopped"
|
|
exit $OCF_NOT_RUNNING
|
|
fi
|
|
;;
|
|
validate-all) scsi_validate_all
|
|
;;
|
|
*) usage
|
|
exit $OCF_ERR_UNIMPLEMENTED
|
|
;;
|
|
esac
|
|
exit $?
|