- Prevent "reservation conflict" messageswhen scsi_reserve starts.
- Leave the fence domain if scsi_reserve fails to register with any device.
- Improve logging in scsi_reserve script.
- Use "locking_type = 0" for all lvm commands (ie. vgs).
- Fix SCSI reservations scripts to handle LVM mirrors and stripes.
- Not an error if fence_scsi attempts to remove a non-existent key from a
device.
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION" It is generated by the Makefile
-
#BEGIN_VERSION_GENERATION
$FENCE_RELEASE_NAME="";
$REDHAT_COPYRIGHT="";
@@ -195,7 +192,6 @@
return $key;
}
-
sub get_options_stdin
{
my $opt;
@@ -252,7 +248,8 @@
($dev) = @_;
my ($in, $out, $err);
- my $cmd = "sg_persist -d $dev -i -k";
+
+ my $cmd = "sg_persist -n -d $dev -i -k";
my $pid = open3($in, $out, $err, $cmd) or die "$!
";
+use POSIX;
use IPC::Open3;
-use Sys::Hostname;
+use XML::LibXML;
use Getopt::Std;
-use POSIX;
my @devices;
my %results;
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION" It is generated by the Makefile
-
#BEGIN_VERSION_GENERATION
$FENCE_RELEASE_NAME="";
$REDHAT_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
-sub get_key
+sub get_scsi_block_devices
{
- my $name = @_;
- my $addr = gethostbyname($name) or die "$!
";
+ my $block_dir = "/sys/block";
- return unpack("H*", $addr);
-}
+ opendir(DIR, $block_dir) or die "$!
";
-sub register_device
-{
- my $func = (caller(0))[3];
- my ($dev, $key) = @_;
+ my @block_devices = grep { /^sd*/ } readdir(DIR);
+# read in config file if it exists
+#
+if [ -f /etc/sysconfig/scsi_reserve ] ; then
+ . /etc/sysconfig/scsi_reserve
+fi
+
+# check if cluster is configured for fence_scsi
+#
+if ! fence_scsi_test -t fence ; then
+ logger -t scsi_reserve
+ "[error] cluster not configured for scsi reservations"
+ exit 1
+fi
+
+# check for nodeids in config file
+#
+if ! fence_scsi_test -t nodes ; then
+ logger -t scsi_reserve
+ "[error] cluster must define nodeid for all nodes"
+ exit 1
+fi
+
# check for sg_persist command provided by sg3_utils package
#
if ! sg_persist -V &> /dev/null ; then
- echo "error: sg_persist not found"
- exit 2
+ logger -t scsi_reserve
+ "[error] unable to exec sg_persist"
+ exit 1
fi
-# get scsi devices that are part of clustered volumes
+# check that cman is running
#
-scsi_devices=$( lvs -o vg_attr,devices --noheadings
- | awk --posix ' $1 ~ /[-a-z]{5}c/ { print $2 } '
- | sed -e 's/([0-9]*)//' | sort | uniq )
+if ! cman_tool status &> /dev/null ; then
+ logger -t scsi_reserve
+ "[error] cman does not appear to be running"
+ exit 1
+fi
-# if no scsi devices were found we can exit now
+# get physical volumes (devices) that are part of cluster volumes
#
-[ -z "$scsi_devices" ] && exit 0
+scsi_devices=$( vgs --config 'global { locking_type = 0 }'
+ --noheadings -o vg_attr,pv_name 2> /dev/null
+ | awk ' $1 ~ /.*c$/ { print $2 } ' )
+
+if [ -z "$scsi_devices" ] ; then
+ logger -t scsi_reserve
+ "[error] did not find devices in cluster volumes"
+ exit 1
+fi
-# get the node name and node addr from cman
+# get the cluster id from cman
#
-node_name=$( cman_tool status | grep "Node name" | awk -F": " '{ print $2 }' )
-node_addr=$( cman_tool status | grep "Node addr" | awk -F": " '{ print $2 }' )
+cluster_id=$( cman_tool status | grep -i "Cluster ID"
+ | awk -F": " '{ print $2 }' )
+
+if [ -z "$cluster_id" ] ; then
+ logger -s -t scsi_reserve
+ "[error] unable to determine cluster id"
+ exit 1
+fi
-# get cluster id and node id from cman
+# get the node id from cman
#
-c_id=$( cman_tool status | grep -i "Cluster ID" | awk -F": " '{ print $2 }' )
-n_id=$( cman_tool status | grep -i "Node ID" | awk -F": " '{ print $2 }' )
+node_id=$( cman_tool status | grep -i "Node ID"
+ | awk -F": " '{ print $2 }' )
-status)
+ for dev in $scsi_devices
+ do
+ # get list of keys registered with this device
+ #
+ key_list=$( sg_persist -n -d $dev -i -k | grep -iE "^[[:space:]]*0x" )
+
+ # check that our key is registered with this device
+ #
+ if ! sg_persist -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then
+ logger -t scsi_reserve
+ "[info] not registered with $dev (key=0x$key)"
+ continue
+ fi
+
+ # check if our key is the reservation holder
+ #
+ if sg_persist -n -d $dev -i -r 2>/dev/null | grep -qiE "$key" ; then
+ if echo "$key_list" | grep -qivE "$key" ; then
+ logger -t scsi_reserve
+ "[error] unable to remove registration on $dev (key=0x$key)"
+ : $[ count = $count + 1 ]
+ error=1
+ continue
+ fi
+ fi
+
+ # remove registration for this device
+ #
+ if ! sg_persist -n -d $dev -o -G -K $key -S 0 &> /dev/null ; then
+ logger -t scsi_reserve
+ "[error] failed to remove registration on $dev (key=0x$key)"
+ : $[ count = $count + 1 ]
+ error=1
+ else
+ logger -t scsi_reserve
+ "[info] removed registration on $dev (key=0x$key)"
+ fi
+
+ done
+
+ # report success or failure
+ #
+ if [ $error -eq 0 ] ; then
+ success
+ else
+ logger -t scsi_reserve
+ "[info] $count errors occured during unregistration"
+ failure
+ fi
-rval=0
+ echo
-# find devices that are registered with our key
-#
-for dev in $scsi_devices
-do
- if sg_persist -d $dev -i -k 2>/dev/null | grep -qiE "$key" ; then
- devices[${#devices[@]}]=$dev
- fi
-done
+ ;; # end of stop
-if [ -z "$devices" ]; then
- echo "No devices resgistered."
-else
- echo "Found ${#devices[@]} registered device(s):"
+ status)
- for i in "${devices[@]}" ; do
- echo $i
- done
-fi
-;;
+ error=0
-esac
+ for dev in $scsi_devices
+ do
+ if sg_persist -n -d $dev -i -k | grep -qiE "$key" ; then
+ devices[${#devices[@]}]=$dev
+ fi
+ done
+
+ if [ -z "$devices" ] ; then
+ echo "No registered devices found."
+ else
+ echo "Found ${#devices[@]} registered device(s):"
+
+ for i in "${devices[@]}"
+ do
+ echo $i
+ done
+ fi
+
+ ;; # end of status