[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Linux-cluster] iSCSI fence agent?



This is a bit of a hack, but it works with unh-iscsi and iptables.  I took one of the other fencing tools and modified it up to do an 'ssh root iscsitarget  iptables -A INPUT -s a.b.c.d -p all -j REJECT' to disable an iscsi initiator.  The enable command deletes the rule.

You will need to set up ssh to run without passwords.

Matt


On Mon, 2004-10-11 at 21:33, David Teigland wrote:
On Tue, Oct 12, 2004 at 11:08:19AM +0800, Chung Hsien Hu wrote:
> Hi,
> I am trying to setup a storage environment with GFS and iSCSI.
> By using the open community projects of iSCSI initiator and target 
> sides, I could
> access the remote disk via iSCSI without too much problem.
> But which fence agent should I indicate for GFS in the /etc/cluster.conf?

It might be nice for someone to write a fencing agent that would talk to
the iscsi target software.  Until then you can use network power switches
or manual fencing to experiment.

> I got these error on my log.
> 
> lock_dlm: init_fence error -1
> GFS: can't mount proto = lock_dlm, table = innocluster:iscsi45, hostdata =

This is because the fence daemon (fenced) is either not running or has not
started up correctly (maybe it can't connect to ccsd).  You can diagnose
fenced problems by using the debug flag: "fenced -D".
#!/usr/bin/perl

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

use Getopt::Std;

# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;

$opt_o = 'disable';        # Default fence action

# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
# "#END_VERSION_GENERATION"  It is generated by the Makefile

#BEGIN_VERSION_GENERATION
$FENCE_RELEASE_NAME="";
$REDHAT_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION


sub usage
{
    print "Usage:\n";
    print "\n";
    print "$pname [options]\n";
    print "\n";
    print "Options:\n";
    print "  -a <ip>          ISCSI target address\n";
    print "  -h               usage\n";
#    print "  -l <name>        Login name\n";
    print "  -n <num>         IP of node to disable\n";
    print "  -o <string>      Action:  disable (default) or enable\n";
#    print "  -p <string>      Password for login (not used)\n";
    print "  -q               quiet mode\n";
    print "  -V               version\n";

    exit 0;
}

sub fail
{
  ($msg) = @_;
  print $msg."\n" unless defined $opt_q;
  $t->close if defined $t;
  exit 1;
}

sub fail_usage
{
  ($msg)= _;
  print STDERR $msg."\n" if $msg;
  print STDERR "Please use '-h' for usage.\n";
  exit 1;
}

sub version
{
  print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n";
  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );

  exit 0;
}


if (@ARGV > 0)
{
   #getopts("a:hl:n:o:p:qV") || fail_usage ;
   getopts("a:hn:o:qV") || fail_usage ;

   usage if defined $opt_h;
   version if defined $opt_V;

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

   fail_usage "No '-a' flag specified." unless defined $opt_a;
   fail_usage "No '-n' flag specified." unless defined $opt_n;
   fail_usage "Unrecognised action '$opt_o' for '-o' flag"
      unless $opt_o =~ /^(disable|enable)$/i;

}
else
{
   get_options_stdin();

   fail "failed: no IP address" unless defined $opt_a;
   fail "failed: no plug number" unless defined $opt_n;
   #fail "failed: no login name" unless defined $opt_l;
   #fail "failed: no password" unless defined $opt_p;
   fail "failed: unrecognised action: $opt_o"
      unless $opt_o =~ /^(disable|enable)$/i;
}

#
# Set up and log in
#

my $target_address=$opt_a; #The address of the iSCSI target
my $command=$opt_o;	#either enable or disable
my $node=$opt_n;	#the cluster member to lock out

#use ssh to log into remote host and send over iptables commands:

# iptables -D INPUT -s a.b.c.d -p all -j REJECT
# iptables -A INPUT -s a.b.c.d -p all -j REJECT

if ($command eq "enable")
{	#Enable $node on $target_address
	my $cmd="/usr/sbin/iptables -D INPUT -s " . $node . " -p all -j REJECT " .
		" ; echo REMOTESTATUS " . '$?';
	$out=runcommand("ssh",'root@' . $target_address,$cmd);

	if ($out !~ /REMOTESTATUS 0/)
	{
		fail "111Could not $command $node on $target_address\n$cmd\n";
	}
}
elsif ($command eq "disable")
{	#Disable $node on $target_address
	my $cmd="/usr/sbin/iptables -A INPUT -s " . $node . " -p all -j REJECT " .
		" ; echo REMOTESTATUS " . '$?';
	$out=runcommand("ssh",'root@' . $target_address,$cmd);

	if ($out !~ /REMOTESTATUS 0/)
	{
		fail "222Could not $command $node on $target_address\n$cmd\n";
	}
}
else
{	#This should never happen:
	fail "Unknown command: $command\n";
}

print "success: $command $node\n" unless defined $opt_q;
exit 0;

sub runcommand
{
	my $command=$_[0];
	shift @_;
	my @parameters= _;
	my $output;

	open(my $file, "-|", "$command",@parameters) or fail "Could not start $command $!\n";
	while (<$file>)
	{
		$output.=$_;
	}
	close $file;
	return $output;
}

sub get_options_stdin
{
    my $opt;
    my $line = 0;
    while( defined($in = <>) )
    {
        $_ = $in;
        chomp;

	# strip leading and trailing whitespace
        s/^\s*//;
        s/\s*$//;

	# skip comments
        next if /^#/;

        $line+=1;
        $opt=$_;
        next unless $opt;

        ($name,$val)=split /\s*=\s*/, $opt;

        if ( $name eq "" )
        {  
           print STDERR "parse error: illegal name in option $line\n";
           exit 2;
	}
	
        # DO NOTHING -- this field is used by fenced
	elsif ($name eq "agent" ) { } 

	# FIXME -- depricated.  use "port" instead.
        elsif ($name eq "fm" ) 
	{
            (my $dummy,$opt_n) = split /\s+/,$val;
	    print STDERR "Depricated \"fm\" entry detected.  refer to man page.\n";
	}

        elsif ($name eq "ipaddr" ) 
	{
            $opt_a = $val;
        } 
	elsif ($name eq "login" ) 
	{
            $opt_l = $val;
        } 

	# FIXME -- depreicated residue of old fencing system
	elsif ($name eq "name" ) { } 

        elsif ($name eq "option" )
        {
            $opt_o = $val;
        }
	elsif ($name eq "passwd" ) 
	{
            $opt_p = $val;
        } 
	elsif ($name eq "port" ) 
	{
            $opt_n = $val;
        } 
	# elsif ($name eq "test" ) 
	# {
        #    $opt_T = $val;
        # } 

        # FIXME should we do more error checking?  
        # Excess name/vals will be eaten for now
	else 
	{
           fail "parse error: unknown option \"$opt\"";
        }
    }
}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]