FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 01-18-2008, 10:02 PM
 
Default cluster/fence/agents/scsi fence_scsi.pl fence_ ...

CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL5
Changes by: rohara@sourceware.org 2008-01-18 23:02:58

Modified files:
fence/agents/scsi: fence_scsi.pl fence_scsi_test.pl scsi_reserve

Log message:
BZ: 373491, 373511, 373531, 373541, 373571, 429033
BZ: 373491, 373511, 373531, 373541, 373571, 429033

- 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.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/fence/agents/scsi/fence_scsi.pl.diff?cvsroot=cluster&only_with_tag=R HEL5&r1=1.5.2.6&r2=1.5.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/fence/agents/scsi/fence_scsi_test.pl.diff?cvsroot=cluster&only_with_ tag=RHEL5&r1=1.1.2.2&r2=1.1.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/fence/agents/scsi/scsi_reserve.diff?cvsroot=cluster&only_with_tag=RH EL5&r1=1.1.2.8&r2=1.1.2.9

--- cluster/fence/agents/scsi/fence_scsi.pl 2007/11/08 18:48:08 1.5.2.6
+++ cluster/fence/agents/scsi/fence_scsi.pl 2008/01/18 23:02:58 1.5.2.7
@@ -11,9 +11,6 @@
s/.*///;
my $pname = $_;

-# 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 "$!
";

waitpid($pid, 0);
@@ -278,46 +275,36 @@
return %key_list;
}

-#sub get_scsi_devices
-#{
-# my ($in, $out, $err);
-# my $cmd = "lvs --noheadings --separator : -o vg_attr,devices";
-# my $pid = open3($in, $out, $err, $cmd) or die "$!
";
-#
-# waitpid($pid, 0);
-#
-# die "Unable to execute lvs.
" if ($?>>8);
-#
-# while (<$out>)
-# {
-# chomp;
-# print "OUT: $_
" if $opt_v;
-#
-# my ($vg_attrs, $device) = split(/:/, $_);
-#
-# if ($vg_attrs =~ /.*c$/)
-# {
-# $device =~ s/(.*)//;
-# push(@volumes, $device);
-# }
-# }
-#
-# close($in);
-# close($out);
-# close($err);
-#}
-
sub get_scsi_devices
{
- open(FILE, "/var/run/scsi_reserve") or die "$!
";
+ my ($in, $out, $err);
+
+ my $cmd = "vgs --config 'global { locking_type = 0 }'" .
+ " --noheadings --separator : -o vg_attr,pv_name";

- while (<FILE>)
+ my $pid = open3($in, $out, $err, $cmd) or die "$!
";
+
+ waitpid($pid, 0);
+
+ die "Unable to execute lvs.
" if ($?>>8);
+
+ while (<$out>)
{
chomp;
- push(@volumes, $_);
+ print "OUT: $_
" if $opt_v;
+
+ my ($vg_attrs, $device) = split(/:/, $_);
+
+ if ($vg_attrs =~ /.*c$/)
+ {
+ $device =~ s/(.*)//;
+ push(@volumes, $device);
+ }
}

- close FILE;
+ close($in);
+ close($out);
+ close($err);
}

sub check_sg_persist
@@ -346,7 +333,7 @@
($dev, $key) = @_;

my ($in, $out, $err);
- my $cmd = "sg_persist -d $dev -o -G -S $key";
+ my $cmd = "sg_persist -n -d $dev -o -G -S $key";
my $pid = open3($in, $out, $err, $cmd) or die "$!
";

waitpid($pid, 0);
@@ -383,13 +370,18 @@
do_register($dev, $host_key);
}

+ if (!$key_list{$node_key})
+ {
+ next;
+ }
+
if ($host_key eq $node_key)
{
- $cmd = "sg_persist -d $dev -o -G -K $host_key -S 0";
+ $cmd = "sg_persist -n -d $dev -o -G -K $host_key -S 0";
}
else
{
- $cmd = "sg_persist -d $dev -o -A -K $host_key -S $node_key -T 5";
+ $cmd = "sg_persist -n -d $dev -o -A -K $host_key -S $node_key -T 5";
}

