1#!/usr/local/bin/bash
2#
3#
4# LinuxSCSI
5#
6# Description:	Enables/Disables SCSI devices to protect them from being
7#		used by mistake
8#
9#
10# Author:	Alan Robertson
11#		Support: users@clusterlabs.org
12# License:	GNU General Public License (GPL)
13# Copyright:	(C) 2002 - 2005 IBM
14#
15# CAVEATS:	See the usage message for some important warnings
16#
17# usage: ./LinuxSCSI (start|stop|status|monitor|meta-data|validate-all|methods)
18#
19#	  OCF parameters are as below:
20#		OCF_RESKEY_scsi
21#
22# An example usage in /etc/ha.d/haresources:
23#       node1  10.0.0.170 LinuxSCSI:0:0:11
24#
25
26#######################################################################
27# Initialization:
28
29: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
30. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
31
32# Parameter defaults
33
34OCF_RESKEY_scsi_default=""
35OCF_RESKEY_ignore_deprecation_default="false"
36
37: ${OCF_RESKEY_scsi=${OCF_RESKEY_scsi_default}}
38: ${OCF_RESKEY_ignore_deprecation=${OCF_RESKEY_ignore_deprecation_default}}
39
40#######################################################################
41
42zeropat="[ 0]0"
43
44PROCSCSI=/proc/scsi/scsi
45
46usage() {
47  cat <<EOF
48	usage: $0 (start|stop|status|monitor|meta-data|validate-all|methods)
49
50	$0 manages the availability of a SCSI device from the point
51	of view of the linux kernel.  It make Linux believe the
52	device has gone away, and it can make it come back again.
53
54	The purpose of this resource script is to keep admins from
55	accidentally messing with a shared disk that is managed by the
56	HA subsystem and is currently owned by the other side.
57
58	To get maximum benefit from this feature, you should (manually)
59	disable the resources on boot, and let your HA software enable
60	them when it wants to acquire the disk.
61	
62	The kernel code says this is potentially dangerous.  DO NOT USE
63	IT ON AN ACTIVE DEVICE.  If the device is inactive, this script
64	will make it stay inactive, when given "off".  If you inactivate
65	the wrong device, you may have to reboot your machine, and your
66	data may take a hit.
67
68	On the other hand, at least one RAID controller requires the
69	use of this technique for it to work correctly in a failover
70	environment - so it is believed that it is more stable in this
71	usage than the comments in the code imply.
72
73	Here are the warnings from the kernel source about the "stop"
74	operation as of 2.4.10:
75
76	------------------------------
77	Consider this feature pre-BETA.
78	    CAUTION: This is not for hotplugging your peripherals. As
79	    SCSI was not designed for this, you could damage your
80	    hardware and thoroughly confuse the SCSI subsystem.
81
82	Similar warnings apply to the "start" operation...
83
84	 Consider this feature BETA.
85	     CAUTION: This is not for hotplugging your peripherals.
86	     As SCSI was not designed for this you could damage your
87	     hardware !
88	However perhaps it is legal to switch on an already connected
89	device. It is perhaps not guaranteed this device doesn't corrupt
90	an ongoing data transfer.
91	-------------------------
92
93	So, Caveat Emptor, and test this feature thoroughly on
94	your kernel and your configuration with real load on the SCSI
95	bus before using it in production!
96
97	Another potential trouble spot...
98	The order in which you bring up LinuxSCSI resources determines which
99	SCSI device they show up as on Linux.  If you have two SCSI devices
100	in different resource groups they will be brought up asyncronously
101	resulting in indeterminate device name assignments.  This usually
102	happens in an active-active configuration.
103	
104	To solve this you probably should use LVM or EVMS to manage these
105	volumes.  LVM and EVMS solve this problem for you by labels they
106	keep in the volumes.  If you don't use a reasonable volume manager,
107	then you'll have to mount by UUID.
108
109EOF
110}
111
112meta_data() {
113	cat <<EOF
114<?xml version="1.0"?>
115<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
116<resource-agent name="LinuxSCSI">
117<version>1.0</version>
118
119<longdesc lang="en">
120Deprecation warning: This agent makes use of Linux SCSI hot-plug
121functionality which has been superseded by SCSI reservations. It is
122deprecated and may be removed from a future release. See the
123scsi2reservation and sfex agents for alternatives. --
124This is a resource agent for LinuxSCSI. It manages the availability of a
125SCSI device from the point of view of the linux kernel. It make Linux
126believe the device has gone away, and it can make it come back again.
127</longdesc>
128<shortdesc lang="en">Enables and disables SCSI devices through the
129kernel SCSI hot-plug subsystem (deprecated)</shortdesc>
130
131<parameters>
132<parameter name="scsi" unique="0" required="1">
133<longdesc lang="en">
134The SCSI instance to be managed.
135</longdesc>
136<shortdesc lang="en">SCSI instance</shortdesc>
137<content type="string" default="${OCF_RESKEY_scsi_default}" />
138</parameter>
139
140<parameter name="ignore_deprecation">
141<longdesc lang="en">
142If set to true, suppresses the deprecation warning for this agent.
143</longdesc>
144<shortdesc lang="en">Suppress deprecation warning</shortdesc>
145<content type="boolean" default="${OCF_RESKEY_ignore_deprecation_default}" />
146</parameter>
147
148</parameters>
149
150<actions>
151<action name="start" timeout="20s" />
152<action name="stop" timeout="20s" />
153<action name="methods" timeout="5s" />
154<action name="status" depth="0" timeout="20s" interval="10s" />
155<action name="monitor" depth="0" timeout="20s" interval="10s" />
156<action name="meta-data" timeout="5s" />
157<action name="validate-all" timeout="5s" />
158</actions>
159</resource-agent>
160EOF
161}
162
163scsi_methods() {
164  cat <<EOF
165	start
166	stop
167	status
168	monitor
169	validate-all
170	methods
171EOF
172}
173
174
175parseinst() {
176  lun=0
177  case "$1" in
178
179    [0-9]*:[0-9]*:[0-9]*);;
180
181    [0-9]*:[0-9]*:[0-9]*:[0-9]*)
182	lun=`echo "$1" | cut -d: -f4`;;
183
184    *)	#host=error
185	#channel=error
186	#target=error
187	#lun=error
188	ocf_log err "Invalid SCSI instance $1"
189	exit $OCF_ERR_ARGS
190  esac
191  host=`echo "$1" | cut -d: -f1`
192  channel=`echo "$1" | cut -d: -f2`
193  target=`echo "$1" | cut -d: -f3`
194}
195
196#
197# start: Enable the given SCSI device in the kernel
198#
199scsi_start() {
200  parseinst "$1"
201#  [ $target = error ] && exit 1
202#  echo "scsi-add-single-device $host $channel $target $lun" >>$PROCSCSI
203  echo "scsi add-single-device $host $channel $target $lun" >>$PROCSCSI
204  if
205    scsi_status "$1"
206  then
207    return $OCF_SUCCESS
208  else
209    ocf_log err "SCSI device $1 not active!"
210    return $OCF_ERR_GENERIC
211  fi
212}
213
214
215#
216# stop: Disable the given SCSI device in the kernel
217#
218scsi_stop() {
219  parseinst "$1"
220#  [ $target = error ] && exit 1
221  echo "scsi remove-single-device $host $channel $target $lun" >>$PROCSCSI
222  if
223    scsi_status "$1"
224  then
225    ocf_log err "SCSI device $1 still active!"
226    return $OCF_ERR_GENERIC
227  else
228    return $OCF_SUCCESS
229  fi
230}
231
232
233#
234# status: is the given device now available?
235#
236scsi_status() {
237  parseinst "$1"
238#  [ $target = error ] && exit 1
239  [ $channel -eq 0 ]	&& channel=$zeropat
240  [ $target -eq 0 ]	&& target=$zeropat
241  [ $lun -eq 0 ]	&& lun=$zeropat
242  greppat="Host: *scsi$host *Channel: *$channel *Id: *$target *Lun: *$lun"
243  grep -i "$greppat" $PROCSCSI >/dev/null
244  if [ $? -eq 0 ]; then
245	return $OCF_SUCCESS
246  else
247	return $OCF_NOT_RUNNING
248  fi
249}
250
251#
252# validate_all: Check the OCF instance parameters
253#
254scsi_validate_all() {
255  parseinst $instance
256  return $OCF_SUCCESS
257}
258
259if
260  ( [ $# -ne 1 ] )
261then
262  ocf_log err "Parameter number error."
263  usage
264  exit $OCF_ERR_GENERIC
265fi
266
267#if
268#  [ -z "$OCF_RESKEY_scsi" ] && [ "X$1" = "Xmethods" ]
269#then
270#  scsi_methods
271#  exit #?
272#fi
273case $1 in
274  methods)		scsi_methods
275			exit $OCF_SUCCESS
276			;;
277  meta-data)		meta_data
278			exit $OCF_SUCCESS
279			;;
280  usage)		usage
281			exit $OCF_SUCCESS
282			;;
283  *)			;;
284esac
285
286# Be obnoxious, log deprecation warning on every invocation (unless
287# suppressed by resource configuration).
288ocf_deprecated
289
290if
291  [ -z "$OCF_RESKEY_scsi" ]
292then
293  ocf_log err "You have to set a valid scsi id at least!"
294#  usage
295  exit $OCF_ERR_GENERIC
296fi
297
298instance=$OCF_RESKEY_scsi
299
300case $1 in
301  start)		scsi_start $instance
302			;;
303  stop)			scsi_stop $instance
304			;;
305  status|monitor)
306	 		if
307			  scsi_status $instance
308			then
309			  ocf_log info "SCSI device $instance is running"
310			  return $OCF_SUCCESS
311			else
312			  ocf_log info "SCSI device $instance is stopped"
313			  exit $OCF_NOT_RUNNING
314			fi
315			;;
316  validate-all)		scsi_validate_all
317			;;
318  *)			usage
319			exit $OCF_ERR_UNIMPLEMENTED
320			;;
321esac
322exit $?
323