fence-agents: master - Add support for unfence operation.
Ryan O'Hara
rohara@fedoraproject.org
Thu Mar 5 19:07:00 GMT 2009
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commitdiff;h=8d3128c05779304263e9e4e885610c49d2f61bc8
Commit: 8d3128c05779304263e9e4e885610c49d2f61bc8
Parent: aa905c0bf7a717648b44069e4a192f7afe0cda61
Author: Ryan O'Hara <rohara@redhat.com>
AuthorDate: Thu Mar 5 13:05:43 2009 -0600
Committer: Ryan O'Hara <rohara@redhat.com>
CommitterDate: Thu Mar 5 13:05:43 2009 -0600
Add support for unfence operation.
---
fence/agents/scsi/fence_scsi.pl | 390 +++++++++++++++------------------------
1 files changed, 148 insertions(+), 242 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index 7e68dab..d95198b 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -13,11 +13,10 @@ END {
$? ||= 1;
}
-my @device_list;
-
$_ = $0;
s/.*\///;
my $pname = $_;
+my @device_list;
#BEGIN_VERSION_GENERATION
$RELEASE_VERSION="";
@@ -31,11 +30,12 @@ sub usage
print "\n";
print "$pname [options]\n";
print "\n";
- print "Options\n";
- print " -n <node> IP address or hostname of node to fence\n";
- print " -h usage\n";
- print " -V version\n";
- print " -v verbose\n";
+ print "Options:\n";
+ print " -n <node> ip address or hostname of node to fence\n";
+ print " -h usage\n";
+ print " -u unfence\n";
+ print " -v verbose\n";
+ print " -V version\n";
exit 0;
}
@@ -43,74 +43,70 @@ sub usage
sub version
{
print "$pname $RELEASE_VERSION $BUILD_DATE\n";
- print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
- exit 0;
+ print "$REDHAT_COPYRIGHT\n" if ($REDHAT_COPYRIGHT);
}
-sub fail
+sub fail_usage
{
- ($msg)=@_;
+ ($msg) = @_;
- print $msg."\n" unless defined $opt_q;
+ print STDERR $msg."\n" if $msg;
+ print STDERR "Please use '-h' for usage.\n";
exit 1;
}
-sub fail_usage
+sub check_sg_persist
{
- ($msg)=@_;
+ my ($in, $out, $err);
+ my $cmd = "sg_persist -V";
+ my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
- print STDERR $msg."\n" if $msg;
- print STDERR "Please use '-h' for usage.\n";
+ waitpid($pid, 0);
- exit 1;
+ die "unable to execute sg_persist.\n" if ($?>>8);
+
+ close ($in);
+ close ($out);
+ close ($err);
}
sub get_cluster_id
{
- my $cluster_id;
-
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);
+ die "unable to execute cman_tool.\n" if ($?>>8);
- while (<$out>)
- {
+ my $cluster_id;
+
+ while (<$out>) {
chomp;
my ($name, $value) = split(/\s*:\s*/, $_);
- if ($name eq "Cluster Id")
- {
+ if ($name eq "Cluster Id") {
$cluster_id = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
- print "[$pname]: get_cluster_id: cluster_id=$cluster_id\n" if $opt_v;
+ close ($in);
+ close ($out);
+ close ($err);
return $cluster_id;
}
sub get_node_id
{
- ($node)=@_;
-
- my $node_id;
+ ($node) = @_;
my ($in, $out, $err);
my $cmd = "ccs_tool query /cluster/clusternodes/clusternode[\@name=\\\"$node\\\"]/\@nodeid";
-
my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
waitpid($pid, 0);
@@ -122,106 +118,60 @@ sub get_node_id
$node_id = $_;
}
- close($in);
- close($out);
- close($err);
-
- print "[$pname]: get_node_id ($node): node_id=$node_id\n" if $opt_v;
+ close ($in);
+ close ($out);
+ close ($err);
return $node_id;
}
-sub get_node_name
-{
- print "[$pname]: get_hode_name: node_name=$opt_n\n" if $opt_v;
-
- return $opt_n;
-}
-
-sub get_host_id
+sub get_host_name
{
- my $host_id;
-
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;
-
- my ($name, $value) = split(/\s*:\s*/, $_);
-
- if ($name eq "Node ID")
- {
- $host_id = $value;
- last;
- }
- }
-
- close($in);
- close($out);
- close($err);
-
- print "[$pname]: get_host_id: host_id=$host_id\n" if $opt_v;
+ die "unable to execute cman_tool.\n" if ($?>>8);
- return $host_id;
-}
-
-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>)
- {
+ while (<$out>) {
chomp;
my ($name, $value) = split(/\s*:\s*/, $_);
- if ($name eq "Node name")
- {
+ if ($name eq "Node name") {
$host_name = $value;
last;
}
}
- close($in);
- close($out);
- close($err);
-
- print "[$pname]: get_host_name: host_name=$host_name\n" if $opt_v;
+ close ($in);
+ close ($out);
+ close ($err);
return $host_name;
}
+sub get_node_name
+{
+ return $opt_n;
+}
+
sub get_key
{
- ($node)=@_;
+ ($node) = @_;
my $cluster_id = get_cluster_id;
my $node_id = get_node_id($node);
if ($node_id == 0) {
- die "Unable to determine nodeid for $node.\n";
+ die "unable to determine nodeid for node '$node'\n";
}
- my $key = sprintf "%x%.4x", $cluster_id, $node_id;
-
- print "[$pname]: get_key ($node): key=$key\n" if $opt_v;
+ my $key = sprintf "%.4x%.4x", $cluster_id, $node_id;
return $key;
}
@@ -231,16 +181,18 @@ sub get_options_stdin
my $opt;
my $line = 0;
- while (defined($in = <>))
- {
+ while (defined($in = <>)) {
+
$_ = $in;
chomp;
- # strip leading and trailing whitespace
+ ## strip leading and trailing whitespace
+ ##
s/^\s*//;
s/\s*$//;
- # skip comments
+ ## skip comments
+ ##
next if /^#/;
$line += 1;
@@ -248,7 +200,7 @@ sub get_options_stdin
next unless $opt;
- ($name, $val) = split(/\s*=\s*/, $opt);
+ ($name, $value) = split(/\s*=\s*/, $opt);
if ($name eq "")
{
@@ -257,74 +209,27 @@ sub get_options_stdin
}
elsif ($name eq "agent")
{
+ ## ignore this
}
elsif ($name eq "node")
{
- $opt_n = $val;
+ $opt_n = $value;
}
elsif ($name eq "nodename")
{
- $opt_n = $val;
+ $opt_n = $value;
}
- elsif ($name eq "verbose")
+ elsif ($name eq "action")
{
- $opt_v = $val;
- }
- else
- {
- fail "parse error: unknown option \"$opt\"";
- }
- }
-}
-
-sub get_key_list
-{
- ($dev) = @_;
-
- my ($in, $out, $err);
-
- my $cmd = "sg_persist -d $dev -i -k";
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
- waitpid($pid, 0);
-
- die "Unable to execute sg_persist.\n" if ($?>>8);
-
- my %key_list;
-
- while (<$out>)
- {
- chomp;
- if ($_ =~ /^\s*0x/)
- {
- s/^\s+0x//;
- s/\s+$//;
-
- $key_list{$_} = 1;
- }
- }
-
- # DEBUG: use -v option
- #
- if ($opt_v)
- {
- my $count = keys %key_list;
- my $index = 0;
-
- print "[$pname]: get_key_list: found $count keys registered with $dev\n";
-
- for $key (keys %key_list)
- {
- print "[$pname]: ($index) key=$key\n";
- $index++;
+ ## if "action=on", the we are performing an unfence operation.
+ ## any other value for "action" is ignored. the default is a
+ ## fence operation.
+ ##
+ if ($value eq "on") {
+ $opt_u = $value;
+ }
}
}
-
- close($in);
- close($out);
- close($err);
-
- return %key_list;
}
sub get_scsi_devices
@@ -338,153 +243,154 @@ sub get_scsi_devices
waitpid($pid, 0);
- die "Unable to execute vgs.\n" if ($?>>8);
+ die "unable to execute vgs.\n" if ($?>>8);
- while (<$out>)
- {
+ while (<$out>) {
chomp;
- my ($vg_attrs, $dev) = split(/:/, $_);
+ my ($attrs, $dev) = split(/:/, $_);
- if ($vg_attrs =~ /.*c$/)
- {
+ if ($attrs =~ /.*c$/) {
$dev =~ s/\(.*\)//;
push(@device_list, $dev);
}
}
- # DEBUG: use -v flag
- #
- if ($opt_v)
- {
- my $count = scalar @device_list;
- my $index = 0;
-
- print "[$pname]: get_scsi_devices: found $count devices\n";
-
- for $dev (@device_list)
- {
- print "[$pname]: ($index) dev=$dev\n";
- $index++;
- }
- }
-
- close($in);
- close($out);
- close($err);
+ close ($in);
+ close ($out);
+ close ($err);
}
-sub check_sg_persist
+sub create_registration
{
+ my ($key, $dev) = @_;
+
my ($in, $out, $err);
- my $cmd = "sg_persist -V";
+ my $cmd = "sg_persist -n -d $dev -o -I -S $key";
my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
waitpid($pid, 0);
- die "Unable to execute sg_persist.\n" if ($?>>8);
+ die "unable to create registration.\n" if ($?>>8);
- close($in);
- close($out);
- close($err);
+ close ($in);
+ close ($out);
+ close ($err);
}
-sub do_register
+sub create_reservation
{
- ($dev, $key) = @_;
+ my ($key, $dev) = @_;
my ($in, $out, $err);
- my $cmd = "sg_persist -n -d $dev -o -G -S $key";
+ my $cmd = "sg_persist -n -d $dev -o -R -K $key -T 5";
my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
waitpid($pid, 0);
- die "Unable to execute sg_persist ($dev).\n" if ($?>>8);
+ die "unable to create reservation.\n" if ($?>>8);
- close($in);
- close($out);
- close($err);
+ close ($in);
+ close ($out);
+ close ($err);
}
sub fence_node
{
- my $host_name = get_host_name();
- my $node_name = get_node_name();
-
+ my $host_name = get_host_name;
my $host_key = get_key($host_name);
+
+ my $node_name = get_node_name;
my $node_key = get_key($node_name);
my ($in, $out, $err);
foreach $dev (@device_list)
{
- my %key_list = get_key_list($dev);
+ ## check that the key we are attempting to remove
+ ## is actually registered with the device. if the key is not
+ ## registered, there is nothing to do for this device.
+ ##
+ system ("sg_persist -n -d $dev -i -k | grep -qiE \"^[[:space:]]*0x$key\"");
- # DEBUG: use -v option
- #
- if ($opt_v)
- {
- print "[$pname]: unregister key 0x$node_key from device $dev\n";
- }
-
- if (!$key_list{$host_key})
- {
- do_register($dev, $host_key);
- }
-
- if (!$key_list{$node_key})
- {
- if ($opt_v)
- {
- print "[$pname]: key 0x$node_key is not registered with device $dev\n";
- }
+ if (($?>>8) != 0) {
next;
}
- if ($host_key eq $node_key)
- {
- $cmd = "sg_persist -n -d $dev -o -G -K $host_key -S 0";
+ if ($host_key eq $node_key) {
+ ## this sg_persist command is for the case where you attempt to
+ ## fence yourself (ie. the local node is the same at the node to
+ ## be fence). this will not work if the node is the reservation
+ ## holder, since you can't unregister while holding the reservation.
+ ##
+ my $cmd = "sg_persist -n -d $dev -o -G -K $host_key -S 0";
}
- else
- {
- $cmd = "sg_persist -n -d $dev -o -A -K $host_key -S $node_key -T 5";
+ else {
+ ## this sg_persist command will remove the registration for $host_key.
+ ## the local node will also become the reservation holder, regardless
+ ## of which node was holding the reservation prior to the fence operation.
+ ##
+ my $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 "$!\n";
waitpid($pid, 0);
- die "Unable to execute sg_persist ($dev).\n" if ($?>>8);
+ die "unable to execute sg_persist.\n" if ($?>>8);
- close($in);
- close($out);
- close($err);
+ close ($in);
+ close ($out);
+ close ($err);
}
}
-### MAIN #######################################################
+sub unfence_node
+{
+ my $host_name = get_host_name;
+ my $host_key = get_key($host_name);
+
+ foreach $dev (@device_list)
+ {
+ create_registration ($host_key, $dev);
+
+ ## check to see if a reservation already exists.
+ ## if no reservation exists, this node/key will become
+ ## the reservation holder.
+ ##
+ system ("sg_persist -n -d $dev -i -r | grep -qiE \"^[[:space:]]*Key=0x\"");
+
+ if (($?>>8) != 0) {
+ create_reservation ($host_key, $dev);
+ }
+ }
+}
if (@ARGV > 0) {
- getopts("n:hqvV") || fail_usage;
+ getopts("hn:uvV") || fail_usage;
usage if defined $opt_h;
version if defined $opt_V;
- fail_usage "Unknown parameter." if (@ARGV > 0);
-
- fail_usage "No '-n' flag specified." unless defined $opt_n;
+ if (!defined $opt_u) {
+ fail_usage "No '-n' flag specified." unless defined $opt_n;
+ }
} else {
get_options_stdin();
- fail "failed: missing 'node'" unless defined $opt_n;
-
}
-check_sg_persist;
-
+## get a list of scsi devices. this call will build a list of devices
+## (device_list) by querying clvm for a list of devices that exist in
+## volume groups that have the cluster bit set.
+##
get_scsi_devices;
-fence_node;
+if ($opt_u) {
+ unfence_node;
+} else {
+ fence_node;
+}
More information about the Cluster-cvs
mailing list