gfs2-utils: master - gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitd...
Commit: cc703e11a2fd3c8adf09d13742b5cfa76f3091d3
Parent: afabf7e6c8547e9651ee8a168e5dc65675c76d8e
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Mon Sep 27 13:34:43 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Mon Sep 27 13:39:11 2010 -0500
gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
This patch causes the inode conversion routine to skip over the jindex and
rindex inodes. Without this patch, the jindex and rindex inodes are converted
to gfs2 format and once converted, there's no way to go back to gfs1 for these
two inodes were the convert to be interrupted somehow. In the eyes of the
subsequent gfs2_convert run, these two inodes would be corrupt and gfs2_convert
would bail out of the conversion.
Skipping conversion of these two inodes doesn't affect gfs2_convert as these
two inodes are freed from disk towards the end of the conversion process. New
jindex and rindex inodes are created for gfs2 separately in the master
directory.
Note: This issue with reconversion failing occurs only when the jindex/rindex
inodes are unstuffed. When stuffed, gfs1 and gfs2 inodes have a similar
structure, so it doesn't matter if these inodes are converted or not, however
with inode height > 0 the structures of gfs1 and gfs2 differ.
Resolves: rhbz#637913
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 659cd4a..2cde2a8 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -150,6 +150,7 @@ uint64_t gfs2_heightsize[GFS2_MAX_META_HEIGHT];
uint64_t gfs2_jheightsize[GFS2_MAX_META_HEIGHT];
uint32_t gfs2_max_height;
uint32_t gfs2_max_jheight;
+uint64_t jindex_addr = 0, rindex_addr = 0;
/* ------------------------------------------------------------------------- */
/* This function is for libgfs's sake. */
@@ -1140,7 +1141,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
}
bh = bread(sbp, block);
if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) {/* if it is an dinode */
- error = adjust_inode(sbp, bh);
+ /* Skip the rindex and jindex inodes for now. */
+ if (block != rindex_addr && block != jindex_addr)
+ error = adjust_inode(sbp, bh);
} else { /* It's metadata, but not an inode, so fix the bitmap. */
int blk, buf_offset;
int bitmap_byte; /* byte within the bitmap to fix */
@@ -1611,6 +1614,10 @@ static int init(struct gfs2_sbd *sbp)
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
gfs2_sb_in(&sbp->sd_sb, bh);
+
+ jindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_jindex_di.no_addr);
+ rindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_rindex_di.no_addr);
+
sbp->bsize = sbp->sd_sb.sb_bsize;
sbp->sd_inptrs = (sbp->bsize - sizeof(struct gfs_indirect)) /
sizeof(uint64_t);
13 years, 7 months
cluster: STABLE3 - gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cd0d5b10e6ad4f04c0fd0adb440d9ccf0380426f
Parent: 5492f5160f1cef50ac5fc38cf184974e587bbfb3
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Mon Sep 27 13:34:43 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Mon Sep 27 13:34:43 2010 -0500
gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
This patch causes the inode conversion routine to skip over the jindex and
rindex inodes. Without this patch, the jindex and rindex inodes are converted
to gfs2 format and once converted, there's no way to go back to gfs1 for these
two inodes were the convert to be interrupted somehow. In the eyes of the
subsequent gfs2_convert run, these two inodes would be corrupt and gfs2_convert
would bail out of the conversion.
Skipping conversion of these two inodes doesn't affect gfs2_convert as these
two inodes are freed from disk towards the end of the conversion process. New
jindex and rindex inodes are created for gfs2 separately in the master
directory.
Note: This issue with reconversion failing occurs only when the jindex/rindex
inodes are unstuffed. When stuffed, gfs1 and gfs2 inodes have a similar
structure, so it doesn't matter if these inodes are converted or not, however
with inode height > 0 the structures of gfs1 and gfs2 differ.
Resolves: rhbz#637913
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 6a754b1..f84de84 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -148,6 +148,7 @@ uint64_t gfs2_heightsize[GFS2_MAX_META_HEIGHT];
uint64_t gfs2_jheightsize[GFS2_MAX_META_HEIGHT];
uint32_t gfs2_max_height;
uint32_t gfs2_max_jheight;
+uint64_t jindex_addr = 0, rindex_addr = 0;
/* ------------------------------------------------------------------------- */
/* This function is for libgfs's sake. */
@@ -1138,7 +1139,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
}
bh = bread(sbp, block);
if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) {/* if it is an dinode */
- error = adjust_inode(sbp, bh);
+ /* Skip the rindex and jindex inodes for now. */
+ if (block != rindex_addr && block != jindex_addr)
+ error = adjust_inode(sbp, bh);
} else { /* It's metadata, but not an inode, so fix the bitmap. */
int blk, buf_offset;
int bitmap_byte; /* byte within the bitmap to fix */
@@ -1609,6 +1612,10 @@ static int init(struct gfs2_sbd *sbp)
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
gfs2_sb_in(&sbp->sd_sb, bh);
+
+ jindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_jindex_di.no_addr);
+ rindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_rindex_di.no_addr);
+
sbp->bsize = sbp->sd_sb.sb_bsize;
sbp->sd_inptrs = (sbp->bsize - sizeof(struct gfs_indirect)) /
sizeof(uint64_t);
13 years, 7 months
cluster: RHEL56 - gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
by Abhijith Das
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: de617fdd1aecc78fcadaaaf5866a28aa7f7dd3b4
Parent: 636d2bc385af29f3f773eb0cdc8fed8992f367fd
Author: Abhijith Das <adas(a)redhat.com>
AuthorDate: Mon Sep 27 13:07:18 2010 -0500
Committer: Abhijith Das <adas(a)redhat.com>
CommitterDate: Mon Sep 27 13:07:18 2010 -0500
gfs2_convert: gfs2_convert doesn't resume after interrupted conversion
This patch causes the inode conversion routine to skip over the jindex and
rindex inodes. Without this patch, the jindex and rindex inodes are converted
to gfs2 format and once converted, there's no way to go back to gfs1 for these
two inodes were the convert to be interrupted somehow. In the eyes of the
subsequent gfs2_convert run, these two inodes would be corrupt and gfs2_convert
would bail out of the conversion.
Skipping conversion of these two inodes doesn't affect gfs2_convert as these
two inodes are freed from disk towards the end of the conversion process. New
jindex and rindex inodes are created for gfs2 separately in the master
directory.
Note: This issue with reconversion failing occurs only when the jindex/rindex
inodes are unstuffed. When stuffed, gfs1 and gfs2 inodes have a similar
structure, so it doesn't matter if these inodes are converted or not, however
with inode height > 0 the structures of gfs1 and gfs2 differ.
Resolves: rhbz#636157
Signed-off-by: Abhi Das <adas(a)redhat.com>
---
gfs2/convert/gfs2_convert.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 899982d..e00fbe7 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -158,6 +158,8 @@ uint64_t gfs2_jheightsize[GFS2_MAX_META_HEIGHT];
int gfs2_max_height;
int gfs2_max_jheight;
+uint64_t jindex_addr = 0, rindex_addr = 0;
+
/* ------------------------------------------------------------------------- */
/* This function is for libgfs's sake. */
/* ------------------------------------------------------------------------- */
@@ -1149,7 +1151,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
}
bh = bread(sbp, block);
if (!gfs2_check_meta(bh, GFS_METATYPE_DI)) {/* if it is an dinode */
- error = adjust_inode(sbp, bh);
+ /* Skip the rindex and jindex inodes for now. */
+ if (block != rindex_addr && block != jindex_addr)
+ error = adjust_inode(sbp, bh);
} else { /* It's metadata, but not an inode, so fix the bitmap. */
int blk, buf_offset;
int bitmap_byte; /* byte within the bitmap to fix */
@@ -1617,6 +1621,10 @@ static int init(struct gfs2_sbd *sbp)
memcpy(&raw_gfs1_ondisk_sb, (struct gfs1_sb *)bh->b_data,
sizeof(struct gfs1_sb));
gfs2_sb_in(&sbp->sd_sb, bh);
+
+ jindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_jindex_di.no_addr);
+ rindex_addr = be64_to_cpu(raw_gfs1_ondisk_sb.sb_rindex_di.no_addr);
+
sbp->bsize = sbp->sd_sb.sb_bsize;
sbp->sd_inptrs = (sbp->bsize - sizeof(struct gfs_indirect)) /
sizeof(uint64_t);
13 years, 7 months
cluster: RHEL56 - fence_scsi_test: rewrite to more accurately test
by rohara
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 636d2bc385af29f3f773eb0cdc8fed8992f367fd
Parent: 5e8ef2ca3e43652e77b277fe72eb3832d2c2b656
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Mon Sep 27 10:50:12 2010 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Mon Sep 27 10:59:33 2010 -0500
fence_scsi_test: rewrite to more accurately test
The old fence_scsi_test tool was far too simple to adequately
test it a devices was capable of being used with fence_scsi.
This rewrite should adequately test all requirements, such as
support for "preempt-and-abort" subcommand. This script will
also verify that each command worked as expected.
Resolves: rhbz#603838
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
---
fence/agents/scsi/fence_scsi_test.pl | 748 ++++++++++++++++++++++++++--------
fence/man/fence_scsi_test.8 | 68 +++
2 files changed, 653 insertions(+), 163 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi_test.pl b/fence/agents/scsi/fence_scsi_test.pl
index e24ef61..25db6ba 100755
--- a/fence/agents/scsi/fence_scsi_test.pl
+++ b/fence/agents/scsi/fence_scsi_test.pl
@@ -1,272 +1,694 @@
#!/usr/bin/perl
-use POSIX;
-use IPC::Open3;
-use XML::LibXML;
-use Getopt::Std;
-
-my @devices;
-my %results;
-
#BEGIN_VERSION_GENERATION
$FENCE_RELEASE_NAME="";
$REDHAT_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
-sub get_scsi_block_devices
+################################################################################
+
+use File::Basename;
+use Term::ANSIColor;
+use Getopt::Long;
+use XML::LibXML;
+
+################################################################################
+
+my @devices = ();
+my %devices_name = ();
+my %devices_path = ();
+my %options = ();
+my %results = ();
+
+################################################################################
+
+sub do_action_on (\@$$)
{
- print "[debug] get_scsi_block_devices\n" if ($opt_d);
+ my @devices = @{(shift)};
+ my ($dev, $node_key) = @_;
+ my $err = 0;
- my $block_dir = "/sys/block";
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev node_key=$node_key)\n";
+ }
- opendir(DIR, $block_dir) or die "$!\n";
+ foreach (@devices) {
+ if (do_reset ($_) != 0) {
+ }
+ if (do_register_ignore ($_, $node_key) != 0) {
+ $err++;
+ }
+ }
- my @block_devices = grep { /^sd*/ } readdir(DIR);
+ if (scalar (get_keys_reserve ($dev)) == 0) {
+ if (do_reserve ($dev, $node_key) != 0) {
+ $err = 0;
+ }
+ }
- closedir(DIR);
+ return ($err);
+}
- for $block_dev (@block_devices)
- {
- print "[debug] \t device = $block_dev\n" if ($opt_d);
+sub do_action_off ($$$)
+{
+ my ($dev, $node_key, $host_key) = @_;
+ my $err = 0;
- push(@devices, "/dev/" . $block_dev);
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev node_key=$node_key host_key=$host_key)\n";
}
+
+ if (do_preempt_abort ($dev, $host_key, $node_key) != 0) {
+ $err++;
+ }
+
+ return ($err);
}
-sub get_cluster_vol_devices
+sub do_verify_on (\@$$)
{
- print "[debug] get_cluster_vol_devices\n" if ($opt_d);
+ my @devices = @{(shift)};
+ my ($dev, $node_key) = @_;
+ my $err = 0;
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev node_key=$node_key)\n";
+ }
+
+ @keys = grep { /^$node_key$/ } get_keys_register ($dev);
- my ($in, $out, $err);
+ if (scalar (@keys) != scalar (@devices)) {
+ $err++;
+ }
- my $cmd = "vgs --config 'global { locking_type = 0 }'" .
- " --noheadings --separator : -o vg_attr,pv_name";
+ @keys = get_keys_reserve ($dev);
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+ if (scalar (@keys) == 0) {
+ $err++;
+ }
- waitpid($pid, 0);
+ return ($err);
+}
- die "[error] unable to execute vgs command.\n" if WEXITSTATUS($?);
+sub do_verify_off ($$$)
+{
+ my ($dev, $node_key, $host_key) = @_;
+ my $err = 0;
- while (<$out>)
- {
- chomp;
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev node_key=$node_key host_key=$host_key)\n";
+ }
- my ($vg_attr, $pv_name) = split(/:/, $_);
+ @keys = grep { /^$node_key$/ } get_keys_register ($dev);
- if ($vg_attr =~ /.*c$/)
- {
- print "[debug] \t device = $pv_name\n" if ($opt_d);
+ if (scalar (@keys) != 0) {
+ $err++;
+ }
- push(@devices, $pv_name);
- }
+ @keys = grep { /^$host_key$/ } get_keys_reserve ($dev);
+
+ if (scalar (@keys) == 0) {
+ $err++;
}
- close($in);
- close($out);
- close($err);
+ return ($err);
}
-sub register_device
+sub do_key_write ($)
{
- my ($dev, $key) = @_;
- my ($in, $out, $err);
+ my $key = shift;
- print "[debug] register_device (device=$dev, key=$key)\n" if ($opt_d);
+ open (\*FILE, ">/tmp/.fence_scsi_test") or die "$!\n";
+ print (FILE "$key\n");
+ close (FILE);
- my $cmd = "sg_persist -n -d $dev -o -G -S $key";
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (key=$key)\n";
+ }
- print "[debug] \t cmd = $cmd\n" if ($opt_d);
+ return;
+}
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+sub do_key_read ($)
+{
+ my $key = shift;
- waitpid($pid, 0);
+ open (\*FILE, "</tmp/.fence_scsi_test") or die "$!\n";
+ chomp ($$key = <FILE>);
+ close (FILE);
- $results{$dev}[0] = WEXITSTATUS($?);
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (key=$$key)\n";
+ }
- close($in);
- close($out);
- close($err);
+ return;
}
-sub unregister_device
+sub do_register ($$)
{
- my ($dev, $key) = @_;
- my ($in, $out, $err);
+ my ($dev, $sark) = @_;
- print "[debug] unregister_device (device=$dev, key=$key)\n" if ($opt_d);
+ my $cmd = "sg_persist -n -o -G -S $sark -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
- my $cmd = "sg_persist -n -d $dev -o -G -K $key -S 0";
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev sark=$sark)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ }
- print "[debug] \t cmd = $cmd\n" if ($opt_d);
+ return ($err);
+}
- my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+sub do_register_ignore ($$)
+{
+ my ($dev, $sark) = @_;
- waitpid($pid, 0);
+ my $cmd = "sg_persist -n -o -I -S $sark -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
- $results{$dev}[1] = WEXITSTATUS($?);
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev sark=$sark)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ }
- close($in);
- close($out);
- close($err);
+ return ($err);
}
-sub test_devices
+sub do_reserve ($$)
{
- my $key = "0x1";
+ my ($dev, $rk) = @_;
+
+ my $cmd = "sg_persist -n -o -R -T 5 -K $rk -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
- foreach $dev (@devices)
- {
- register_device($dev, $key);
- unregister_device($dev, $key);
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev rk=$rk)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
}
+
+ return ($err);
}
-sub check_config_fence
+sub do_release ($$)
{
- my $xml = XML::LibXML->new();
- my $tree = $xml->parse_file("/etc/cluster/cluster.conf");
- my $root = "//cluster/fencedevices/fencedevice";
+ my ($dev, $rk) = @_;
- my $xpath_fence = "count(${root}[\@agent='fence_scsi'])";
+ my $cmd = "sg_persist -n -o -L -T 5 -K $rk -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev rk=$rk)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ }
- return ( ! $tree->findvalue($xpath_fence));
+ return ($err);
}
-sub check_config_nodes
+sub do_preempt ($$$)
{
- my $xml = XML::LibXML->new();
- my $tree = $xml->parse_file("/etc/cluster/cluster.conf");
- my $root = "//cluster/clusternodes/clusternode";
+ my ($dev, $rk, $sark) = @_;
- my $xpath_name = "count(${root}/\@name)";
- my $xpath_nodeid = "count(${root}/\@nodeid)";
+ my $cmd = "sg_persist -n -o -P -T 5 -K $rk -S $sark -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev rk=$rk sark=$sark)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ }
- return ($tree->findvalue($xpath_name) != $tree->findvalue($xpath_nodeid));
+ return ($err);
}
-sub print_results
+sub do_preempt_abort ($$$)
{
- my $device_count = scalar(@devices);
+ my ($dev, $rk, $sark) = @_;
- my $failure_count = 0;
- my $success_count = 0;
+ my $cmd = "sg_persist -n -o -A -T 5 -K $rk -S $sark -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
- print "\nAttempted to register with devices:\n";
- print "-------------------------------------\n";
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev rk=$rk sark=$sark)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ }
- for $dev (@devices)
- {
- print "\t$dev\t";
- if ($results{$dev}[0] == 0)
- {
- $success_count++;
- print "Success\n";
- }
- else
- {
- $failure_count++;
- print "Failure\n";
- }
+ return ($err);
+}
+
+sub do_clear ($$)
+{
+ my ($dev, $rk) = @_;
+
+ my $cmd = "sg_persist -n -o -C -K $rk -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev rk=$rk)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
}
- print "-------------------------------------\n";
- print "Number of devices tested: $device_count\n";
- print "Number of devices passed: $success_count\n";
- print "Number of devices failed: $failure_count\n\n";
+ return ($err);
+}
+
+sub do_reset ($)
+{
+ my ($dev) = @_;
+
+ my $cmd = "sg_turs $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
- if ($failure_count != 0)
- {
- exit(1);
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
}
+
+ return ($err);
}
-sub print_usage
+sub get_options ()
{
- print "\nUsage: fence_scsi_test [-c|-s] [-d] [-h]\n\n";
+ my @opts = ("d|device=s",
+ "h|help",
+ "k|key=s",
+ "o|action=s",
+ "t|test=s",
+ "v|verbose");
- print "Options:\n\n";
+ Getopt::Long::Configure ("no_auto_abbrev") or exit (1);
+ Getopt::Long::GetOptions (\%options, @opts) or exit (1);
- print " -c Cluster mode. This mode is intended to test\n";
- print " SCSI persistent reservation capabilties for\n";
- print " devices that are part of existing clustered\n";
- print " volumes. Only devices in LVM cluster volumes\n";
- print " will be tested.\n\n";
- print " -s SCSI mode. This mode is intended to test SCSI\n";
- print " persistent reservation capabilities for all SCSI\n";
- print " devices visible on a node.\n\n";
- print " -d Debug flag. This will print debugging information\n";
- print " such as the actual commands being run to register\n";
- print " and unregister a device.\n\n";
- print " -h Help. Prints out this usage information.\n\n";
+ return;
}
-sub test_tools_path
+sub get_devices ()
{
- my $tool_name = "sg_persist";
-
- for my $path ( split /:/, $ENV{PATH} ) {
- if ( -f "$path/$tool_name" && -x _ ) {
- return;
- }
+ my @devices = split (/,/, $options{'d'});
+
+ map { s/^\s+// } @devices;
+ map { s/\s+$// } @devices;
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self\n";
+ }
+
+ return (@devices);
+}
+
+sub get_devices_clvm ()
+{
+ my @devices = ();
+
+ my $cmd = "vgs" .
+ " --noheadings" .
+ " --sort pv_uuid" .
+ " --options pv_name,vg_attr" .
+ " --config 'global { locking_type=0 }'";
+
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ @devices = map { (split)[0] } grep { /c$/ } @out;
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self\n";
+ }
+
+ return (@devices);
+}
+
+sub get_devices_scsi ()
+{
+ my @devices = ();
+
+ open (\*DIR, "/sys/block/") or die "$!\n";
+ @devices = grep { /^sd/ } readdir (DIR);
+ close (DIR);
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self\n";
+ }
+
+ return (@devices);
+}
+
+sub get_devices_name ($)
+{
+ my $dev = shift;
+ my $name = basename ($dev);
+
+ if (-l "/dev/mpath/$name") {
+ $name = basename (readlink "/dev/mpath/$name");
+ }
+
+ $name = "/dev/$name";
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " name=$name\n";
}
-
- die "No $tool_name command available, please install the sg3_utils package.\n"
+
+ return ($name);
}
-### MAIN #######################################################################
+sub get_devices_path ($)
+{
+ my $dev = shift;
+ my $name = basename ($dev);
+ my @path = ();
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ }
+
+ if (-d "/sys/block/$name/slaves/") {
+ opendir (\*DIR, "/sys/block/$name/slaves/");
+ @path = grep { !/^\./ } readdir (DIR);
+ closedir (DIR);
+ }
+
+ if (scalar (@path) == 0) {
+ push (@path, $name);
+ }
-test_tools_path;
+ if ($path[0] =~ /^dm/) {
+ @path = get_devices_path ("/dev/$path[0]");
+ } else {
+ @path = map { "/dev/$_" } @path;
+ if (defined $options{'v'}) {
+ print " path=[ @path ]\n";
+ }
+ }
-if (getopts("cdhst:v") == 0)
+ return (@path);
+}
+
+sub get_devices_info ($)
{
- print_usage;
- exit(1);
+ my $dev = shift;
+ my $name = basename ($dev);
+ my @info = ();
+
+ if (-e "/sys/block/$name/device/vendor") {
+ open (\*FILE, "</sys/block/$name/device/vendor");
+ chomp ($info[0] = <FILE>);
+ close (FILE);
+ }
+
+ if (-e "/sys/block/$name/device/model") {
+ open (\*FILE, "</sys/block/$name/device/model");
+ chomp ($info[1] = <FILE>);
+ close (FILE);
+ }
+
+ map { s/^\s+// } @info;
+ map { s/\s+$// } @info;
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " info=[ @info ]\n";
+ }
+
+ return (@info);
}
-if ($opt_h)
+sub get_keys_register ($)
{
- print_usage;
- exit(0);
+ my $dev = shift;
+ my @keys = ();
+
+ my $cmd = "sg_persist -n -i -k -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ foreach (@out) {
+ chomp;
+ push (@keys, $_) if ($_ =~ s/^\s+0x//i);
+ }
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ print " keys=[ @keys ]\n";
+ }
+
+ return (@keys);
}
-if ($opt_c && $opt_s) {
- print_usage;
- exit(1);
+sub get_keys_reserve
+{
+ my $dev = shift;
+ my @keys = ();
+
+ my $cmd = "sg_persist -n -i -r -d $dev";
+ my @out = qx { $cmd 2> /dev/null };
+ my $err = ($?>>8);
+
+ foreach (@out) {
+ chomp;
+ push (@keys, $_) if ($_ =~ s/^\s+key=0x//i);
+ }
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " cmd=$cmd\n";
+ print " err=$err\n";
+ print " keys=[ @keys ]\n";
+ }
+
+ return (@keys);
}
-if ($opt_c)
+sub test_config_fence ()
{
- print "\nTesting devices in cluster volumes...\n";
- get_cluster_vol_devices;
- test_devices;
- print_results;
+ my $xml = XML::LibXML->new();
+ my $file = "/etc/cluster/cluster.conf";
+ my $tree = $xml->parse_file ($file);
+ my $root = "//cluster/fencedevices/fencedevice";
+ my $err = 0;
+
+ my $xpath_agent = "count(${root}[\@agent='fence_scsi'])";
+
+ if ($tree->findvalue ($xpath_agent) == 0) {
+ $err = 1;
+ }
+
+ exit ($err);
}
-if ($opt_s)
+sub test_config_nodes ()
{
- print "\nTesting all SCSI block devices...\n";
- get_scsi_block_devices;
- test_devices;
- print_results;
+ my $xml = XML::LibXML->new();
+ my $file = "/etc/cluster/cluster.conf";
+ my $tree = $xml->parse_file ($file);
+ my $root = "//cluster/clusternodes/clusternode";
+ my $err = 0;
+
+ my $xpath_name = "count(${root}/\@name)";
+ my $xpath_nodeid = "count(${root}/\@nodeid)";
+
+ if ($tree->findvalue ($xpath_name) != $tree->findvalue ($xpath_nodeid)) {
+ $err = 1;
+ }
+
+ exit ($err);
}
-if ($opt_t)
+sub print_devices ()
{
- if ($opt_t eq "fence")
- {
- exit check_config_fence;
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self\n";
+ foreach (@devices) {
+ print " $_\n";
+ }
}
- if ($opt_t eq "nodes")
- {
- exit check_config_nodes;
+
+ return;
+}
+
+sub print_options ()
+{
+ return;
+}
+
+sub print_results ($)
+{
+ my $dev = shift;
+ my @results = @{$results{$dev}};
+
+ if (defined $options{'v'}) {
+ $self = (caller(0))[3];
+ print " $self (dev=$dev)\n";
+ print " results=[ action=$results[0] verify=$results[1] ]\n";
+ } else {
+ printf (" %-*s", $width, $_);
+ if (grep { $_ } @results) {
+ $test = colored (" FAIL ", "red");
+ } else {
+ $test = colored (" OK ", "green");
+ }
+ printf ("[%s]\n", $test);
}
+
+ return;
}
-if (!$opt_c && !$opt_s && !$opt_t)
+sub print_usage
{
- print "\nPlease specify either cluster or SCSI mode.\n";
- print_usage;
- exit(1);
+ print "\n";
+ print "Usage: fence_scsi_test -o <on|off> -k <key> [options]\n";
+ print "\n";
+ print "Actions:\n";
+ print "\n";
+ print " on Register <key> with the devices.\n";
+ print " off Remove <key> form the devices.\n";
+ print "\n";
+ print "Options:\n";
+ print "\n";
+ print " -d, --devices=LIST Devices used for the current action.\n";
+ print " -h, --help Display this help and exit.\n";
+ print " -v, --verbose Verbose mode.\n";
+ print "\n";
+
+ defined $options{'h'} ? exit (0) : exit (1);
+}
+
+################################################################################
+
+get_options ();
+
+if (scalar (keys %options) == 0) {
+ print_usage ();
+}
+
+if (defined $options{'v'}) {
+ print_options ();
+}
+
+if (defined $options{'h'}) {
+ print_usage ();
+}
+
+if (defined $options{'t'}) {
+ for ($options{'t'}) {
+ ($_ =~ /^fence$/i) && do {
+ test_config_fence ();
+ last;
+ };
+ ($_ =~ /^nodes$/i) && do {
+ test_config_nodes ();
+ last;
+ };
+ exit (1);
+ }
+}
+
+if ($options{'k'} =~ /^[[:xdigit:]]+$/) {
+ $node_key = lc ($options{'k'});
+} else {
+ print_usage ();
+}
+
+for ($options{'o'}) {
+ ($_ =~ /^on$/i) && do {
+ do_key_write ($node_key);
+ last;
+ };
+ ($_ =~ /^off$/i) && do {
+ do_key_read (\$host_key);
+ last;
+ };
+ print_usage ();
+}
+
+if (defined $options{'d'}) {
+ @devices = get_devices ();
+} else {
+ @devices = get_devices_clvm ();
+}
+
+if (scalar (@devices) == 0) {
+ die "error: no devices found\n";
+} else {
+ $count = scalar (@devices);
+ $width = (reverse sort { $a <=> $b } map { (length) + 8 } @devices)[0];
+}
+
+if (defined $options{'v'}) {
+ print_devices ();
+}
+
+foreach (@devices) {
+ if (! -e $_) {
+ die "error: $_ does not exist\n";
+ }
+ if (! -b $_) {
+ die "error: $_ is not a block device\n";
+ }
+
+ $devices_name{$_} = get_devices_name ($_);
+ $devices_path{$_} = [ get_devices_path ($devices_name{$_}) ];
+}
+
+for ($options{'o'}) {
+ ($_ =~ /^on$/i) && do {
+ print "\n" if (!defined $options{'v'});
+ foreach (@devices) {
+ $results{$_}[0] = do_action_on (@{$devices_path{$_}}, $_, $node_key);
+ $results{$_}[1] = do_verify_on (@{$devices_path{$_}}, $_, $node_key);
+ print_results ($_);
+ }
+ print "\n" if (!defined $options{'v'});
+ last;
+ };
+ ($_ =~ /^off$/i) && do {
+ print "\n" if (!defined $options{'v'});
+ foreach (@devices) {
+ $results{$_}[0] = do_action_off ($devices_name{$_}, $node_key, $host_key);
+ $results{$_}[1] = do_verify_off ($devices_name{$_}, $node_key, $host_key);
+ print_results ($_);
+ }
+ print "\n" if (!defined $options{'v'});
+ last;
+ };
+ print_usage ();
}
diff --git a/fence/man/fence_scsi_test.8 b/fence/man/fence_scsi_test.8
new file mode 100644
index 0000000..3252dca
--- /dev/null
+++ b/fence/man/fence_scsi_test.8
@@ -0,0 +1,68 @@
+.\" Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+.\"
+.\" This copyrighted material is made available to anyone wishing to use,
+.\" modify, copy, or redistribute it subject to the terms and conditions
+.\" of the GNU General Public License v.2.
+
+.TH fence_scsi_test 8
+
+.SH NAME
+fence_scsi_test - Test for SCSI persistent reservation fencing
+
+.SH SYNOPSIS
+.B
+fence_scsi_test -o <on|off> -k <key>
+[\fIOPTIONS\fR]
+
+.SH DESCRIPTION
+fence_scsi_test is a script used to verify that specific hardware
+configurations are capable of being used with the fence_scsi
+agent. All storage devices that are to be used with the fence_scsi
+agent must be capable of SCSI persistent reservations. This script
+assists in determining that the requirements are met by performing
+appropriate SCSI-PR actions and verifying the results.
+
+This script is capable of creating reservations and registrations, as
+well as removing them. The "on" action is used to create reservations,
+just as you would do when a node comes online. The "off" action is
+used to remove registrations, which is equivalent to fencing. It is
+important to test both the "on" and "off" actions when testing for
+fence_scsi compatibility.
+
+Because this script is capable of creating, modifying, and removing
+existing reservations and registrations, it should not be used on any
+systems that are actively using SCSI persistent reservations.
+
+.SH OPTIONS
+.TP
+\fB-o, --action=[on|off]\fR
+The action to perform. This value can be "on" or "off". For "on", the
+script will attempt to register a key (see -k option) with the
+device(s) (see -d option) and create a reservation if none exists. The
+"off" action will attempt to remove a key from the device(s). This
+option is required.
+
+.TP
+\fB-k, --key=VALUE\fR
+The key to use for the current action. The key must be a hexadecimal
+value and should be unique to a node. For the "on" action, the key
+specifies the key value use to register the local node with the
+device(s). For the "off" action, the key specifies the key value to be
+removed from the device(s).
+
+.TP
+\fB-d, --devices=LIST\fR
+List of devices to use for current action. This can be a single device
+or a comma-separated list of devices. Each device should be given as
+the full path (eg. /dev/sdc).
+
+.TP
+\fB-h, --help\fR
+Print out a help message describing available options, then exit.
+
+.TP
+\fB-v, --verbose\fR
+Verbose output.
+
+.SH SEE ALSO
+fence_scsi(8), fence(8), fence_node(8), sg_persist(8), lvs(8), lvm.conf(5)
13 years, 7 months
cluster: RHEL60 - fsck.gfs2 segfaults if journals are missing
by Bob Peterson
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 11f4e89470e8e239087e80b3f2ce94baf7cbe154
Parent: c4d0ebcd261faa04ea6764b5c96dff27db9c0fd5
Author: Bob Peterson <rpeterso(a)redhat.com>
AuthorDate: Wed Aug 18 13:06:31 2010 -0500
Committer: Bob Peterson <rpeterso(a)redhat.com>
CommitterDate: Mon Sep 27 10:46:54 2010 -0500
fsck.gfs2 segfaults if journals are missing
This patch makes it possible for fsck.gfs2 to detect missing and damaged
journals and recreate them. Previous versions of fsck.gfs2 would
segfault if journals were missing because it made assumptions about
the jindex file pointing to a valid dinode. Also, I moved function
ji_update which was exclusively used by fsck.gfs2 from libgfs2 to fsck.
rhbz#622576
---
gfs2/convert/gfs2_convert.c | 12 +++--
gfs2/fsck/fs_recovery.c | 55 ++++++++++++++++++++++-
gfs2/fsck/fs_recovery.h | 7 ++-
gfs2/fsck/pass1.c | 104 +++++++++++++++++++++++++++---------------
gfs2/libgfs2/libgfs2.h | 5 +-
gfs2/libgfs2/structures.c | 32 +++++++------
gfs2/libgfs2/super.c | 43 +----------------
7 files changed, 154 insertions(+), 104 deletions(-)
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 642d26a..6a754b1 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1987,22 +1987,24 @@ static void conv_build_jindex(struct gfs2_sbd *sdp)
sdp->md.jiinode = createi(sdp->master_dir, "jindex", S_IFDIR | 0700,
GFS2_DIF_SYSTEM);
+ sdp->md.journal = malloc(sdp->md.journals *
+ sizeof(struct gfs2_inode *));
for (j = 0; j < sdp->md.journals; j++) {
char name[256];
- struct gfs2_inode *ip;
printf("Writing journal #%d...", j + 1);
fflush(stdout);
sprintf(name, "journal%u", j);
- ip = createi(sdp->md.jiinode, name, S_IFREG | 0600,
- GFS2_DIF_SYSTEM);
- write_journal(sdp, ip, j,
+ sdp->md.journal[j] = createi(sdp->md.jiinode, name, S_IFREG |
+ 0600, GFS2_DIF_SYSTEM);
+ write_journal(sdp, j,
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
- inode_put(&ip);
+ inode_put(&sdp->md.journal[j]);
printf("done.\n");
fflush(stdout);
}
+ free(sdp->md.journal);
if (sdp->debug) {
printf("\nJindex:\n");
gfs2_dinode_print(&sdp->md.jiinode->i_di);
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index d908873..07c1552 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -12,6 +12,8 @@
#include "libgfs2.h"
#include "util.h"
+#define JOURNAL_NAME_SIZE 16
+
unsigned int sd_found_jblocks = 0, sd_replayed_jblocks = 0;
unsigned int sd_found_metablocks = 0, sd_replayed_metablocks = 0;
unsigned int sd_found_revokes = 0;
@@ -540,7 +542,7 @@ out:
log_info( _("jid=%u: Failed\n"), j);
reinit:
if (query( _("Do you want to clear the journal instead? (y/n)")))
- error = write_journal(sdp, sdp->md.journal[j], j,
+ error = write_journal(sdp, j,
sdp->md.journal[j]->i_di.di_size /
sdp->sd_sb.sb_bsize);
else
@@ -569,6 +571,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
*clean_journals = 0;
+ sdp->jsize = GFS2_DEFAULT_JSIZE;
/* Get master dinode */
gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
@@ -579,7 +582,19 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
}
for(i = 0; i < sdp->md.journals; i++) {
+ if (!sdp->md.journal[i]) {
+ log_err(_("File system journal \"journal%d\" is "
+ "missing: pass1 will try to recreate it.\n"),
+ i);
+ continue;
+ }
if (!error) {
+ uint64_t jsize = sdp->md.journal[i]->i_di.di_size /
+ (1024 * 1024);
+
+ if (sdp->jsize == GFS2_DEFAULT_JSIZE && jsize &&
+ jsize != sdp->jsize)
+ sdp->jsize = jsize;
error = gfs2_recover_journal(sdp->md.journal[i], i,
preen, force_check,
&clean);
@@ -600,3 +615,41 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
fsync(sdp->device_fd);
return error;
}
+
+/*
+ * ji_update - fill in journal info
+ * sdp: the incore superblock pointer
+ *
+ * Given the inode for the journal index, read in all
+ * the journal inodes.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+int ji_update(struct gfs2_sbd *sdp)
+{
+ struct gfs2_inode *jip, *ip = sdp->md.jiinode;
+ char journal_name[JOURNAL_NAME_SIZE];
+ int i;
+
+ if(!ip) {
+ log_crit("Journal index inode not found.\n");
+ return -1;
+ }
+
+ if(!(sdp->md.journal = calloc(ip->i_di.di_entries - 2, sizeof(struct gfs2_inode *)))) {
+ log_err("Unable to allocate journal index\n");
+ return -1;
+ }
+ sdp->md.journals = 0;
+ memset(journal_name, 0, sizeof(*journal_name));
+ for(i = 0; i < ip->i_di.di_entries - 2; i++) {
+ /* FIXME check snprintf return code */
+ snprintf(journal_name, JOURNAL_NAME_SIZE, "journal%u", i);
+ gfs2_lookupi(sdp->md.jiinode, journal_name, strlen(journal_name),
+ &jip);
+ sdp->md.journal[i] = jip;
+ }
+ sdp->md.journals = ip->i_di.di_entries - 2;
+ return 0;
+
+}
diff --git a/gfs2/fsck/fs_recovery.h b/gfs2/fsck/fs_recovery.h
index a61884d..1a7aae3 100644
--- a/gfs2/fsck/fs_recovery.h
+++ b/gfs2/fsck/fs_recovery.h
@@ -3,9 +3,10 @@
#include "libgfs2.h"
-int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
- int *clean_journals);
-int preen_is_safe(struct gfs2_sbd *sdp, int preen, int force_check);
+extern int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
+ int *clean_journals);
+extern int preen_is_safe(struct gfs2_sbd *sdp, int preen, int force_check);
+extern int ji_update(struct gfs2_sbd *sdp);
#endif /* __FS_RECOVERY_H__ */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 4fb7abf..17b23df 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1174,25 +1174,37 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
/* Check system inode and verify it's marked "in use" in the bitmap: */
/* Should work for all system inodes: root, master, jindex, per_node, etc. */
-static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
- int builder(struct gfs2_sbd *sbp),
- enum gfs2_mark_block mark)
+/* We have to pass the sysinode as ** because the pointer may change out from
+ under the reference by way of the builder() function. */
+static int check_system_inode(struct gfs2_sbd *sdp,
+ struct gfs2_inode **sysinode,
+ const char *filename,
+ int builder(struct gfs2_sbd *sbp),
+ enum gfs2_mark_block mark)
{
uint64_t iblock = 0;
struct dir_status ds = {0};
int error;
log_info( _("Checking system inode '%s'\n"), filename);
- if (sysinode) {
+ if (*sysinode) {
/* Read in the system inode, look at its dentries, and start
* reading through them */
- iblock = sysinode->i_di.di_num.no_addr;
+ iblock = (*sysinode)->i_di.di_num.no_addr;
log_info( _("System inode for '%s' is located at block %"
PRIu64 " (0x%" PRIx64 ")\n"), filename,
iblock, iblock);
-
- /* FIXME: check this block's validity */
-
+ if (gfs2_check_meta((*sysinode)->i_bh, GFS2_METATYPE_DI)) {
+ log_err( _("Found invalid system dinode at block #"
+ "%llu (0x%llx)\n"),
+ (unsigned long long)iblock,
+ (unsigned long long)iblock);
+ gfs2_blockmap_set(bl, iblock, gfs2_block_free);
+ check_n_fix_bitmap(sdp, iblock, gfs2_block_free);
+ inode_put(sysinode);
+ }
+ }
+ if (*sysinode) {
ds.q = block_type(iblock);
/* If the inode exists but the block is marked free, we might
be recovering from a corrupt bitmap. In that case, don't
@@ -1201,52 +1213,67 @@ static int check_system_inode(struct gfs2_inode *sysinode, const char *filename,
if (ds.q == gfs2_block_free) {
log_info( _("The inode exists but the block is not "
"marked 'in use'; fixing it.\n"));
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
+ fsck_blockmap_set(*sysinode,
+ (*sysinode)->i_di.di_num.no_addr,
filename, mark);
ds.q = mark;
if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
+ dirtree_insert((*sysinode)->i_di.di_num.no_addr);
}
} else
- log_info( _("System inode for '%s' is missing.\n"), filename);
+ log_info( _("System inode for '%s' is corrupt or missing.\n"),
+ filename);
/* If there are errors with the inode here, we need to create a new
inode and get it all setup - of course, everything will be in
lost+found then, but we *need* our system inodes before we can
do any of that. */
- if(!sysinode || ds.q != mark) {
+ if(!(*sysinode) || ds.q != mark) {
log_err( _("Invalid or missing %s system inode (should be %d, "
"is %d).\n"), filename, mark, ds.q);
if (query(_("Create new %s system inode? (y/n) "), filename)) {
- builder(sysinode->i_sbd);
- fsck_blockmap_set(sysinode,
- sysinode->i_di.di_num.no_addr,
+ log_err( _("Rebuilding system file \"%s\"\n"),
+ filename);
+ error = builder(sdp);
+ if (error) {
+ log_err( _("Error trying to rebuild system "
+ "file %s: Cannot continue\n"),
+ filename);
+ return error;
+ }
+ fsck_blockmap_set(*sysinode,
+ (*sysinode)->i_di.di_num.no_addr,
filename, mark);
ds.q = mark;
if (mark == gfs2_inode_dir)
- dirtree_insert(sysinode->i_di.di_num.no_addr);
+ dirtree_insert((*sysinode)->i_di.di_num.no_addr);
} else {
log_err( _("Cannot continue without valid %s inode\n"),
filename);
return -1;
}
}
- if (S_ISDIR(sysinode->i_di.di_mode)) {
+ if (S_ISDIR((*sysinode)->i_di.di_mode)) {
struct block_count bc = {0};
sysdir_fxns.private = &bc;
- if (sysinode->i_di.di_flags & GFS2_DIF_EXHASH)
- check_metatree(sysinode, &sysdir_fxns);
+ if ((*sysinode)->i_di.di_flags & GFS2_DIF_EXHASH)
+ check_metatree(*sysinode, &sysdir_fxns);
else
- check_linear_dir(sysinode, sysinode->i_bh,
+ check_linear_dir(*sysinode, (*sysinode)->i_bh,
&sysdir_fxns);
}
- error = handle_ip(sysinode->i_sbd, sysinode);
+ error = handle_ip(sdp, *sysinode);
return error;
}
static int build_a_journal(struct gfs2_sbd *sdp)
{
+ char name[256];
+
+ /* First, try to delete the journal if it's in jindex */
+ sprintf(name, "journal%u", sdp->md.journals);
+ gfs2_dirent_del(sdp->md.jiinode, name, strlen(name));
+ /* Now rebuild it */
build_journal(sdp, sdp->md.journals, sdp->md.jiinode);
return 0;
}
@@ -1258,43 +1285,43 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
/*******************************************************************
******* Check the system inode integrity *************
*******************************************************************/
- if (check_system_inode(sdp->master_dir, "master", build_master,
+ if (check_system_inode(sdp, &sdp->master_dir, "master", build_master,
gfs2_inode_dir)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.rooti, "root", build_root,
+ if (check_system_inode(sdp, &sdp->md.rooti, "root", build_root,
gfs2_inode_dir)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.inum, "inum", build_inum,
+ if (check_system_inode(sdp, &sdp->md.inum, "inum", build_inum,
gfs2_inode_file)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.statfs, "statfs", build_statfs,
+ if (check_system_inode(sdp, &sdp->md.statfs, "statfs", build_statfs,
gfs2_inode_file)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.jiinode, "jindex", build_jindex,
+ if (check_system_inode(sdp, &sdp->md.jiinode, "jindex", build_jindex,
gfs2_inode_dir)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.riinode, "rindex", build_rindex,
+ if (check_system_inode(sdp, &sdp->md.riinode, "rindex", build_rindex,
gfs2_inode_file)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.qinode, "quota", build_quota,
+ if (check_system_inode(sdp, &sdp->md.qinode, "quota", build_quota,
gfs2_inode_file)) {
stack;
return -1;
}
- if (check_system_inode(sdp->md.pinode, "per_node", build_per_node,
- gfs2_inode_dir)) {
+ if (check_system_inode(sdp, &sdp->md.pinode, "per_node",
+ build_per_node, gfs2_inode_dir)) {
stack;
return -1;
}
@@ -1306,7 +1333,7 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
char jname[16];
sprintf(jname, "journal%d", sdp->md.journals);
- if (check_system_inode(sdp->md.journal[sdp->md.journals],
+ if (check_system_inode(sdp, &sdp->md.journal[sdp->md.journals],
jname, build_a_journal,
gfs2_inode_file)) {
stack;
@@ -1399,6 +1426,14 @@ int pass1(struct gfs2_sbd *sbp)
skip_this_pass = FALSE;
fflush(stdout);
}
+ if (fsck_system_inode(sbp, block)) {
+ log_debug(_("Already processed system inode "
+ "%lld (0x%llx)\n"),
+ (unsigned long long)block,
+ (unsigned long long)block);
+ first = 0;
+ continue;
+ }
bh = bread(sbp, block);
/*log_debug( _("Checking metadata block #%" PRIu64
@@ -1417,11 +1452,6 @@ int pass1(struct gfs2_sbd *sbp)
}
check_n_fix_bitmap(sbp, block,
gfs2_block_free);
- } else if (fsck_system_inode(sbp, block)) {
- log_debug(_("Already processed system inode "
- "%lld (0x%llx)\n"),
- (unsigned long long)block,
- (unsigned long long)block);
} else if (handle_di(sbp, bh) < 0) {
stack;
brelse(bh);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 8835a4f..c798bda 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -472,8 +472,8 @@ extern int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
extern void build_height(struct gfs2_inode *ip, int height);
extern void unstuff_dinode(struct gfs2_inode *ip);
extern unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size);
-extern int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip,
- unsigned int j, unsigned int blocks);
+extern int write_journal(struct gfs2_sbd *sdp, unsigned int j,
+ unsigned int blocks);
/**
* device_size - figure out a device's size
@@ -671,7 +671,6 @@ extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
/* super.c */
extern int check_sb(struct gfs2_sb *sb);
extern int read_sb(struct gfs2_sbd *sdp);
-extern int ji_update(struct gfs2_sbd *sdp);
extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index c288abd..66a5733 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -73,8 +73,7 @@ void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
}
}
-int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
- unsigned int blocks)
+int write_journal(struct gfs2_sbd *sdp, unsigned int j, unsigned int blocks)
{
struct gfs2_log_header lh;
unsigned int x;
@@ -84,8 +83,9 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
/* Build the height up so our journal blocks will be contiguous and */
/* not broken up by indirect block pages. */
- height = calc_tree_height(ip, (blocks + 1) * sdp->bsize);
- build_height(ip, height);
+ height = calc_tree_height(sdp->md.journal[j],
+ (blocks + 1) * sdp->bsize);
+ build_height(sdp->md.journal[j], height);
memset(&lh, 0, sizeof(struct gfs2_log_header));
lh.lh_header.mh_magic = GFS2_MAGIC;
@@ -94,14 +94,16 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
for (x = 0; x < blocks; x++) {
- struct gfs2_buffer_head *bh = get_file_buf(ip, x, TRUE);
+ struct gfs2_buffer_head *bh = get_file_buf(sdp->md.journal[j],
+ x, TRUE);
if (!bh)
return -1;
bmodified(bh);
brelse(bh);
}
for (x = 0; x < blocks; x++) {
- struct gfs2_buffer_head *bh = get_file_buf(ip, x, FALSE);
+ struct gfs2_buffer_head *bh = get_file_buf(sdp->md.journal[j],
+ x, FALSE);
if (!bh)
return -1;
@@ -121,7 +123,7 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
if (sdp->debug) {
printf("\nJournal %u:\n", j);
- gfs2_dinode_print(&ip->i_di);
+ gfs2_dinode_print(&sdp->md.journal[j]->i_di);
}
return 0;
}
@@ -129,17 +131,14 @@ int write_journal(struct gfs2_sbd *sdp, struct gfs2_inode *ip, unsigned int j,
int build_journal(struct gfs2_sbd *sdp, int j, struct gfs2_inode *jindex)
{
char name[256];
- struct gfs2_inode *ip;
int ret;
sprintf(name, "journal%u", j);
- ip = createi(jindex, name, S_IFREG | 0600, GFS2_DIF_SYSTEM);
- ret = write_journal(sdp, ip, j,
+ sdp->md.journal[j] = createi(jindex, name, S_IFREG | 0600,
+ GFS2_DIF_SYSTEM);
+ ret = write_journal(sdp, j,
sdp->jsize << 20 >> sdp->sd_sb.sb_bsize_shift);
- if (ret)
- return ret;
- inode_put(&ip);
- return 0;
+ return ret;
}
int build_jindex(struct gfs2_sbd *sdp)
@@ -150,17 +149,20 @@ int build_jindex(struct gfs2_sbd *sdp)
jindex = createi(sdp->master_dir, "jindex", S_IFDIR | 0700,
GFS2_DIF_SYSTEM);
-
+ sdp->md.journal = malloc(sdp->md.journals *
+ sizeof(struct gfs2_inode *));
for (j = 0; j < sdp->md.journals; j++) {
ret = build_journal(sdp, j, jindex);
if (ret)
return ret;
+ inode_put(&sdp->md.journal[j]);
}
if (sdp->debug) {
printf("\nJindex:\n");
gfs2_dinode_print(&jindex->i_di);
}
+ free(sdp->md.journal);
inode_put(&jindex);
return 0;
}
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index c5b5800..5d232a6 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -75,6 +75,9 @@ int read_sb(struct gfs2_sbd *sdp)
(sdp->sd_sb.sb_bsize-sizeof(struct gfs2_meta_header)) /
sizeof(uint64_t);
sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+ sdp->sd_hash_bsize = sdp->bsize / 2;
+ sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
+ sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs;
for (x = 2; ; x++){
@@ -113,46 +116,6 @@ int read_sb(struct gfs2_sbd *sdp)
return error;
}
-#define JOURNAL_NAME_SIZE 16
-
-/*
- * ji_update - fill in journal info
- * sdp: the incore superblock pointer
- *
- * Given the inode for the journal index, read in all
- * the journal inodes.
- *
- * Returns: 0 on success, -1 on failure
- */
-int ji_update(struct gfs2_sbd *sdp)
-{
- struct gfs2_inode *jip, *ip = sdp->md.jiinode;
- char journal_name[JOURNAL_NAME_SIZE];
- int i;
-
- if(!ip) {
- log_crit("Journal index inode not found.\n");
- return -1;
- }
-
- if(!(sdp->md.journal = calloc(ip->i_di.di_entries - 2, sizeof(struct gfs2_inode *)))) {
- log_err("Unable to allocate journal index\n");
- return -1;
- }
- sdp->md.journals = 0;
- memset(journal_name, 0, sizeof(*journal_name));
- for(i = 0; i < ip->i_di.di_entries - 2; i++) {
- /* FIXME check snprintf return code */
- snprintf(journal_name, JOURNAL_NAME_SIZE, "journal%u", i);
- gfs2_lookupi(sdp->md.jiinode, journal_name, strlen(journal_name),
- &jip);
- sdp->md.journal[i] = jip;
- }
- sdp->md.journals = ip->i_di.di_entries - 2;
- return 0;
-
-}
-
/**
* rindex_read - read in the rg index file
* @sdp: the incore superblock pointer
13 years, 7 months
cluster: RHEL56 - rgmanager: tomcat-5 can't start properly
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 5e8ef2ca3e43652e77b277fe72eb3832d2c2b656
Parent: 64a1dc0330e2733c266b99e0cd8cfbd72f1f96a1
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Sep 27 15:28:19 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Sep 27 15:33:30 2010 +0200
rgmanager: tomcat-5 can't start properly
Error was introduced when switching from sudo to su
Resolves: rhbz#591003
---
rgmanager/src/resources/tomcat-5.sh | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/rgmanager/src/resources/tomcat-5.sh b/rgmanager/src/resources/tomcat-5.sh
index fa74d90..52d6f39 100755
--- a/rgmanager/src/resources/tomcat-5.sh
+++ b/rgmanager/src/resources/tomcat-5.sh
@@ -193,12 +193,12 @@ start()
CLASSPATH="$JAVA_HOME"/lib/tools.jar:"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging-api.jar:`/usr/bin/build-classpath mx4j/mx4j-impl`:`/usr/bin/build-classpath mx4j/mx4j-jmx`
- su "$TOMCAT_USER" -c "$JAVA_HOME/bin/java" $JAVA_OPTS $OCF_RESKEY_catalina_options \
- -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
- -Dcatalina.base="$TOMCAT_gen_catalina_base" \
- -Dcatalina.home="$CATALINA_HOME" \
- -Djava.io.tmpdir="$CATALINA_TMPDIR" \
- org.apache.catalina.startup.Bootstrap "$@" start \
+ su "$TOMCAT_USER" -c " \"$JAVA_HOME/bin/java\" $JAVA_OPTS $OCF_RESKEY_catalina_options \
+ -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \
+ -Dcatalina.base=\"$TOMCAT_gen_catalina_base\" \
+ -Dcatalina.home=\"$CATALINA_HOME\" \
+ -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \
+ org.apache.catalina.startup.Bootstrap \"$@\" start " \
>> "$TOMCAT_gen_catalina_base"/logs/catalina.out 2>&1 &
13 years, 7 months
cluster: STABLE3 - rgmanager: tomcat-5 can't start properly
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 5492f5160f1cef50ac5fc38cf184974e587bbfb3
Parent: c51005e99964c0020511cb953b7eeacb8bc1bbdf
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Sep 27 15:28:19 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Sep 27 15:28:19 2010 +0200
rgmanager: tomcat-5 can't start properly
Error was introduced when switching from sudo to su
Resolves: rhbz#591003
---
rgmanager/src/resources/tomcat-5.sh | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/rgmanager/src/resources/tomcat-5.sh b/rgmanager/src/resources/tomcat-5.sh
index cbdd2e3..a84b450 100644
--- a/rgmanager/src/resources/tomcat-5.sh
+++ b/rgmanager/src/resources/tomcat-5.sh
@@ -162,12 +162,12 @@ start()
CLASSPATH="$JAVA_HOME"/lib/tools.jar:"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging-api.jar:`/usr/bin/build-classpath mx4j/mx4j-impl`:`/usr/bin/build-classpath mx4j/mx4j-jmx`
- su "$TOMCAT_USER" -c "$JAVA_HOME/bin/java" $JAVA_OPTS $OCF_RESKEY_catalina_options \
- -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
- -Dcatalina.base="$TOMCAT_gen_catalina_base" \
- -Dcatalina.home="$CATALINA_HOME" \
- -Djava.io.tmpdir="$CATALINA_TMPDIR" \
- org.apache.catalina.startup.Bootstrap "$@" start \
+ su "$TOMCAT_USER" -c " \"$JAVA_HOME/bin/java\" $JAVA_OPTS $OCF_RESKEY_catalina_options \
+ -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \
+ -Dcatalina.base=\"$TOMCAT_gen_catalina_base\" \
+ -Dcatalina.home=\"$CATALINA_HOME\" \
+ -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \
+ org.apache.catalina.startup.Bootstrap \"$@\" start " \
>> "$TOMCAT_gen_catalina_base"/logs/catalina.out 2>&1 &
13 years, 7 months
cluster: RHEL56 - fence_ifmib: New fence agent for IF-MIB
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 64a1dc0330e2733c266b99e0cd8cfbd72f1f96a1
Parent: c73d85e25c4f198534ec7a8585f42b89ba0675ae
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Sep 27 09:59:48 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Sep 27 09:59:48 2010 +0200
fence_ifmib: New fence agent for IF-MIB
Fence agent imported from STABLE3
Resolves: rhbz#572863
---
fence/agents/Makefile | 3 +
fence/agents/ifmib/Makefile | 38 ++++++++++
fence/agents/ifmib/README | 45 +++++++++++
fence/agents/ifmib/fence_ifmib.py | 149 +++++++++++++++++++++++++++++++++++++
4 files changed, 235 insertions(+), 0 deletions(-)
diff --git a/fence/agents/Makefile b/fence/agents/Makefile
index 3c16fc5..716530c 100644
--- a/fence/agents/Makefile
+++ b/fence/agents/Makefile
@@ -27,6 +27,7 @@ all:
${MAKE} -C drac all
${MAKE} -C egenera all
# ${MAKE} -C ibmblade all
+ ${MAKE} -C ifmib all
${MAKE} -C ilo all
${MAKE} -C ilo_mp all
${MAKE} -C ipmilan all
@@ -61,6 +62,7 @@ install: all
${MAKE} -C drac install
${MAKE} -C egenera install
# ${MAKE} -C ibmblade install
+ ${MAKE} -C ifmib install
${MAKE} -C ilo install
${MAKE} -C ilo_mp install
${MAKE} -C ipmilan install
@@ -95,6 +97,7 @@ clean:
${MAKE} -C drac clean
${MAKE} -C egenera clean
# ${MAKE} -C ibmblade clean
+ ${MAKE} -C ifmib clean
${MAKE} -C ilo clean
${MAKE} -C ilo_mp clean
${MAKE} -C ipmilan clean
diff --git a/fence/agents/ifmib/Makefile b/fence/agents/ifmib/Makefile
new file mode 100644
index 0000000..e564689
--- /dev/null
+++ b/fence/agents/ifmib/Makefile
@@ -0,0 +1,38 @@
+###############################################################################
+###############################################################################
+##
+## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
+## Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+##
+## This copyrighted material is made available to anyone wishing to use,
+## modify, copy, or redistribute it subject to the terms and conditions
+## of the GNU General Public License v.2.
+##
+###############################################################################
+###############################################################################
+
+SOURCE= fence_ifmib.py
+TARGET= fence_ifmib
+
+top_srcdir=../..
+include ${top_srcdir}/make/defines.mk
+
+all: $(TARGET)
+
+fence_ifmib: $(SOURCE)
+ : > $(TARGET)
+ awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
+ echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET)
+ ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET)
+ echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET)
+ awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET)
+ chmod +x $(TARGET)
+
+install: all
+ if [ ! -d ${sbindir} ]; then \
+ install -d ${sbindir}; \
+ fi
+ install -m755 ${TARGET} ${sbindir}
+
+clean:
+ rm -f $(TARGET)
diff --git a/fence/agents/ifmib/README b/fence/agents/ifmib/README
new file mode 100644
index 0000000..cd2a3c1
--- /dev/null
+++ b/fence/agents/ifmib/README
@@ -0,0 +1,45 @@
+Intro:
+------
+This is an SNMP-based fencing agent for RHCS. It was designed with the use-case
+of disabling ethernet ports on an iSCSI SAN, but could be used to disable any
+port on any SNMP v1/2c/3 device that implementes the IF-MIB.
+
+The script requires NetSNMP to be installed and working on all nodes
+in the cluster. There are no requirements for any MIBs to be setup --- all of
+the required OIDs are hard-coded into the script. Since the IF-MIB is an IETF
+standard, these identifiers are very widely supported and will not change.
+
+
+Typical usage:
+--------------
+To use this agen with the switch used on the iSCSI network, you'll require:
+ 1) A managed switch running SNMP.
+ 2) An SNMP community with write privileges.
+ 3) Permission to send SNMP through any ACLs or firewalls from the nodes.
+ 4) The ifIndex or ifPort associated with the ports being used by the cluster nodes.
+
+Consider a three-node cluster composed of A, B, and C. Each node has two
+network interfaces - one used for network and cluster communication, the second
+used for iSCSI traffic. If A needs to be fenced, B and C will run this script
+to administratively disable the switchport for A's connection to the iSCSI
+storage.
+
+If you are using a single interface for cluster and iSCSI traffic, this will
+still work, but you will lose network connectivity to the fenced host.
+
+
+cluster.conf:
+-------------
+There is no GUI support for this fence agent at this time. To use it, you will
+need something like this cluster.conf
+
+<fencedevice agent="fence_ifmib" name="myswitch" comm="fencing" ipaddr="sw1"/>
+
+In a node's fencing methods, you'll include a line like this:
+
+<device name="myswitch" port="43" option="off"/>
+
+This node will be fenced by disabling the port with ifIndex 43 on the host sw1.
+In SNMP speak, we set IF-MIB::ifAdminStatus.43 = down(2).
+
+If you will use port name (like fc1/1), script will try to find ifIndex.
diff --git a/fence/agents/ifmib/fence_ifmib.py b/fence/agents/ifmib/fence_ifmib.py
new file mode 100644
index 0000000..a0f979c
--- /dev/null
+++ b/fence/agents/ifmib/fence_ifmib.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+
+# The Following agent has been tested on:
+# - Cisco MDS UROS 9134 FC (1 Slot) Chassis ("1/2/4 10 Gbps FC/Supervisor-2") Motorola, e500v2
+# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
+# - Cisco MDS 9124 (1 Slot) Chassis ("1/2/4 Gbps FC/Supervisor-2") Motorola, e500
+# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
+# - Partially with APC PDU (Network Management Card AOS v2.7.0, Rack PDU APP v2.7.3)
+# Only lance if is visible
+
+import sys, re, pexpect
+sys.path.append("/usr/lib/fence")
+from fencing import *
+from fencing_snmp import *
+
+#BEGIN_VERSION_GENERATION
+FENCE_RELEASE_NAME=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+# IF-MIB trees for alias, status and port
+ALIASES_OID=".1.3.6.1.2.1.31.1.1.1.18"
+PORTS_OID=".1.3.6.1.2.1.2.2.1.2"
+STATUSES_OID=".1.3.6.1.2.1.2.2.1.7"
+
+# Status constants returned as value from SNMP
+STATUS_UP=1
+STATUS_DOWN=2
+STATUS_TESTING=3
+
+### GLOBAL VARIABLES ###
+# Port number converted from port name or index
+port_num=None
+
+### FUNCTIONS ###
+
+# Convert port index or name to port index
+def port2index(conn,port):
+ res=None
+
+ if (port.isdigit()):
+ res=int(port)
+ else:
+ ports=conn.walk(PORTS_OID,30)
+
+ for x in ports:
+ if (x[1].strip('"')==port):
+ res=int(x[0].split('.')[-1])
+ break
+
+ if (res==None):
+ fail_usage("Can't find port with name %s!"%(port))
+
+ return res
+
+def get_power_status(conn,options):
+ global port_num
+
+ if (port_num==None):
+ port_num=port2index(conn,options["-n"])
+
+ (oid,status)=conn.get("%s.%d"%(STATUSES_OID,port_num))
+ return (status==str(STATUS_UP) and "on" or "off")
+
+def set_power_status(conn, options):
+ global port_num
+
+ if (port_num==None):
+ port_num=port2index(conn,options["-n"])
+
+ conn.set("%s.%d"%(STATUSES_OID,port_num),(options["-o"]=="on" and STATUS_UP or STATUS_DOWN))
+
+# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
+# in format a.b.c.d...z and returned dict has key only z
+def array_to_dict(ar):
+ return dict(map(lambda y:[y[0].split('.')[-1],y[1]],ar))
+
+def get_outlets_status(conn, options):
+ result={}
+
+ res_fc=conn.walk(PORTS_OID,30)
+ res_aliases=array_to_dict(conn.walk(ALIASES_OID,30))
+
+ for x in res_fc:
+ port_num=x[0].split('.')[-1]
+
+ port_name=x[1].strip('"')
+ port_alias=(res_aliases.has_key(port_num) and res_aliases[port_num].strip('"') or "")
+ port_status=""
+ result[port_name]=(port_alias,port_status)
+
+ return result
+
+# Define new options
+def ifmib_define_defaults():
+ all_opt["snmp_version"]["default"]="2c"
+
+# Main agent method
+def main():
+ global port_oid
+
+ device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
+ "action", "ipaddr", "login", "passwd", "passwd_script",
+ "test", "port", "separator", "no_login", "no_password",
+ "snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
+ "snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
+ "udpport","inet4_only","inet6_only",
+ "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
+
+ atexit.register(atexit_handler)
+
+ snmp_define_defaults ()
+
+ options=process_input(device_opt)
+
+ # Emulate enable/disable functionality
+ if (options.has_key("-o")):
+ options["-o"]=options["-o"].lower()
+
+ if (options["-o"]=="enable"):
+ options["-o"]="on"
+ if (options["-o"]=="disable"):
+ options["-o"]="off"
+ else:
+ options["-o"]="off"
+
+ options = check_input(device_opt, options)
+
+ docs = { }
+ docs["shortdesc"] = "Fence agent for IF MIB"
+ docs["longdesc"] = "fence_ifmib is an I/O Fencing agent \
+which can be used with any SNMP IF-MIB capable device. \
+\n.P\n\
+It was written with managed ethernet switches in mind, in order to \
+fence iSCSI SAN connections. However, there are many devices that \
+support the IF-MIB interface. The agent uses IF-MIB::ifAdminStatus \
+to control the state of an interface."
+ docs["vendorurl"] = "http://www.ietf.org/wg/concluded/ifmib.html"
+ show_docs(options, docs)
+
+ # Operate the fencing device
+ result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
+
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()
13 years, 7 months
cluster: RHEL56 - fence_cisco_ucs: Fix path to fencing library
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: c73d85e25c4f198534ec7a8585f42b89ba0675ae
Parent: 66638a76b2b41acbb1f43cb5f4d500f803949678
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Sep 27 09:35:04 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Sep 27 09:59:01 2010 +0200
fence_cisco_ucs: Fix path to fencing library
Resolves: rhbz#579859
---
fence/agents/cisco_ucs/fence_cisco_ucs.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py
index 07375b3..702f05b 100755
--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py
@@ -2,7 +2,7 @@
import sys, re, pexpect, socket
import pycurl, StringIO
-sys.path.append("@FENCEAGENTSLIBDIR@")
+sys.path.append("/usr/lib/fence")
from fencing import *
#BEGIN_VERSION_GENERATION
13 years, 7 months
cluster: RHEL56 - fence_rhevm: Fix build system
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 66638a76b2b41acbb1f43cb5f4d500f803949678
Parent: f2f0db60469f811f26123eec87cfc09d9002f35d
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Sep 27 09:33:30 2010 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Sep 27 09:58:52 2010 +0200
fence_rhevm: Fix build system
Resolves: #rhbz#595385
---
fence/agents/Makefile | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/fence/agents/Makefile b/fence/agents/Makefile
index 0055288..3c16fc5 100644
--- a/fence/agents/Makefile
+++ b/fence/agents/Makefile
@@ -34,6 +34,7 @@ all:
${MAKE} -C manual all
${MAKE} -C mcdata all
# ${MAKE} -C rackswitch all
+ ${MAKE} -C rhevm all
${MAKE} -C rps10 all
${MAKE} -C rsa all
${MAKE} -C rsb all
@@ -67,6 +68,7 @@ install: all
${MAKE} -C manual install
${MAKE} -C mcdata install
# ${MAKE} -C rackswitch install
+ ${MAKE} -C rhevm install
${MAKE} -C rps10 install
${MAKE} -C rsa install
${MAKE} -C rsb install
@@ -100,6 +102,7 @@ clean:
${MAKE} -C manual clean
${MAKE} -C mcdata clean
# ${MAKE} -C rackswitch clean
+ ${MAKE} -C rhevm clean
${MAKE} -C rps10 clean
${MAKE} -C rsa clean
${MAKE} -C rsb clean
13 years, 7 months