ok, here's the patch for ibm blade fencing agent... qlogic sanbox2, comming up next :) On Mon, 2004-07-26 at 19:08, Lazar Obradovic wrote: > Hello all, > > I'd like to develop my own fencing agents (for IBM BladeCenter and > QLogic SANBox2 switches), but they will require SNMP bindings. > > Is that ok with general development philosophy, since I'd like to > contribude them? net-snmp-5.x.x-based API? -- Lazar Obradovic, System Engineer ----- laza@xxxxxx YUnet International http://www.EUnet.yu Dubrovacka 35/III, 11000 Belgrade Tel: +381 11 3119901; Fax: +381 11 3119901 ----- This e-mail is confidential and intended only for the recipient. Unauthorized distribution, modification or disclosure of its contents is prohibited. If you have received this e-mail in error, please notify the sender by telephone +381 11 3119901. -----
diff -urN old-cluster/fence/agents/Makefile cluster/fence/agents/Makefile --- old-cluster/fence/agents/Makefile 2004-06-24 10:53:11.000000000 +0200 +++ cluster/fence/agents/Makefile 2004-07-30 01:06:44.291020208 +0200 @@ -25,6 +25,7 @@ cd wti && ${MAKE} all cd xcat && ${MAKE} all cd zvm && ${MAKE} all + cd ibmblade && ${MAKE} all copytobin: cd apc && ${MAKE} copytobin @@ -39,6 +40,7 @@ cd wti && ${MAKE} copytobin cd xcat && ${MAKE} copytobin cd zvm && ${MAKE} copytobin + cd ibmblade && ${MAKE} copytobin clean: cd apc && ${MAKE} clean @@ -53,4 +55,5 @@ cd wti && ${MAKE} clean cd xcat && ${MAKE} clean cd zvm && ${MAKE} clean + cd ibmblade && ${MAKE} clean diff -urN old-cluster/fence/agents/ibmblade/Makefile cluster/fence/agents/ibmblade/Makefile --- old-cluster/fence/agents/ibmblade/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ cluster/fence/agents/ibmblade/Makefile 2004-07-30 01:07:42.799125624 +0200 @@ -0,0 +1,37 @@ +############################################################################### +############################################################################### +## +## 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_ibmblade.pl +TARGET= fence_ibmblade + +top_srcdir=../.. +include ${top_srcdir}/make/defines.mk + +all: $(TARGET) + +$(TARGET): $(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 perl 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) + +copytobin: ${TARGET} + cp ${TARGET} ${top_srcdir}/bin/${TARGET} + +clean: + rm -f $(TARGET) + + diff -urN old-cluster/fence/agents/ibmblade/fence_ibmblade.pl cluster/fence/agents/ibmblade/fence_ibmblade.pl --- old-cluster/fence/agents/ibmblade/fence_ibmblade.pl 1970-01-01 01:00:00.000000000 +0100 +++ cluster/fence/agents/ibmblade/fence_ibmblade.pl 2004-08-01 18:43:28.350545072 +0200 @@ -0,0 +1,279 @@ +#!/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; +use Net::SNMP; + +# Get the program name from $0 and strip directory names +$_=$0; +s/.*\///; +my $pname = $_; + +my $sleep_time = 5; +my $snmp_timeout = 10; +$opt_o = "reboot"; + +my $oid_powerState = ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4"; # remoteControlBladePowerState +my $oid_powerChange = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7"; # powerOnOffBlade +my $oid_resetPower = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.8"; # restartBlade + +# 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> IP address or hostname of BladeCenter\n"; + print " -h usage\n"; + print " -c <community> SNMP Community\n"; + print " -n <num> Port number to disable\n"; + print " -o <string> Action: Reboot (default), On or Off\n"; + print " -q quiet mode\n"; + print " -t test power state\n"; + print " -V version\n"; + + exit 0; +} + +sub fail_usage +{ + ($msg)=@_; + print STDERR $msg."\n" if $msg; + print STDERR "Please use '-h' for usage.\n"; + exit 1; +} + +sub fail +{ + ($msg) = @_; + print $msg."\n" unless defined $opt_q; + $t->close if defined $t; + exit 1; +} + +sub version +{ + print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; + print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); + + exit 0; +} + +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 "community" ) + { + $opt_c = $val; + } + # FIXME -- depreicated residue of old fencing system + elsif ($name eq "name" ) { } + + elsif ($name eq "option" ) + { + $opt_o = $val; + } + elsif ($name eq "port" ) + { + $opt_n = $val; + } + + # FIXME should we do more error checking? + # Excess name/vals will be eaten for now + else + { + fail "parse error: unknown option \"$opt\""; + } + } +} + +# ---------------------------- MAIN -------------------------------- + +if (@ARGV > 0) { + getopts("a:hc:n:o:qtV") || 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 "No '-c' flag specified." unless defined $opt_c; + fail_usage "Unrecognised action '$opt_o' for '-o' flag" + unless $opt_o =~ /^(reboot|on|off)$/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 SNMP community" unless defined $opt_c; + fail "failed: unrecognised action: $opt_o" + unless $opt_o =~ /^(reboot|on|off)$/i; +} + +my ($snmpsess, $error) = Net::SNMP->session ( + -hostname => $opt_a, + -version => "snmpv1", + -community => $opt_c, + -timeout => $snmp_timeout); + +if (!defined ($snmpsess)) { + printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $error); + exit 1; +}; + +# first check in what state are we now +my $oid = $oid_powerState . "." . $opt_n; +my $oid_val = ""; +my $result = $snmpsess->get_request ( + -varbindlist => [$oid] +); +if (!defined($result)) { + printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $snmpsess->error); + $snmpsess->close; + exit 1; +} + +if (defined ($opt_t)) { + printf ("$FENCE_RELEASE_NAME STATE: Port %d on %s returned %d\n", $opt_n, $opt_a, $result->{$oid}); + exit 1; +}; + +if ($opt_o =~ /^(reboot|off)$/i) { + if ($result->{$oid} == "0") { + printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s already down.\n", $opt_n, $opt_a); + $snmpsess->close; + exit 1; + }; +} else { + if ($result->{$oid} == "1") { + printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s already up.\n", $opt_n, $opt_a); + $snmpsess->close; + exit 1; + }; +}; + +# excellent, now change the state +if ($opt_o =~ /^reboot$/i) { + # reboot + $oid = $oid_resetPower . "." . $opt_n; + $oid_val = "1"; +} elsif ($opt_o =~ /^on$/i) { + # power on + $oid = $oid_powerChange . "." . $opt_n; + $oid_val = "1"; +} else { + # power down + $oid = $oid_powerChange . "." . $opt_n; + $oid_val = "0"; +}; + +$result = $snmpsess->set_request ( + -varbindlist => [$oid, INTEGER, $oid_val] +); + +if (!defined ($result)) { + # ignore this for now, seems like IBM BladeCenter has a broken SNMPd + # it almost always timeouts +}; + +# now, wait a bit and see if we have done it +sleep($sleep_time); + +$oid = $oid_powerState . "." . $opt_n; + +undef $result; +$result = $snmpsess->get_request ( + -varbindlist => [$oid] +); + +if (!defined($result)) { + # this is a real error + printf("$FENCE_RELEASE_NAME ERROR: %s.\n", $snmpsess->error); + $snmpsess->close; + exit 1; +}; + +if ($opt_o =~ /^(off)$/i) { + if ($result->{$oid} == "1") { + printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s still up.\n", $opt_n, $opt_a); + $snmpsess->close; + exit 1; + }; +} else { + if ($result->{$oid} == "0") { + printf ("$FENCE_RELEASE_NAME ERROR: Port %d on %s still down.\n", $opt_n, $opt_a); + $snmpsess->close; + exit 1; + }; +}; + +# everything's a ok :) +$snmpsess->close; + +printf ("$FENCE_RELEASE_NAME SUCCESS: Port %d on %s changed state to %s\n", $opt_n, $opt_a, $opt_o) unless defined $opt_q; +exit 0; + diff -urN old-cluster/fence/man/Makefile cluster/fence/man/Makefile --- old-cluster/fence/man/Makefile 2004-06-24 10:53:20.000000000 +0200 +++ cluster/fence/man/Makefile 2004-08-01 18:30:42.213015680 +0200 @@ -26,7 +26,8 @@ fence_vixel.8 \ fence_wti.8 \ fence_xcat.8 \ - fence_zvm.8 + fence_zvm.8 \ + fence_ibmblade.8 UNINSTALL=${top_srcdir}/scripts/uninstall.pl diff -urN old-cluster/fence/man/fence_ibmblade.8 cluster/fence/man/fence_ibmblade.8 --- old-cluster/fence/man/fence_ibmblade.8 1970-01-01 01:00:00.000000000 +0100 +++ cluster/fence/man/fence_ibmblade.8 2004-08-01 18:30:02.177102064 +0200 @@ -0,0 +1,103 @@ +.\" 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. + +.tl 'fence_ibmblade(8)''fence_ibmblade(8)' + +\fBNAME\fP +.in +7 +fence_ibmblade - I/O Fencing agent for IBM BladeCenter + +.in +\fBSYNOPSIS\fP +.in +7 +\fBfence_ibmblade -a\fP \fIIPaddress\fR \fB-c\fP \fIcommunity\fR \fB-n\fP \fIport\fR \fB-o\fP \fIaction\fR + +.in +.sp +\fBDESCRIPTION\fP +.in +7 +fence_ibmblade is an I/O Fencing agent which can be used with IBM BladeCenter +chassis. It issues SNMP Set request to BladeCenter chassins, rebooting, powering +up or down the specified Blade Server. +.sp +fence_ibmblade accepts options on the command line as well as from stdin. +fenced sends parameters through stdin when it execs the agent. fence_ibmblade +can be run by itself with command line options which is useful for testing. +.sp +.in +\fBOPTIONS\fP +.in +\fB-a\fP \fIIPaddress\fP +.in +7 +IP address of the BladeCenter chassis. +.sp +.in +\fB-h\fP +.in +7 +Print out a help message describing available options, then exit. +.sp +.in +\fB-c\fP \fIcommunity\fP +.in +7 +SNMP community string to use. +.sp +.in +\fB-n\fP \fIport\fP +.in +7 +The Blade port number to disable. +.in +.sp +\fB-o\fP \fIaction\fP +.in +7 +The action required. Reboot (default), On or off. +.in +.sp +\fB-q\fP +.in +7 +Quiet mode: print only error messages. +.sp +.in +\fB-V\fP +.in +7 +Print out a version message, then exit. +.sp +.in + +.in -7 +\fBSTDIN PARAMETERS\fP +.in + +\fI agent = < param >\fR +.sp +This option is used by fence_node(8) and is ignored by fence_ibmblade. +.sp + +\fIipaddr = < hostname | ip >\fR +.sp +IP address or hostname of the switch. +.sp + +\fI community = < param >\fR +.sp +SNMP community. +.sp + +\fI option = < param >\fR +.sp +The action required. reboot (default), on or off. +.sp + +\fI port = < param >\fR +.sp +The Blade port number to disable. +.sp + + +.in -7 +\fBSEE ALSO\fP +.in +7 +fence(8), fence_node(8)