Gitweb:
http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=com...
Commit: 40e5f51eec5e12e6bf25beeacdcef82aa567a4b5
Parent: 1215fd3ecec974c32df312dacb254ec29088825e
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Mon Dec 7 16:43:40 2009 -0600
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Apr 20 14:42:11 2010 +0200
New fence_scsi with config options.
---
fence/agents/scsi/fence_scsi.pl | 379 ++++++++++++++++++++++-----------------
1 files changed, 215 insertions(+), 164 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index e58a5b1..59259cf 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -2,7 +2,7 @@
use File::Basename;
use Getopt::Std;
-use IPC::Open3;
+use POSIX;
#BEGIN_VERSION_GENERATION
$RELEASE_VERSION="";
@@ -16,67 +16,82 @@ my $ME = fileparse ($0, ".pl");
sub log_debug ($)
{
+ my $time = strftime "%b %e %T", localtime;
my ($msg) = @_;
- print STDOUT "[debug]: $msg\n" unless defined ($opt_q);
+ print STDOUT "$time $ME: [debug] $msg\n" unless defined ($opt_q);
+
+ return;
}
sub log_error ($)
{
+ my $time = strftime "%b %e %T", localtime;
my ($msg) = @_;
- print STDERR "[error]: $msg\n" unless defined ($opt_q);
+ print STDERR "$time $ME: [error] $msg\n" unless defined ($opt_q);
+
+ exit (1);
}
sub do_action_on ($@)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($node_key, @devices) = @_;
key_write ($node_key);
foreach $dev (@devices) {
+ log_error ("device $dev does not exist") if (! -e $dev);
+ log_error ("device $dev is not a block device") if (! -b $dev);
+
do_register_ignore ($node_key, $dev);
if (!get_reservation_key ($dev)) {
do_reserve ($node_key, $dev);
}
}
+
+ return;
}
sub do_action_off ($@)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($node_key, @devices) = @_;
my $host_key = key_read ();
if ($host_key eq $node_key) {
log_error ($self);
- exit (1);
}
foreach $dev (@devices) {
+ log_error ("device $dev does not exist") if (! -e $dev);
+ log_error ("device $dev is not a block device") if (! -b $dev);
+
my @keys = grep { /$node_key/ } get_registration_keys ($dev);
if (scalar (@keys) != 0) {
do_preempt_abort ($host_key, $node_key, $dev);
}
}
+
+ return;
}
sub do_action_status ($@)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($node_key, @devices) = @_;
my $dev_count = 0;
my $key_count = 0;
foreach $dev (@devices) {
+ log_error ("device $dev does not exist") if (! -e $dev);
+ log_error ("device $dev is not a block device") if (! -b $dev);
+
my @keys = grep { /$node_key/ } get_registration_keys ($dev);
if (scalar (@keys) != 0) {
@@ -94,140 +109,125 @@ sub do_action_status ($@)
sub do_register ($$$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($host_key, $node_key, $dev) = @_;
if (substr ($dev, 5) =~ /^dm/) {
my @slaves = get_mpath_slaves ($dev);
-
foreach (@slaves) {
do_register ($node_key, $_);
}
return;
}
- my $cmd = "sg_persist -n -o -G -K $host_key -S $node_key -d $dev";
- $cmd .= " -Z" if (defined $opt_a);
+ log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
+
+ my $cmd;
+ my $out;
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ $cmd = "sg_persist -n -o -G -K $host_key -S $node_key -d $dev";
+ $cmd .= " -Z" if (defined $opt_a);
+ $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub do_register_ignore ($$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($node_key, $dev) = @_;
if (substr ($dev, 5) =~ /^dm/) {
my @slaves = get_mpath_slaves ($dev);
-
foreach (@slaves) {
do_register_ignore ($node_key, $_);
}
return;
}
- my $cmd = "sg_persist -n -o -I -S $node_key -d $dev";
- $cmd .= " -Z" if (defined $opt_a);
+ log_debug ("$self (node_key=$node_key, dev=$dev)");
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ my $cmd;
+ my $out;
- waitpid ($pid, 0);
+ $cmd = "sg_persist -n -o -I -S $node_key -d $dev";
+ $cmd .= " -Z" if (defined $opt_a);
+ $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub do_reserve ($$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($host_key, $dev) = @_;
- my $cmd = "sg_persist -n -o -R -T 5 -K $host_key -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ log_debug ("$self (host_key=$host_key, dev=$dev)");
- waitpid ($pid, 0);
+ my $cmd = "sg_persist -n -o -R -T 5 -K $host_key -d $dev";
+ my $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub do_release ($$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($host_key, $dev) = @_;
- my $cmd = "sg_persist -n -o -L -T 5 -K $host_key -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ log_debug ("$self (host_key=$host_key, dev=$dev)");
- waitpid ($pid, 0);
+ my $cmd = "sg_persist -n -o -L -T 5 -K $host_key -d $dev";
+ my $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub do_preempt ($$$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($host_key, $node_key, $dev) = @_;
- my $cmd = "sg_persist -n -o -P -T 5 -K $host_key -S $node_key -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
- waitpid ($pid, 0);
+ my $cmd = "sg_persist -n -o -P -T 5 -K $host_key -S $node_key -d $dev";
+ my $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub do_preempt_abort ($$$)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($host_key, $node_key, $dev) = @_;
- my $cmd = "sg_persist -n -o -A -T 5 -K $host_key -S $node_key -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
- waitpid ($pid, 0);
+ my $cmd = "sg_persist -n -o -A -T 5 -K $host_key -S $node_key -d $dev";
+ my $out = qx { $cmd };
- die "[error]: $self ($dev)\n" if ($?>>8);
+ die "[error]: $self\n" if ($?>>8);
- close (IN);
- close (OUT);
- close (ERR);
+ return;
}
sub key_read ()
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
+ my $key;
open (\*FILE, "</var/lib/cluster/fence_scsi.key") or die
"$!\n";
-
- chomp (my $key = <FILE>);
-
+ chomp ($key = <FILE>);
close (FILE);
return ($key);
@@ -235,18 +235,18 @@ sub key_read ()
sub key_write ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
open (\*FILE, ">/var/lib/cluster/fence_scsi.key") or die
"$!\n";
-
print FILE "$_[0]\n";
-
close (FILE);
+
+ return;
}
sub get_key ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
my $key = sprintf ("%.4x%.4x", get_cluster_id (), get_node_id ($_[0]));
@@ -255,98 +255,76 @@ sub get_key ($)
sub get_node_id ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
+ my $node_id;
my $cmd = "cman_tool nodes -n $_[0] -F id";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
-
- waitpid ($pid, 0);
+ my $out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- chomp (my $node_id = <OUT>);
+ chomp ($out);
- close (IN);
- close (OUT);
- close (ERR);
+ $node_id = $out;
return ($node_id);
}
sub get_cluster_id ()
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
+ my $cluster_id;
my $cmd = "cman_tool status";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
-
- waitpid ($pid, 0);
+ my @out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- my $cluster_id;
-
- while (<OUT>) {
+ foreach (@out) {
chomp;
-
my ($param, $value) = split (/\s*:\s*/, $_);
-
if ($param =~ /^cluster\s+id/i) {
$cluster_id = $value;
}
}
- close (IN);
- close (OUT);
- close (ERR);
-
return ($cluster_id);
}
sub get_devices_clvm ()
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
+ my @devices;
my $cmd = "vgs --noheadings " .
- " --separator : " .
- " --sort pv_uuid " .
- " --options vg_attr,pv_name " .
- " --config 'global { locking_type = 0 } " .
- " devices { preferred_names = [ \"^/dev/dm\" ]
}'";
-
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+ " --separator : " .
+ " --sort pv_uuid " .
+ " --options vg_attr,pv_name " .
+ " --config 'global { locking_type = 0 } " .
+ " devices { preferred_names = [ \"^/dev/dm\" ]
}'";
- waitpid ($pid, 0);
+ my @out = qx { $cmd 2> /dev/null };
die "[error]: $self\n" if ($?>>8);
- my @devices;
-
- while (<OUT>) {
+ foreach (@out) {
chomp;
-
my ($vg_attr, $pv_name) = split (/:/, $_);
-
if ($vg_attr =~ /c$/) {
push (@devices, $pv_name);
}
}
- close (IN);
- close (OUT);
- close (ERR);
-
return (@devices);
}
sub get_devices_scsi ()
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
+ my $self = (caller(0))[3];
+ my @devices;
opendir (\*DIR, "/sys/block/") or die "$!\n";
-
- my @devices = grep { /^sd/ } readdir (DIR);
-
+ @devices = grep { /^sd/ } readdir (DIR);
closedir (DIR);
return (@devices);
@@ -354,18 +332,16 @@ sub get_devices_scsi ()
sub get_mpath_name ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($dev) = @_;
+ my $name;
if ($dev =~ /^\/dev\//) {
$dev = substr ($dev, 5);
}
open (\*FILE, "/sys/block/$dev/dm/name") or die "$!\n";
-
- chomp (my $name = <FILE>);
-
+ chomp ($name = <FILE>);
close (FILE);
return ($name);
@@ -373,18 +349,16 @@ sub get_mpath_name ($)
sub get_mpath_uuid ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($dev) = @_;
+ my $uuid;
if ($dev =~ /^\/dev\//) {
$dev = substr ($dev, 5);
}
open (\*FILE, "/sys/block/$dev/dm/uuid") or die "$!\n";
-
- chomp (my $uuid = <FILE>);
-
+ chomp ($uuid = <FILE>);
close (FILE);
return ($name);
@@ -392,9 +366,9 @@ sub get_mpath_uuid ($)
sub get_mpath_slaves ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($dev) = @_;
+ my @slaves;
if ($dev =~ /^\/dev\//) {
$dev = substr ($dev, 5);
@@ -402,12 +376,10 @@ sub get_mpath_slaves ($)
opendir (\*DIR, "/sys/block/$dev/slaves/") or die "$!\n";
- my @slaves = grep { !/^\./ } readdir (DIR);
-
+ @slaves = grep { !/^\./ } readdir (DIR);
if ($slaves[0] =~ /^dm/) {
@slaves = get_mpath_slaves ($slaves[0]);
- }
- else {
+ } else {
@slaves = map { "/dev/$_" } @slaves;
}
@@ -418,73 +390,53 @@ sub get_mpath_slaves ($)
sub get_registration_keys ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($dev) = @_;
+ my @keys;
my $cmd = "sg_persist -n -i -k -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
-
- waitpid ($pid, 0);
+ my @out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- my @keys;
-
- while (<OUT>) {
- chomp;
-
+ foreach (@out) {
+ chomp;
if ($_ =~ s/^\s+0x//i) {
push (@keys, $_);
}
}
- close (IN);
- close (OUT);
- close (ERR);
-
return (@keys);
}
sub get_reservation_key ($)
{
- (my $self = (caller(0))[3]) =~ s/^main:://;
-
+ my $self = (caller(0))[3];
my ($dev) = @_;
+ my $key;
my $cmd = "sg_persist -n -i -r -d $dev";
- my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
-
- waitpid ($pid, 0);
+ my @out = qx { $cmd };
die "[error]: $self\n" if ($?>>8);
- my $key;
-
- while (<OUT>) {
- chomp;
-
+ foreach (@out) {
+ chomp;
if ($_ =~ s/^\s+key=0x//i) {
$key = $_;
last;
}
}
- close (IN);
- close (OUT);
- close (ERR);
-
- return ($key);
+ return ($key)
}
sub get_options_stdin ()
{
my $num = 0;
- while (<STDIN>)
- {
+ while (<STDIN>) {
chomp;
-
s/^\s*//;
s/\s*$//;
@@ -548,29 +500,102 @@ sub print_version ()
exit (0);
}
+sub print_metadata ()
+{
+ print "<?xml version=\"1.0\" ?>\n";
+ print "<resource-agent name=\"fence_scsi\"" .
+ " shortdesc=\"fence agent for SCSI-3 persistent
reservations\">\n";
+ print "<longdesc>fence_scsi</longdesc>\n";
+ print "<parameters>\n";
+ print "\t<parameter name=\"aptpl\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-a\"/>\n";
+ print "\t\t<content type=\"boolean\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "Use APTPL flag for registrations" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "\t<parameter name=\"devices\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-d\"/>\n";
+ print "\t\t<content type=\"string\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "List of devices to be used for fencing action" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "\t<parameter name=\"logfile\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-f\"/>\n";
+ print "\t\t<content type=\"string\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "File to write error/debug messages" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "\t<parameter name=\"key\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-k\"/>\n";
+ print "\t\t<content type=\"string\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "Key value to be used for fencing action" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "\t<parameter name=\"action\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-o\"/>\n";
+ print "\t\t<content type=\"string\"
default=\"off\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "Fencing action" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "\t<parameter name=\"nodename\" unique=\"1\"
required=\"0\">\n";
+ print "\t\t<getopt mixed=\"-n\"/>\n";
+ print "\t\t<content type=\"string\"/>\n";
+ print "\t\t<shortdesc lang=\"en\">" .
+ "Name of node" .
+ "</shortdesc>\n";
+ print "\t</parameter>\n";
+ print "</parameters>\n";
+ print "<actions>\n";
+ print "\t<action name=\"on\"/>\n";
+ print "\t<action name=\"off\"/>\n";
+ print "\t<action name=\"status\"/>\n";
+ print "\t<action name=\"metadata\"/>\n";
+ print "</actions>\n";
+ print "</resource-agent>\n";
+
+ exit (0);
+}
+
################################################################################
if (@ARGV > 0) {
- getopts ("ad:f:hk:n:o:qV") or die "$!\n";
+ getopts ("ad:f:hk:n:o:qV") or print_usage;
print_usage if (defined $opt_h);
print_version if (defined $opt_V);
+
+ ## handle the metadata action here to avoid other parameter checks
+ ##
+ if ($opt_o =~ /^metadata$/i) {
+ print_metadata;
+ }
}
else {
get_options_stdin ();
}
+## if the logfile (-f) parameter was specified, open the logfile
+## and redirect STDOUT and STDERR to the logfile.
+##
if (defined $opt_f) {
open (LOG, ">$opt_f") or die "$!\n";
open (STDOUT, ">&LOG");
open (STDERR, ">&LOG");
}
+## verify that either key or nodename have been specified
+##
if ((!defined $opt_n) && (!defined $opt_k)) {
- log_error ("No '-n' or '-k' flag specified.");
- exit (1);
+ print_usage ();
}
+## determine key value
+##
if (defined $opt_k) {
$key = $opt_k;
}
@@ -578,6 +603,20 @@ else {
$key = get_key ($opt_n);
}
+## verify that key is not zero
+##
+if ($key == 0) {
+ log_error ("key cannot be zero");
+}
+
+## remove any leading zeros from key
+##
+if ($key =~ /^0/) {
+ $key =~ s/^0+//;
+}
+
+## get devices
+##
if (defined $opt_d) {
@devices = split (/\s*,\s*/, $opt_d);
}
@@ -585,10 +624,20 @@ else {
@devices = get_devices_clvm ();
}
+## verify that device list is not empty
+##
+if (scalar (@devices) == 0) {
+ log_error ("no devices found");
+}
+
+## default action is "off"
+##
if (!defined $opt_o) {
$opt_o = "off";
}
+## determine the action to perform
+##
if ($opt_o =~ /^on$/i) {
do_action_on ($key, @devices);
}
@@ -603,6 +652,8 @@ else {
exit (1);
}
+## close the logfile
+##
if (defined $opt_f) {
close (LOG);
}