my $pid = open3($in, $out, $err, $cmd) or die "$!
";
@@ -419,7 +411,7 @@
usage if defined $opt_h;
version if defined $opt_V;

- fail_usage "Unkown parameter." if (@ARGV > 0);
+ fail_usage "Unknown parameter." if (@ARGV > 0);

fail_usage "No '-n' flag specified." unless defined $opt_n;

--- cluster/fence/agents/scsi/fence_scsi_test.pl 2007/03/06 19:10:34 1.1.2.2
+++ cluster/fence/agents/scsi/fence_scsi_test.pl 2008/01/18 23:02:58 1.1.2.3
@@ -1,123 +1,96 @@
#!/usr/bin/perl

+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);

- print "DEBUG: $func ($dev, $key)
" if ($opt_d);
+ closedir(DIR);

+ for $block_dev (@block_devices)
+ {
+ push(@devices, "/dev/" . $block_dev);
+ }
+}
+
+sub get_cluster_vol_devices
+{
my ($in, $out, $err);
- my $cmd = "sg_persist -d $dev -o -G -S $key";
+
+ my $cmd = "vgs --config 'global { locking_type = 0 }'" .
+ " --noheadings --separator : -o vg_attr,pv_name";

my $pid = open3($in, $out, $err, $cmd) or die "$!
";

waitpid($pid, 0);

- my $rval = WEXITSTATUS($?);
+ die "[error] unable to execute vgs command.
" if WEXITSTATUS($?);

- $results{$dev}[0] = $rval;
+ while (<$out>)
+ {
+ chomp;

- print "DEBUG: [$rval] $cmd
" if ($opt_d);
+ my ($vg_attr, $pv_name) = split(/:/, $_);
+
+ if ($vg_attr =~ /.*c$/)
+ {
+ ###### DEBUG ######
+ print "DEBUG: pv_name = $pv_name
";
+
+ push(@devices, $pv_name);
+ }
+ }

close($in);
close($out);
close($err);
-
- return $rval;
}

-sub unregister_device
+sub register_device
{
- my $func = (caller(0))[3];
my ($dev, $key) = @_;
-
- print "DEBUG: $func ($dev, $key)
" if ($opt_d);
-
my ($in, $out, $err);
- my $cmd = "sg_persist -d $dev -o -G -K $key -S 0";

+ my $cmd = "sg_persist -n -d $dev -o -G -S $key";
my $pid = open3($in, $out, $err, $cmd) or die "$!
";

waitpid($pid, 0);

- my $rval = WEXITSTATUS($?);
-
- $results{$dev}[1] = $rval;
-
- print "DEBUG: [$rval] $cmd
" if ($opt_d);
+ $results{$dev}[0] = WEXITSTATUS($?);

close($in);
close($out);
close($err);
-
- return $rval;
-}
-
-sub get_block_devices
-{
- my $block_dir = "/sys/block";
-
- opendir(DIR, $block_dir) or die "Error: $! $block_dir
";
-
- my @block_devices = grep { /^sd*/ } readdir(DIR);
-
- closedir(DIR);
-
- for $dev (@block_devices)
- {
- push @devices, "/dev/" . $dev;
- }
}

