Hi Martin,

On Mon, Mar 21, 2011 at 03:20:33PM +0100, Martin Dziobek wrote:
> 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. 

Perhaps you can add that to the meta-data then.

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

Not entirely. Of course it's better to have two PDU/UPS, but
power supplies break often.

> $DBG is a remainder from standalone testing -
> feel free to remove it.

I'm not in a position to edit contributions, sorry.

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

It was not variables, but parameters I commented on. The prefix
"device" looks redundant to me, in particular since all
parameters start with it.

Cheers,

Dejan

> 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/
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to