Hello Dejan, Thanks for your feedback !
Sure it works : Due to some stonith timing errors I made the two test servers happily stonith'ted each other for hours =8:) It should be emphasized that the netio firmware has to be (at least ?) V 2.33; I had to upgrade both of my new netios first. It does not make sense to use more than one port of a netio device for a single node if you have redundant power supplies in a box, since this would remove redundancy. Each port is fed through the netio's power connector ! To keep redundancy, use two netios on different phases.... $DBG is a remainder from standalone testing - feel free to remove it. For the sake of readability, I didn't ran the "make-an-expert-looking-perl-script-from-boring-straight-source" filter on the code, hence the somewhat explicit names of variables. Cheers, Martin On Mon, 21 Mar 2011 14:39:57 +0100 Dejan Muhamedagic <[email protected]> wrote: > Hi, > > On Mon, Mar 21, 2011 at 11:34:42AM +0100, Martin Dziobek wrote: > > Hello all, > > > > It is time to give back - I would like to submit a stonith plugin written > > in perl > > for the netio230A IP Switch device for review and possible inclusion to > > glue. > > > > See http://www.koukaam.se/showproduct.php?article_id=1504 for info about > > the device. > > Many thanks for the contribution. A few comments below. > > > Thanks, > > Martin > > > > > > #!/usr/bin/perl -w > > # > > # External STONITH module for netio-230A IP switch devices > > # > > # Copyright (c) 2011 Martin Dziobek (dziobek at ihr.uni-stuttgart.de) > > # > > # This program is free software; you can redistribute it and/or modify > > # it under the terms of version 2 of the GNU General Public License as > > # published by the Free Software Foundation. > > # > > # This program is distributed in the hope that it would be useful, but > > # WITHOUT ANY WARRANTY; without even the implied warranty of > > # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > # > > # Further, this software is distributed without any warranty that it is > > # free of the rightful claim of any third person regarding infringement > > # or the like. Any license provided herein, whether implied or > > # otherwise, applies only to this software file. Patent licenses, if > > # any, provided herein do not apply to combinations of this program with > > # other software, or any other product whatsoever. > > # > > # You should have received a copy of the GNU General Public License > > # along with this program; if not, write the Free Software Foundation, > > # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. > > # > > > > # This module talks to netio-230A devices via encrypted telnet interface > > # Tested with firmware revision V 2.33 > > # Settings : All ports manual, watchdog off, port names set to names of > > # the machines to be switched > > What happens if more than one port is used for a single node > (i.e. dual power supply)? > > > use IO::Socket; > > use Digest::MD5 qw(md5 md5_hex md5_base64); > > > > my $EX_OK=0; > > my $EX_FAIL=1; > > my $EX_ERR=3; > > > > # set to 1 for debugging, else 0 > > my $DBG=0; > > You don't need this. Just use ha_log.sh for logging and specify > debug as severity. For instance: > > ha_log.sh debug "..." > > > # stuff from environment > > my $deviceip = '127.0.0.1'; > > my $deviceport = 1234; > > my $devicelogin = 'none'; > > my $devicepass = 'none'; > > > > # handle to netio device > > my $remote; > > # comm line to netio device > > my $line=''; > > # ports on netio device > > my @ports=(); > > > > my $target="none"; > > my $command="none"; > > > > # get command > > $command = $ARGV[0] if ( defined $ARGV[0] ); > > > > # get host to handle on device > > $target = $ARGV[1] if ( defined $ARGV[1] ); > > > > # get stuff from environment > > $deviceip = $ENV{'deviceip'} if ( defined $ENV{'deviceip'} ); > > $deviceport = $ENV{'deviceport'} if ( defined $ENV{'deviceport'} ); > > $devicelogin = $ENV{'devicelogin'} if ( defined $ENV{'devicelogin'} ); > > $devicepass = $ENV{'devicepass'} if ( defined $ENV{'devicepass'} ); > > Why not name parameters without leading "device"? > > > print STDERR "$command $target $deviceip $deviceport $devicelogin > > $devicepass\n" if $DBG; > > > > # handle commands which need no connection to > > # device first > > if ( $command =~ /^getconfignames$/ ) { > > foreach $i ('deviceip','deviceport','devicelogin','devicepass'){ > > print "$i\n"; > > } > > exit($EX_OK); > > } elsif ( $command =~ /^getinfo-devid$/ ) { > > print "netio-230A STONITH device\n"; > > exit($EX_OK); > > } elsif ( $command =~ /^getinfo-devname$/ ) { > > print "netio-230A device\n"; > > exit($EX_OK); > > } elsif ( $command =~ /^getinfo-devdescr$/ ) { > > print "netio-230A IP power switch device\n"; > > exit($EX_OK); > > } elsif ( $command =~ /^getinfo-devurl$/ ) { > > print "http://www.koukaam.se/"; > > exit($EX_OK); > > } elsif ( $command =~ /^getinfo-xml$/ ) { > > $metadata = <<END; > > <parameters> > > <parameter name="deviceip" unique="0" required="0"> > > <content type="string" /> > > <shortdesc lang="en"> > > deviceip > > </shortdesc> > > <longdesc lang="en"> > > IP of netio-230A device > > </longdesc> > > </parameter> > > <parameter name="deviceport" unique="0" required="0"> > > <content type="string" /> > > <shortdesc lang="en"> > > deviceport > > </shortdesc> > > <longdesc lang="en"> > > Port to use on netio-230A device > > </longdesc> > > </parameter> > > <parameter name="devicelogin" unique="0" required="0"> > > <content type="string" /> > > <shortdesc lang="en"> > > devicelogin > > </shortdesc> > > <longdesc lang="en"> > > Username at the netio-230A device > > </longdesc> > > </parameter> > > <parameter name="devicepass" unique="0" required="0"> > > <content type="string" /> > > <shortdesc lang="en"> > > devicepass > > </shortdesc> > > <longdesc lang="en"> > > Password at the netio-230A device > > </longdesc> > > </parameter> > > </parameters> > > END > > print $metadata; > > exit($EX_OK); > > } > > > > # connect to device > > &connect; > > > > if ( $command =~ /^status$/ ) { > > print STDERR "CMD status done\n" if $DBG; > > # if we came here without bailing out, device is ok > > close $remote; > > exit($EX_OK); > > } > > > > # log in and get port info > > &login; > > > > # now handle commands which need a connection to the device > > > > if ( $command =~ /^gethosts$/ ) { > > print STDERR "CMD gethosts\n" if $DBG; > > foreach $n (1..4){ > > print $ports[$n]."\n"; > > } > > &bye; > > } > > > > > > # switch commands > > > > if ( $command =~ /^on$/ ) { > > print STDERR "CMD $target on\n" if $DBG;; > > &switch("ON"); > > } elsif ( $command =~ /^off$/ ) { > > print STDERR "CMD $target off\n" if $DBG; > > &switch("OFF"); > > } elsif ( $command =~ /^reset$/ ) { > > print STDERR "CMD $target reset\n" if $DBG; > > &switch("RESET"); > > } else { > > print STDERR "Command $command: not supported\n" if $DBG; > > $line="Command $command: not supported"; > > &bailout; > > } > > > > # we should not end up here > > close $remote; > > exit($EX_OK); > > > > # ----------------------------------------- > > sub connect{ > > $remote = IO::Socket::INET->new( Proto => "tcp", > > PeerAddr => $deviceip, > > PeerPort => $deviceport, > > ); > > unless ($remote) { > > print STDERR "cannot connect to daemon on $deviceip\n"; > > exit($EX_ERR); > > } > > } > > > > sub login{ > > > > $remote->autoflush(1); > > > > $line = <$remote>; > > my($stat,undef,$key,undef)=split(' ',$line,4); > > &bailout unless ($stat == 100); > > > > my($digest)=md5_hex($devicelogin.$devicepass.$key); > > > > print $remote "clogin $devicelogin $digest\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^250 OK/); > > > > foreach $n (1..4){ > > print $remote "port setup $n\n"; > > $line = <$remote>; > > print STDERR "$line" if $DBG; > > my($stat,$name,undef,undef,$on)=split(' ',$line,5); > > &bailout unless ($stat == 250); > > $name=~s/\"//g; > > $ports[$n]=$name; > > } > > } > > > > sub gethosts{ > > foreach $n (1..4){ > > print $ports[$n]." "; > > } > > } > > > > sub switch{ > > my($stat)=shift; > > foreach $n (1..4){ > > if($target eq $ports[$n]){ > > if($stat eq 'ON'){ > > print $remote "port $n 1\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^250 OK/); > > &bye; > > }elsif($stat eq 'OFF'){ > > print $remote "port $n 0\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^250 OK/); > > &bye; > > }elsif($stat eq 'RESET'){ > > print $remote "port $n 0\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^250 OK/); > > sleep 5; > > print $remote "port $n 1\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^250 OK/); > > &bye; > > } > > } > > } > > $line = "Invalid target\n"; > > &bailout; > > } > > > > sub bailout{ > > # exit with error condition > > print STDERR "Bailout on $deviceip Offending line: $line"; > > close $remote; > > exit($EX_ERR); > > } > > > > sub bye{ > > # exit gracefully > > print $remote "quit\n"; > > $line = <$remote>; > > &bailout unless($line=~m/^110 BYE/); > > close $remote; > > exit($EX_OK); > > } > > Looks good. Does it work? ;-) > > Cheers, > > Dejan > _______________________________________________________ > Linux-HA-Dev: [email protected] > http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev > Home Page: http://linux-ha.org/ _______________________________________________________ Linux-HA-Dev: [email protected] http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev Home Page: http://linux-ha.org/