-sub get_cluster_devices
+sub unregister_device
{
+ my ($dev, $key) = @_;
my ($in, $out, $err);
- my $cmd = "lvs --noheadings --separator : -o vg_attr,devices";

+ my $cmd = "sg_persist -n -d $dev -o -G -K $key -S 0";
my $pid = open3($in, $out, $err, $cmd) or die "$!
";

waitpid($pid, 0);

- die "Error: unable to exec lvs command.
" if WEXITSTATUS($?);
-
- while (<$out>)
- {
- chomp;
-
- my ($vg_attr, $dev) = split(/:/, $_);
-
- if ($vg_attr =~ /.*c$/)
- {
- $dev =~ s/(.*)//;
- push @devices, $dev;
- }
- }
+ $results{$dev}[1] = WEXITSTATUS($?);

close($in);
close($out);
@@ -126,20 +99,38 @@

sub test_devices
{
- my $name = hostname() or die "$!
";
- my $key = get_key($name);
+ my $key = "0xDEADBEEF";

foreach $dev (@devices)
{
- if (register_device($dev, $key) != 0)
- {
- }
- if (unregister_device($dev, $key) != 0)
- {
- }
+ register_device($dev, $key);
+ unregister_device($dev, $key);
}
}

+sub check_config_fence
+{
+ my $xml = XML::LibXML->new();
+ my $tree = $xml->parse_file("/etc/cluster/cluster.conf");
+ my $root = "//cluster/fencedevices/fencedevice";
+
+ my $xpath_fence = "count(${root}[@agent='fence_scsi'])";
+
+ return ( ! $tree->findvalue($xpath_fence));
+}
+
+sub check_config_nodes
+{
+ my $xml = XML::LibXML->new();
+ my $tree = $xml->parse_file("/etc/cluster/cluster.conf");
+ my $root = "//cluster/clusternodes/clusternode";
+
+ my $xpath_name = "count(${root}/@name)";
+ my $xpath_nodeid = "count(${root}/@nodeid)";
+
+ return ($tree->findvalue($xpath_name) != $tree->findvalue($xpath_nodeid));
+}
+
sub print_results
{
my $device_count = scalar(@devices);
@@ -196,9 +187,9 @@
print " -h Help. Prints out this usage information.

";
}

-### MAIN ################################################## #####
+### MAIN ################################################## #####################

-if (getopts("cdhsv") == 0)
+if (getopts("cdhst:v") == 0)
{
print_usage;
exit(1);
@@ -213,25 +204,34 @@
if ($opt_c)
{
print "
Testing devices in cluster volumes...
";
- get_cluster_devices;
+ get_cluster_vol_devices;
+ test_devices;
+ print_results;
}

if ($opt_s)
{
print "
Testing all SCSI block devices...
";
- get_block_devices;
+ get_scsi_block_devices;
+ test_devices;
+ print_results;
+}
+
+if ($opt_t)
+{
+ if ($opt_t eq "fence")
+ {
+ exit check_config_fence;
+ }
+ if ($opt_t eq "nodes")
+ {
+ exit check_config_nodes;
+ }
}

-if (!$opt_c && !$opt_s)
+if (!$opt_c && !$opt_s && !$opt_t)
{
print "
Please specify either cluster or SCSI mode.
";
print_usage;
exit(1);
}
-
-test_devices;
-
-print_results;
-
-exit 0;
-
--- cluster/fence/agents/scsi/scsi_reserve 2007/11/08 18:48:08 1.1.2.8
+++ cluster/fence/agents/scsi/scsi_reserve 2008/01/18 23:02:58 1.1.2.9
@@ -1,166 +1,248 @@
#!/bin/bash
#
+# scsi_reserve:
+#
# chkconfig: 345 25 75
-# description: start/stop persistent reservation service for lvm
+# description:
+# config: /etc/sysconfig/scsi_reserve

. /etc/init.d/functions

+# 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 }' )

-[ -z "$c_id" ] && exit 1
-[ -z "$n_id" ] && exit 1
+if [ -z "$node_id" ] ; then
+ logger -t scsi_reserve
+ "[error] unable to determine node id"
+ exit 1
+fi

-# create unique key for this host
+# generate unique key using cluster_id and node_id
#
-key=$( printf "%x%.4x" $c_id $n_id )
+key=$( printf "%x%.4x" $cluster_id $node_id )
+
+if [ -z "$key" ] ; then
+ logger -t scsi_reserve
+ "[error] unable to generate key"
+ exit 1
+fi

-################################################## #############################
+################################################# ###############################

case $1 in

-start)
+ start)

