From mboxrd@z Thu Jan 1 00:00:00 1970 From: rohara@sourceware.org Date: 29 Nov 2006 20:14:44 -0000 Subject: [Cluster-devel] cluster/fence/agents/scsi fence_scsi.pl Message-ID: <20061129201444.24386.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL4 Changes by: rohara at sourceware.org 2006-11-29 20:14:43 Added files: fence/agents/scsi: fence_scsi.pl Log message: Fence agent for SCSI persistent reservations. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/fence/agents/scsi/fence_scsi.pl.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.5.6.1 /cvs/cluster/cluster/fence/agents/scsi/fence_scsi.pl,v --> standard output revision 1.5.6.1 --- cluster/fence/agents/scsi/fence_scsi.pl +++ - 2006-11-29 20:14:44.724242000 +0000 @@ -0,0 +1,280 @@ +#!/usr/bin/perl + +use Getopt::Std; +use IPC::Open3; +use POSIX; + +my @volumes; + +$_ = $0; +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=""; +$BUILD_DATE=""; +#END_VERSION_GENERATION + +sub usage +{ + print "Usage\n"; + print "\n"; + print "$pname [options]\n"; + print "\n"; + print "Options\n"; + print " -n IP address or hostname of node to fence\n"; + print " -h usage\n"; + print " -V version\n"; + print " -v verbose\n"; + + exit 0; +} + +sub version +{ + print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; + print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); + + exit 0; +} + +sub fail +{ + ($msg)=@_; + + print $msg."\n" unless defined $opt_q; + + exit 1; +} + +sub fail_usage +{ + ($msg)=@_; + + print STDERR $msg."\n" if $msg; + print STDERR "Please use '-h' for usage.\n"; + + exit 1; +} + +sub get_key +{ + ($node)=@_; + + my $addr = gethostbyname($node) or die "$!\n"; + + return unpack("H*", $addr); +} + +sub get_node_name +{ + return $opt_n; +} + +sub get_host_name +{ + my $host_name; + + my ($in, $out, $err); + my $cmd = "cman_tool status"; + + my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; + + waitpid($pid, 0); + + die "Unable to execute cman_tool.\n" if ($?>>8); + + while (<$out>) + { + chomp; + print "OUT: $_\n" if $opt_v; + + my ($name, $value) = split(/\s*:\s*/, $_, 2); + + if ($name eq "Node name") + { + $host_name = $value; + last; + } + } + + close($in); + close($out); + close($err); + + return $host_name; +} + +sub get_option_stdin +{ + my $opt; + mt $line = 0; + + while (defined($in = <>)) + { + $_ = $in; + chomp; + + # strip leading and trailing whitespace + s/^\s*//; + s/\s*$//; + + # skip comments + next if /^#/; + + $line += 1; + $opt = $_; + + next unless $opt; + + ($name, $val) = split /\s*=\s*/, $opt; + + if ($name eq "") + { + print STDERR "parse error: illegal name in option $line\n"; + exit 2; + } + elsif ($name eq "agent") + { + } + elsif ($name eq "node") + { + $opt_n = $val; + } + elsif ($name eq "self") + { + $opt_s = $val; + } + elsif ($name eq "verbose") + { + $opt_v = $val; + } + else + { + fail "parse error: unknown option \"$opt\""; + } + } +} + +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 "$!\n"; + + waitpid($pid, 0); + + die "Unable to execute lvs.\n" if ($?>>8); + + while (<$out>) + { + chomp; + print "OUT: $_\n" if $opt_v; + + my ($vg_attrs, $device) = split /:/, $_, 2; + + if ($vg_attrs =~ /.*c$/) + { + $device =~ s/\(.*\)://; + push @volumes, $device; + } + } + + close($in); + close($out); + close($err); +} + +sub check_sg_persist +{ + my ($in, $out, $err); + my $cmd = "sg_persist -V"; + my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; + + waitpid($pid, 0); + + die "Unable to execute sg_persist.\n" if ($?>>8); + + while (<$out>) + { + chomp; + print "OUT: $_\n" if $opt_v; + } + + close($in); + close($out); + close($err); +} + +sub fence_node +{ + my $host_name = get_host_name(); + my $node_name = get_node_name(); + + my $host_key = get_key($host_name); + my $node_key = get_key($node_name); + + my $cmd; + my ($in, $out, $err); + + foreach $dev (@volumes) + { + if ($host_key eq $node_key) + { + $cmd = "sg_persist -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"; + } + + my $pid = open3($in, $out, $err, $cmd) or die "$!\n"; + + waitpid($pid, 0); + + die "Unable to execute sg_persist.\n" if ($?>>8); + + while (<$out>) + { + chomp; + print "OUT: $_\n" if $opt_v; + } + + close($in); + close($out); + close($err); + } +} + +### MAIN ####################################################### + +if (@ARGV > 0) { + + getopts("n:s:hqvV") || fail_usage; + + usage if defined $opt_h; + version if defined $opt_V; + + fail_usage "Unkown parameter." if (@ARGV > 0); + fail_usage "No '-n' flag specified." unless defined $opt_n; + fail_usage "No '-s' flag specified." unless defined $opt_s; + +} else { + + get_options_stdin(); + + fail "failed: missing 'node'" unless defined $opt_n; + fail "failed: missing 'self'" unless defined $opt_s; + +} + +check_sg_persist; + +get_scsi_devices; + +fence_node; +