-rval=0
+ error=0
+ count=0

-echo "$key" > /var/lock/subsys/scsi_reserve
+ echo -n "Starting scsi_reserve:"

-cat /dev/null > /var/run/scsi_reserve
+ for dev in $scsi_devices
+ do
+ # check if our key is already resgistered with this device
+ #
+ if sg_persist -n -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then
+ logger -t scsi_reserve
+ "[info] already registered with $dev (key=0x$key)"
+ continue
+ fi
+
+ # create the scsi registration
+ #
+ if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then
+ logger -t scsi_reserve
+ "[error] unable to register device $dev (key=0x$key)"
+ : $[ count = $count + 1 ]
+ error=1
+ else
+ logger -t scsi_reserve
+ "[info] registered with device $dev (key=0x$key)"
+ fi
+
+ # check to see if reservation already exists
+ #
+ if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then
+ logger -t scsi_reserve
+ "[info] reservation already exists on $dev"
+ continue
+ fi
+
+ # create the scsi reservation
+ #
+ if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then
+ logger -t scsi_reserver
+ "[error] unable to create reservation on $dev (key=0x$key)"
+ : $[ count = $count + 1 ]
+ error=1
+ fi
+ done
+
+ # leave fence domain if any errors occured during registration
+ #
+ if [ $error -eq 0 ] ; then
+ success
+ else
+ logger -t scsi_reserve
+ "[info] $count errors during registration"
+ logger -t scsi_reserve
+ "[info] leaving the fence domain"
+ fence_tool leave
+ failure
+ fi

-# register each device using our key
-#
-for dev in $scsi_devices
-do
-
- echo -n "Registering device: $dev"
-
- for error in 1
- do
- sg_persist -d $dev -o -G -S $key &>/dev/null || break
- error=0
- done
-
- if [ $error -eq 0 ]; then
- echo $dev >> /var/run/scsi_reserve
- success
- else
- # perhaps we are already resgistered
- #
- if sg_persist -d $dev -i -k 2>/dev/null | grep -qiE "$key" ; then
- echo $dev >> /var/run/scsi_reserve
- success
- else
- failure
- rval=1
- fi
- fi
-
- echo
-
- # create a reservation
- #
- sg_persist -d $dev -o -R -K $key -T 5 &>/dev/null
-
-done
-;;
-
-stop)
-
-rval=0
-
-# unregister each device for this node
-#
-for dev in $scsi_devices
-do
- echo -n "Unregistering device: $dev"
-
- # get list of keys registered for this device
- #
- reg_keys=$( sg_persist -d $dev -i -k | grep '^[[:space:]]*0x' )
-
- # check if this node/key is the node/key holding the reservation
- #
- if sg_persist -d $dev -i -r 2>/dev/null | grep -qiE "$key" ; then
- if echo "$reg_keys" | grep -qivE "${key#0}" ; then
- error=1
- else
- for error in 1
- do
- sg_persist -d $dev -o -G -K $key -S 0 &>/dev/null || break
- error=0
- done
- fi
- else
- for error in 1
- do
- sg_persist -d $dev -o -G -K $key -S 0 &>/dev/null || break
- error=0
- done
- fi
+ echo

- if [ $error -eq 0 ]; then
- success "unregister device $dev"
- else
- failure
- rval=1
- fi
+ ;; # end of start

- echo
-done
+ stop)

-rm -f /var/lock/subsys/scsi_reserve
+ error=0
+ count=0

-;;
+ echo -n "Stopping scsi_reserve:"

-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

-exit $rval
+esac

+exit $error
 

Thread Tools




All times are GMT. The time now is 05:55 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org