pkg://GFS-6.0.0-7.src.rpm:1084957/gfs-build.tar.gz
info downloads
Makefile 0100600 0007452 0007452 00000004064 10052451420 012050 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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.
##
###############################################################################
###############################################################################
SHELL=/bin/bash
LINUX_DIR=linux
ifeq ($(hugemem),y)
LINUX_DIR=linuxhugemem
endif
ifeq ($(smp),y)
LINUX_DIR=linuxsmp
endif
include checkout_date.mk
all:
cd ${LINUX_DIR} && ${MAKE} modules
cd bedrock && ${MAKE} all
cd GFS && ${MAKE} all
cd gnbd && ${MAKE} all
cd gulm && ${MAKE} all
clean:
rm -f *~
cd ${LINUX_DIR} && ${MAKE} clean
cd GFS && ${MAKE} clean
cd gnbd && ${MAKE} clean
cd gulm && ${MAKE} clean
cd bedrock && ${MAKE} clean
install:
cd ${LINUX_DIR} && ${MAKE} modules_install
cd GFS && ${MAKE} install
cd gnbd && ${MAKE} install
cd gulm && ${MAKE} install
cd bedrock && ${MAKE} install
deinstall uninstall:
cd GFS && ${MAKE} uninstall
cd gnbd && ${MAKE} uninstall
cd gulm && ${MAKE} uninstall
cd bedrock && ${MAKE} uninstall
distclean:
rm -rf linux*
cd GFS && ${MAKE} distclean
cd gnbd && ${MAKE} distclean
cd gulm && ${MAKE} distclean
cd bedrock && ${MAKE} distclean
srpm:
echo "CO_DATE=\"`date`\"" > checkout_date.mk
make srpm_real
srpm_real:
echo "Checking out GFS"
cvs export -r RHEL3 -D ${CO_DATE} GFS
echo "Checking out gnbd"
cvs export -r RHEL3 -D ${CO_DATE} gnbd
echo "Checking out gulm"
cvs export -r RHEL3 -D ${CO_DATE} gulm
echo "Checking out bedrock"
cvs export -r RHEL3 -D ${CO_DATE} bedrock
echo "Building src rpm"
tar -zcvf gfs-build.tar.gz Makefile checkout_date.mk bedrock GFS gulm gnbd
rpmbuild -bs gfs-build.spec --define "_sourcedir `pwd`" --define "_srcrpmdir `pwd`"
rm -rf *gz *~ #*#
srpm_clean:
rm -rf *gz GFS gnbd gulm bedrock *~ *rpm #*#
checkout_date.mk 0100600 0007452 0007452 00000000047 10073325702 013546 0 ustar alewis alewis CO_DATE="Thu Jul 8 15:17:06 CDT 2004"
bedrock/ 0040700 0007452 0007452 00000000000 10073325704 012026 5 ustar alewis alewis bedrock/init.d/ 0040700 0007452 0007452 00000000000 10073325704 013213 5 ustar alewis alewis bedrock/init.d/ccsd 0100700 0007452 0007452 00000004511 10054411614 014046 0 ustar alewis alewis #!/bin/bash
#
# ccsd start/stop ccsd
#
# chkconfig: 345 20 80
# description: Starts and stops the ccsd specified by $CCS_ARCHIVE \
# in /etc/sysconfig/gfs
#
#
### BEGIN INIT INFO
# Provides:
### END INIT INFO
. /etc/init.d/functions
[ -f /etc/sysconfig/gfs ] && . /etc/sysconfig/gfs
# attempt to autodetect a CCA device. If a single CCA device is found
# CCS_ARCHIVE will be set to that device and return 0. If more than
# one device is found, autodetect() will not set CCS_ARCHIVE and will
# return 1
# XXX: Should this also scan for cca files in /etc/sysconfig?
autodetect()
{
ccadevs=$( pool_tool -s | awk '/CCA device /{print $1}' | xargs -r )
[ -z "$ccadevs" ] && return 1
match=""
for dev in $ccadevs
do
if [ -z "$match" ]
then
match=$dev
else
return 1
fi
done
CCS_ARCHIVE=$match
return 0
}
get_clustername()
{
clustername=$(ccs_read string cluster.ccs cluster/name 2>/dev/null)
}
start()
{
echo -n "Starting ccsd:"
# verify that CCS_ARCHIVE is defineddd
if [ -z "$CCS_ARCHIVE" ]
then
if ! autodetect
then
echo "CCS_ARCHIVE not specified in /etc/sysconfig/gfs" >&2
return 1
fi
fi
# determine if ccsd needs the '-f' '-d' or '-s' option
if [ -b "$CCS_ARCHIVE" ]
then
ccs_type="-d"
elif [ -f "$CCS_ARCHIVE" ]
then
ccs_type="-f"
else
ccs_type="-s"
fi
# start ccsd
if ccsd $ccs_type $CCS_ARCHIVE &>/dev/null
then
# verify that ccsd has infact started
for sec in $(seq 1 10)
do
sleep 1
if get_clustername
then
echo -n " clustername = $clustername"
success
echo
return 0
fi
done
fi
failure
echo
return 1
}
stop()
{
echo -n "Stopping ccsd:"
for sec in $(seq 1 10)
do
if get_clustername
then
# get the pid of ccsd from /var/run/sistina/ccsd.pid
# and break if the file is not there
[ -r /var/run/sistina/ccsd.pid ] || break
pid=$(cat /var/run/sistina/ccsd.pid )
kill $pid
sleep 1
else
success
echo
return 0
fi
done
failure
echo
return 1
}
rtrn=1
# See how we were called.
case "$1" in
start)
start
rtrn=$?
[ $rtrn = 0 ] && touch /var/lock/subsys/ccsd
;;
stop)
stop
rtrn=$?
[ $rtrn = 0 ] && rm -f /var/lock/subsys/ccsd
;;
restart)
$0 stop
$0 start
rtrn=$?
;;
status)
status ccsd
rtrn=0
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
;;
esac
exit $rtrn
bedrock/init.d/Makefile 0100600 0007452 0007452 00000001643 10041575211 014651 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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.
##
###############################################################################
###############################################################################
TARGET= ccsd
UNINSTALL=${top_srcdir}/scripts/uninstall.pl
top_srcdir=..
include ${top_srcdir}/make/defines.mk
copytobin:
clean:
install:
install -d ${DESTDIR}/etc/init.d
install ${TARGET} ${DESTDIR}/etc/init.d
uninstall:
${UNINSTALL} ${TARGET} ${DESTDIR}/etc/init.d
bedrock/fence/ 0040700 0007452 0007452 00000000000 10073325704 013106 5 ustar alewis alewis bedrock/fence/agents/ 0040700 0007452 0007452 00000000000 10073325704 014367 5 ustar alewis alewis bedrock/fence/agents/egenera/ 0040700 0007452 0007452 00000000000 10073325704 015775 5 ustar alewis alewis bedrock/fence/agents/egenera/Makefile 0100600 0007452 0007452 00000002607 10046014736 017441 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_egenera.pl
TARGET= fence_egenera
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
fence_egenera: fence_egenera.pl
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/egenera/fence_egenera.pl 0100700 0007452 0007452 00000017017 10055145621 021104 0 ustar alewis alewis #!/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 IPC::Open3;
# 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="";
$SISTINA_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
$esh="/opt/panmgr/bin/esh";
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -c <string> cserver\n";
print " -h help\n";
print " -l <string> lpan\n";
print " -o <string> Action: reboot (default), off, on or status\n";
print " -p <string> pserver\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 "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
if (@ARGV > 0)
{
getopts("c:hl:o:p:qV") || fail_usage ;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
$cserv = $opt_c if defined $opt_c;
$lpan = $opt_l if defined $opt_l;
$pserv = $opt_p if defined $opt_p;
$action = $opt_o if defined $opt_o;
}
else
{
get_options_stdin();
}
$action = "reboot" unless defined $action;
fail "failed: no cserver defined" unless defined $cserv;
fail "failed: no lpan defined" unless defined $lpan;
fail "failed: no pserver defined" unless defined $pserv;
fail "failed: unrecognised action: $action"
unless $action =~ /^(off|on|reboot|status|pblade)$/i;
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;
}
elsif ($name eq "agent" )
{
# DO NOTHING -- this field is used by fenced
}
elsif ($name eq "cserver" )
{
$cserv = $val;
}
elsif ($name eq "lpan" )
{
$lpan = $val;
}
elsif ($name eq "pserver" )
{
$pserv = $val;
}
elsif ($name eq "action" )
{
$action = $val;
}
elsif ($name eq "esh" )
{
$esh = $val;
}
# FIXME should we do more error checking?
# Excess name/vals will be eaten for now
else
{
fail "parse error: unknown option \"$opt\"";
}
}
}
# _pserver_query_field -- query the state of the pBlade or Status field
# and return it's value in $_.
# Return 0 on success, or non-zero on error
sub _pserver_query_field
{
my ($field,$junk) = @_;
if ($field ne "pBlade" && $field ne "Status")
{
$_="Error _pserver_query_field: unknown field of type '$field'";
return 1;
}
my $val;
my $cmd = "ssh $cserv $esh pserver $lpan/$pserv";
my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
or die "error open3(): $!";
while(<RDR>)
{
chomp;
my $line = $_;
my @fields = split /\s+/,$line;
if ($fields[0] eq "Error:")
{
$val=$line;
print "Debug ERROR: $val\n";
last;
}
elsif ($fields[0] eq $pserv)
{
if ( $field eq "Status" )
{
$val=$fields[1];
}
elsif ($field eq "pBlade" )
{
# grrr... Status can be "Shutting down"
if ($fields[1] ne "Shutting")
{
$val=$fields[3];
}
else
{
$val=$fields[4];
}
}
}
}
close WTR;
close RDR;
waitpid $pid,0;
my $rtrn = $?>>8;
$_=$val if defined $val;
return $rtrn;
}
# return the pBlade of an lpan/pserver in $_.
# Return 0 on success or non=zero on error
sub pserver_pblade
{
_pserver_query_field "pBlade";
}
# return the Status of an lpan/pserver in $_.
# Return 0 on success or non=zero on error
sub pserver_status
{
_pserver_query_field "Status";
}
# boot an lpan/pserver.
# Return 0 if the status is "Booted" or "Booting" or non-zero on failure.
# Continue checking the value until the status is "Boot" or "Booting" or
# until a timeout of 120 seconds has been reached.
sub pserver_boot
{
my $rtrn=1;
# It seems it can take a while for a pBlade to
# boot sometimes. We shall wait for 120 seconds
# before giving up on a node returning failure
for (my $trys=0; $trys<120; $trys++)
{
last if (pserver_status != 0);
my $status = $_;
if ( $status eq "Booted" || $status eq "Booting")
{
$rtrn=0;
last;
}
if(pserver_pblade)
{
die "error getting pBlade info";
}
# Is there any harm in sending this command multiple times?
my $cmd = "ssh $cserv $esh blade -b $_";
my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
or die "error open3(): $!";
close WTR;
close RDR;
waitpid $pid,0;
$rtrn = $?>>8;
sleep 1;
}
return $rtrn;
}
# boot an lpan/pserver.
# Return 0 if the status is "Shutdown" or non-zero on failure.
# Continue checking the value until the status is "Shutdown" or
# until a timeout of 20 seconds has been reached.
sub pserver_shutdown
{
my $rtrn=1;
for (my $trys=0; $trys<20; $trys++)
{
last if (pserver_status != 0);
my $status = $_;
if (/^Shutdown/)
{
$rtrn=0;
last;
}
elsif (/^Shutting/)
{
# We are already in the process of shutting down.
# do I need to do anything here?
# We'll just wait for now
}
else
{
if (pserver_pblade)
{
die "error getting pBlade info: $_";
}
# is there any harm in sending this command multiple
# times?
my $cmd = "ssh $cserv $esh blade -s $_";
my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
or die "error open3(): $!";
close WTR;
close RDR;
waitpid $pid,0;
$rtrn = $?>>8;
}
sleep 1;
}
return $rtrn;
}
$_=$action;
if (/^status$/i)
{
if (pserver_status==0)
{
print "$lpan/$pserv is $_\n" unless defined $opt_q;
exit 0;
}
else
{
fail "failed to get status of $lpan/$pserv: $_";
}
}
elsif (/^pblade$/i)
{
if (pserver_pblade==0)
{
print "$lpan/$pserv is $_\n" unless defined $opt_q;
exit 0;
}
else
{
fail "failed to get pblade of $lpan/$pserv: $_";
}
}
elsif (/^off$/i)
{
if (pserver_shutdown==0)
{
print "success: $lpan/$pserv has been shutdown\n"
unless defined $opt_q;
exit 0;
}
else
{
fail "failed to shutdown $lpan/$pserv";
}
}
elsif (/^on$/i)
{
if (pserver_boot==0)
{
print "success: $lpan/$pserv has been turned on\n"
unless defined $opt_q;
exit 0;
}
else
{
fail "failed to turn on $lpan/$pserv";
}
}
elsif (/^reboot$/i)
{
if (pserver_shutdown!=0)
{
fail "failed to shutdown $lpan/$pserv";
}
if (pserver_boot==0)
{
print "success: $lpan/$pserv has been rebooted\n"
unless defined $opt_q;
exit 0;
}
else
{
fail "failed to turn on $lpan/$pserv";
}
}
else
{
die "unknown action: $action";
}
bedrock/fence/agents/cpint/ 0040700 0007452 0007452 00000000000 10073325704 015504 5 ustar alewis alewis bedrock/fence/agents/cpint/fence_cpint.pl 0100700 0007452 0007452 00000007022 10015057456 020321 0 ustar alewis alewis #!/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 = $_;
$comm_prog = "hcp";
# 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="";
$SISTINA_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -h usage\n";
print " -u <string> userid of the virtual machine to fence\n";
print " -q quiet mode\n";
print " -V Version\n";
exit 0;
}
sub fail
{
($msg)=@_;
print "failed: " . $msg . "\n" unless defined $opt_q;
exit 1;
}
sub fail_usage
{
($msg)=@_q;
print stderr $msg."\n" if $msg;
print stderr "Please use '-h' for usage.\n";
exit 1;
}
sub version
{
print "$pname $GFS_RELEASE_NAME $BUILD_DATE\n";
print "$SISTINA_COPYRIGHT\n" if ( $SISTINA_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 or stomithd
elsif ($name eq "agent" ) { }
# FIXME -- depricated. use "userid" and "password" instead.
elsif ($name eq "fm" )
{
(my $dummy,$opt_u,$opt_p) = split /\s+/,$val;
print STDERR "Depricated \"fm\" entry detected. refer to man page.\n";
}
# FIXME -- depreicated residue of old fencing system
elsif ($name eq "name" ) { }
elsif ($name eq "userid" )
{
$opt_u = $val;
}
else
{
print stderr "parse error: unknown option \"$opt\"\n";
#> exit 2;
}
}
}
if (@ARGV > 0){
getopts("hqu:V") || fail_usage;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
fail_usage "No '-u' flag specified." unless defined $opt_u;
} else {
get_options_stdin();
fail "no userid" unless defined $opt_u;
}
$ret_val = system("$comm_prog send cp $opt_u logoff > /dev/null 2>&1") >> 8;
fail "$comm_prog failed ($ret_val)" unless ($ret_val == 0 || $ret_val == 45);
$ret_val = system("$comm_prog send cp $opt_u > /dev/null 2>&1") >> 8;
fail "$userid isn't logged off. $comm_prog return ($ret_val)" unless ($ret_val == 45);
print "success: booted userid $opt_u\n" unless defined $opt_q;
exit 0;
bedrock/fence/agents/cpint/Makefile 0100600 0007452 0007452 00000002572 10015057456 017153 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_cpint.pl
TARGET= fence_cpint
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
$(TARGET): $(SOURCE)
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/zvm/ 0040700 0007452 0007452 00000000000 10073325704 015203 5 ustar alewis alewis bedrock/fence/agents/zvm/Makefile 0100600 0007452 0007452 00000002566 10015057457 016656 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_zvm.pl
TARGET= fence_zvm
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
$(TARGET): $(SOURCE)
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/zvm/fence_zvm.pl 0100700 0007452 0007452 00000016124 10015057457 017523 0 ustar alewis alewis #!/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 IPC::Open2;
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
# 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="";
$SISTINA_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
$comm_program = s3270;
$debug = 0;
$max_loops = 10;
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -a <ip> IP address or hostname of the physical s390\n";
print " -h usage\n";
print " -u <string> userid of the virtual machine to fence\n";
print " -p <string> Password\n";
print " -q quiet mode\n";
print " -r <devnum> ipl device <devnum>\n";
print " -V Version\n";
exit 0;
}
sub fail
{
($msg)=@_;
print "failed: " . $msg . "\n" unless defined $opt_q;
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 "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
sub do_read
{
my($line);
$line = <READ_H>;
if ($debug)
{
my($l) = ($line);
$l =~ s/\n//;
print "read: $l\n";
}
return $line;
}
sub do_write
{
my($line) = @_;
if ($debug)
{
my($l) = ($line);
$l =~ s/\n//;
print "write: $l\n";
}
print WRITE_H $line;
}
sub look_for
{
my ($text, $found);
$found = 0;
($text) = @_;
&do_write("ascii\n");
while(1){
$_ = &do_read;
last unless (/^data:/);
$found = 1 if (/$text/);
}
$_ = &do_read;
fail "error while looking for string '$text'." unless (/ok/);
return $found;
}
sub in_cp_read_state
{
my ($prev);
$_ = "";
&do_write("ascii\n");
while (1){
$prev = $_;
$_ = &do_read;
last unless (/^data:/);
}
$_ = &do_read;
fail "error while looking for machine state." unless (/ok/);
return 1 if ($prev =~ /CP READ/i);
return 0;
}
sub send_wait
{
&do_write("wait\n");
$_ = &do_read;
$_ = &do_read;
if (/ok/){
return 1;
}
return 0;
}
sub send_string
{
my ($cmd);
($cmd) = @_;
&do_write('string "' . $cmd . '\n"' . "\n");
$_ = &do_read;
$_ = &do_read;
if (/ok/){
return send_wait;
}
return 0;
}
sub send_cmd
{
my ($cmd);
($cmd) = @_;
&do_write($cmd . "\n");
$_ = &do_read;
$_ = &do_read;
if (/ok/){
return send_wait;
}
return 0;
}
sub wait_for_response
{
my ($pass, $failure, $msg, $found, $loops);
$loops = 0;
$found = 0;
($pass, $failure, $msg) = @_;
while (1){
$loops = $loops + 1;
fail "timed out waiting for '$pass'" if ($loops > $max_loops);
&do_write("ascii\n");
while(1){
$_ = &do_read;
chomp;
last unless (/^data:/);
$found = 1 if (/$pass/);
if ($failure){
fail("$msg '$_'") if (/$failure/);
}
}
$_ = &do_read;
fail "wait for response failed '$_'" unless (/ok/);
last if $found;
sleep 1;
}
return 0;
}
sub check_response
{
($action) = @_;
$_ = &do_read;
$_ = &do_read;
fail "$action failed." unless (/ok/);
}
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 or stomithd
elsif ($name eq "agent" ) { }
# FIXME -- depricated. use "userid" and "password" instead.
elsif ($name eq "fm" )
{
(my $dummy,$opt_u,$opt_p) = split /\s+/,$val;
print STDERR "Depricated \"fm\" entry detected. refer to man page.\n";
}
elsif ($name eq "ipaddr" )
{
$opt_a = $val;
}
elsif ($name eq "ipl" )
{
$opt_r = $val;
}
# FIXME -- depreicated residue of old fencing system
elsif ($name eq "name" ) { }
elsif ($name eq "passwd" )
{
$opt_p = $val;
}
elsif ($name eq "userid" )
{
$opt_u = $val;
}
else
{
print stderr "parse error: unknown option \"$opt\"\n";
#> exit 2;
}
}
}
if (@ARGV > 0){
getopts("a:hp:qr:u:V") || fail_usage;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
fail_usage "No '-a' flag specified." unless defined $opt_a;
fail_usage "No '-p' flag specified." unless defined $opt_p;
fail_usage "No '-u' flag specified." unless defined $opt_u;
} else {
get_options_stdin();
fail "no IP address" unless defined $opt_a;
fail "no userid" unless defined $opt_u;
fail "no password" unless defined $opt_p;
}
$pid = open2(READ_H, WRITE_H, "$comm_program 2>&1");
&do_write("connect $opt_a\n");
$_ = &do_read;
unless (/^U U U/){
chomp;
fail "communication program failed with '$_'.";
}
$_ = &do_read;
fail "couldn't connect to $opt_a." unless(/ok/);
send_wait or fail "couldn't start 3270 session on $opt_a.";
send_cmd "enter" or fail "couldn't reach logon prompt.";
look_for "Enter one of the following commands:" or fail "doesn't look like a login prompt\n";
send_string "logon $opt_u $opt_p norun here" or fail "couldn't login";
send_cmd "clear" or fail "couldn't send the clear command.";
send_string "#cp query userid";
wait_for_response(uc($opt_u),"Enter one of the following commands:", "logon failed");
fail "machine not in CP READ state" unless in_cp_read_state;
if (defined $opt_r){
send_string "ipl $opt_r" or fail "couldn't send reboot command";
} else {
send_string "stop" or fail "couldn't send stop command\n";
}
fail "command failed" if look_for "Unknown CP command";
if (defined $opt_r && !in_cp_read_state){
send_string "#cp disc";
} else {
&do_write("disconnect\n");
}
&do_write("quit\n");
print "success: booted userid $opt_u\n" unless defined $opt_q;
exit 0;
bedrock/fence/agents/rackswitch/ 0040700 0007452 0007452 00000000000 10073325704 016531 5 ustar alewis alewis bedrock/fence/agents/rackswitch/do_rack.h 0100600 0007452 0007452 00000000735 10012362641 020302 0 ustar alewis alewis
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/net.h>
#include <linux/fs.h>
#include <linux/socket.h>
/*#include <linux/in.h>*/
#include <arpa/inet.h>
#include <signal.h>
#include "fence_release.cf"
#include "copyright.cf"
#define SA struct sockaddr
#define MAXBUF 1200
#define DID_SUCCESS 0
#define DID_FAILURE 1
bedrock/fence/agents/rackswitch/Makefile 0100600 0007452 0007452 00000002105 10015057456 020170 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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.
##
###############################################################################
###############################################################################
TARGET= fence_rackswitch
SOURCE= do_rack.c
top_srcdir=../../..
ccs_libdir=${top_srcdir}/ccs/lib
INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: ${TARGET}
fence_rackswitch: ${SOURCE:.c=.o}
${CC} ${CFLAGS} ${LDFLAGS} ${SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@
copytobin: all
cp ${TARGET} ${top_srcdir}/bin
clean:
rm -f *.o ${TARGET} *~
bedrock/fence/agents/rackswitch/do_rack.c 0100600 0007452 0007452 00000043275 10015057456 020313 0 ustar alewis alewis /******************************************************************************
*******************************************************************************
**
** 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.
**
*******************************************************************************
******************************************************************************/
#include "do_rack.h"
char *pname = "fence_rack";
int quiet_flag = 0;
int verbose_flag = 0;
int debug_flag = 0;
char ipaddr[256];
char portnumber[256];
char username[256];
char password[256];
char arg[256];
char name[256];
char readbuf[MAXBUF];
char writebuf[MAXBUF];
int sock;
char op_login = 0x7e; /* 126*/
char op_action = 0x66; /* 102 */
char ack_login = 0x7D; /* 125 */
char action_idle = 0x00;
char action_reset = 0x01;
char action_off = 0x02;
char action_offon = 0x03;
char configuration_request = 0x5b; /* 91 */
char config_reply = 0x5c; /* 92 */
char config_general = 0x01;
char config_section1 = 0x02;
char config_section2 = 0x03;
char config_section3 = 0x04;
char message_status = 0x65; /* 101 */
char login_deny = 0xFF;
int time_out = 60;
void ignore_message_status(void);
int wait_frame(char);
/*
* scan input, waiting for a given frame
*/
int wait_frame(char frame_id)
{
int read_more = 1;
int success = 0;
int n;
char target = frame_id;
if(debug_flag){printf("%s: Looking for frametype 0x%.2x\n",name,target);}
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(debug_flag){printf("%s: Found frametype 0x%.2x\n",name,readbuf[0]);}
if(readbuf[0] == target){
read_more = 0;
success = 1;
}
else{
if(readbuf[0] == message_status){
ignore_message_status();
read_more = 1;
}
else{
if(debug_flag){printf("%s: Got unexpected frame from switch\n",name);}
read_more = 0;
success = 0;
}
}
}
return(success);
}
void ignore_message_status(void)
{
int n,i;
int read_more = 1;
int number_of_temp;
int number_of_config_mobo;
if(debug_flag){printf("%s: Ignoring message-status\n",name);}
read_more=1;
while(read_more){
n = read(sock,readbuf,1); /* status */
if(n == 1)
read_more = 0;
}
read_more = 1;
while(read_more){ /* Date & time */
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
read_more = 1;
number_of_temp = 0;
n = read(sock,readbuf,1); /* Temprature Input count */
number_of_temp = (int)readbuf[0];
for(i=0;i<number_of_temp;i++){
read_more = 1;
while(read_more){
n = read(sock,readbuf,1); /* Temprature input ID */
n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */
n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */
n = read(sock,readbuf,1); /* Temprature Alarm */
}
}
number_of_config_mobo = 0;
for(i=4;i>0;i--){
read_more = 1;
while(read_more){
n=read(sock,readbuf,1);
if(n == 1){
read_more = 0;
number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
}
}
}
for(i=0;i<number_of_config_mobo;i++){
n = read(sock,readbuf,4); /* Motherboard ID */
n = read(sock,readbuf,1); /* Motherboard status */
}
}
void print_usage(void)
{
printf("Usage:\n");
printf("\n");
printf("%s [options]\n"
"\n"
"Options:\n"
" -h usage\n"
" -a <ip> IP address for RackSwitch\n"
" -n <dec num> Physical plug number on RackSwitch\n"
" -l <string> Username\n"
" -p <string> Password\n"
" -v Verbose\n"
" -q Quiet\n"
" -V Version information\n", pname);
}
void get_options(int argc, char **argv)
{
int c;
char *value;
if (argc > 1){
/*
* Command line input
*/
while ((c = getopt(argc, argv, "ha:n:l:p:vqVd")) != -1)
{
switch(c)
{
case 'h':
print_usage();
exit(DID_SUCCESS);
case 'a':
strncpy(ipaddr,optarg,254);
break;
case 'n':
strncpy(portnumber,optarg,254);
break;
case 'l':
strncpy(username,optarg,254);
break;
case 'p':
strncpy(password,optarg,254);
break;
case 'v':
verbose_flag = 1;
break;
case 'q':
quiet_flag = 1;
break;
case 'd':
debug_flag = 1;
break;
case 'V':
printf("%s %s (built %s %s)\n", pname, FENCE_RELEASE_NAME,
__DATE__, __TIME__);
printf("%s\n", SISTINA_COPYRIGHT);
exit(DID_SUCCESS);
break;
case ':':
case '?':
fprintf(stderr, "Please use '-h' for usage.\n");
exit(DID_FAILURE);
break;
default:
fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c);
exit(DID_FAILURE);
break;
}
}
strcpy(name, pname);
}
else{
errno = 0;
while(fgets(arg, 256, stdin) != NULL){
if( (value = strchr(arg, '\n')) == NULL){
fprintf(stderr, "line too long: '%s'\n", arg);
exit(DID_FAILURE);
}
*value = 0;
if( (value = strchr(arg, '=')) == NULL){
fprintf(stderr, "invalid input: '%s'\n", arg);
exit(DID_FAILURE);
}
*value = 0;
value++;
/* bahfuck. "agent" is not passed to us anyway
* if (!strcmp(arg, "agent")){
* strcpy(name, value);
* pname = name;
*}
*/
strcpy(name, pname);
if (!strcmp(arg, "ipaddr"))
strcpy(ipaddr, value);
if (!strcmp(arg, "portnumber"))
strcpy(portnumber, value);
if (!strcmp(arg, "username"))
strcpy(username, value);
if (!strcmp(arg, "password"))
strcpy(password, value);
}
errno = 0;
}
}
static void sig_alarm(int sig)
{
if(!quiet_flag){
fprintf(stderr,"failed: %s: Timeout, nothing happened for %d seconds.\n", pname, time_out);
fprintf(stderr,"failed: %s: Perhaps you should inspect the RackSwitch at %s\n",pname,ipaddr);
}
exit(DID_FAILURE);
}
int main(int argc, char **argv)
{
int n,i,j,pnumb;
int ip_portnumber = 1025;
char boardnum = 0x00;
/*char number_of_action = 0x01;*/
int number_of_config_mobo = 0;
int number_of_section_config_mobo = 0;
int exit_status= 0;
int success_off = 0;
/*int success_on = 0;*/
int read_more = 1;
struct sockaddr_in rackaddr;
/*char mobo_enabled = 0x01;*/
/*char mobo_default_status = 0x00;*/
/*char mobo_output_status = 0x00;*/
int this_mobo = 0;
/*int mobo_id = 0;*/
/*int our_mobo = 0;*/
int number_of_temp = 0;
memset(arg, 0, 256);
memset(name, 0, 256);
memset(ipaddr, 0, 256);
memset(portnumber,0,256);
memset(username,0,256);
memset(password,0,256);
/*
* Ensure that we always get out of the fencing agent
* even if things get fucked up and we get no replies
*/
signal(SIGALRM, &sig_alarm);
alarm(time_out);
get_options(argc, argv);
if(name[0] == '\0')
{
if(!quiet_flag)
fprintf(stderr,"failed: no name for this program\n");
exit(DID_FAILURE);
}
if(ipaddr[0] == '\0')
{
if(!quiet_flag)
fprintf(stderr,"failed: %s, no IP address given\n",name);
exit(DID_FAILURE);
}
if (portnumber[0] == '\0')
{
if(!quiet_flag)
fprintf(stderr,"failed: %s, no portnumber given\n",name);
exit(DID_FAILURE);
}
if (username[0] == '\0')
{
if(!quiet_flag)
fprintf(stderr,"failed: %s, no username given\n",name);
exit(DID_FAILURE);
}
if (password[0] == '\0')
{
if(!quiet_flag)
fprintf(stderr,"failed: %s, no password given\n",name);
exit(DID_FAILURE);
}
/*
* Port number given to us as a string.
* Does the number make sense?
*/
pnumb = 0;
for(n=0;(portnumber[n]!='\0');n++){
if((portnumber[n] < 48) || (portnumber[n] > 57)){
if(!quiet_flag)
fprintf(stderr,"failed: %s, invalid port number\n",name);
exit(1);
}
pnumb = ((pnumb * 10) + ((int)(portnumber[n]) - 48));
}
/*
* what section of the rack is this port part of?
* The switch has 4 "subsections", called boardnum here
*/
if((pnumb > 0) && (pnumb < 47))
boardnum = 0x02;
if((pnumb > 46) && (pnumb < 94))
boardnum = 0x03;
if((pnumb > 93) && (pnumb < 137))
boardnum = 0x04;
if((pnumb < 1) || (pnumb> 136)){
boardnum = 0x00;
if(!quiet_flag)
fprintf(stderr,"failed: %s, the portnumber given is not in the range [1 - 136]\n",name);
exit(DID_FAILURE);
}
/*********************************************
***
*** set up TCP connection to the rackswitch
***
********************************************/
if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0){
fprintf(stderr,"failed: %s: socket error, %s\n",name,strerror(errno));
exit(DID_FAILURE);
}
bzero(&rackaddr,sizeof(rackaddr));
rackaddr.sin_family = AF_INET;
rackaddr.sin_port = htons(ip_portnumber);
if(inet_pton(AF_INET,ipaddr,&rackaddr.sin_addr) <= 0){
fprintf(stderr,"failed: %s: inet_pton error\n", name);
}
if(connect(sock,(SA *) &rackaddr,sizeof(rackaddr)) < 0){
fprintf(stderr,"failed: %s: connect error to %s, %s\n", name, ipaddr,strerror(errno));
exit(DID_FAILURE);
}
/**********************************************
***
*** Send Login Frame
***
*********************************************/
writebuf[0] = op_login;
for(n=0;n<=(strlen(username));n++){
writebuf[sizeof(char)+n] = username[n];
}
writebuf[sizeof(char)+(strlen(username))+1] ='\n';
for(n=0;n<=(strlen(password))+1;n++){
writebuf[sizeof(char)+strlen(username)+1+n] = password[n];
}
writebuf[sizeof(char)+(strlen(username))+1+(strlen(password))+1] ='\n';
write(sock,writebuf,sizeof(char)+strlen(username)+strlen(password)+2);
/********************************************
***
*** Read Login Reply
***
*******************************************/
if(wait_frame(ack_login)){
n=read(sock,readbuf,1);
if(readbuf[0] == login_deny){
if(!quiet_flag){fprintf(stderr,"failed: %s: Not able to log into RackSwitch\n",name);}
exit(DID_FAILURE);
}
else{
if(verbose_flag){printf("%s: Successfully logged into RackSwitch\n",name);}
}
}
/********************************************
***
*** Send Configuration Request Message
***
*******************************************/
writebuf[0] = configuration_request;
writebuf[1] = config_general;
write(sock,writebuf,2*(sizeof(char)));
/********************************************
***
*** Read General Configuration Message
***
*******************************************/
if(wait_frame(config_reply)){
n = read(sock,readbuf,1);
if(readbuf[0] == config_general){
/* Configuration Status, one byte */
n = read(sock,readbuf,1);
/* Switch description, string */
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
/* Serial number, string */
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
/* Version number, string */
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
/* number of configured temps, 1 byte */
number_of_temp = 0;
n = read(sock,readbuf,1);
number_of_temp = (int)readbuf[0];
for(i=0;i<number_of_temp;i++){
/* Temprature description, string */
read_more = 1;
while(read_more){
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
}
n = read(sock,readbuf,1); /* Temprature input ID */
n = read(sock,readbuf,1); /* Tempratue unit */
n = read(sock,readbuf,8); /* Temprature HI alarm */
n = read(sock,readbuf,8); /* Temprature LO alarm */
n = read(sock,readbuf,1); /* Temprature HI Alarm */
n = read(sock,readbuf,1); /* Temprature LO Alarm */
n = read(sock,readbuf,1); /* Temprature Alarm email */
}
/* Number of configured motherboards */
number_of_config_mobo = 0;
for(i=4;i>0;i--){
read_more = 1;
while(read_more){
n=read(sock,readbuf,1);
if(n == 1){
read_more = 0;
number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
}
}
}
/*
* make sure the motherboard we are asked to turn of is configured
*/
if(pnumb > number_of_config_mobo){
if(!quiet_flag){
fprintf(stderr,"failed: %s asked to reboot port %d, but there are only %d ports configured\n",name,pnumb,number_of_config_mobo);
exit(DID_FAILURE);
}
}
n = read(sock,readbuf,1); /* email alarms */
n = read(sock,readbuf,4); /* email alarm delay */
/* email addresses, string */
read_more = 1;
while(read_more){
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
n = read(sock,readbuf,4); /* reset action duration */
n = read(sock,readbuf,4); /* power off action duration */
n = read(sock,readbuf,4); /* power on action duration */
}
else{
if(debug_flag){fprintf(stderr,"failed: %s: Did not receive general configuration frame when requested\n",name);}
exit(DID_FAILURE);
}
}
else{
if(debug_flag){fprintf(stderr,"failed: %s: Did not receive configuration frame when requested\n",name);}
exit(DID_FAILURE);
}
/******************************************
***
*** Send Action packet to switch
*** Off/On port <portnum>
***
*****************************************/
memset(writebuf,0,sizeof(writebuf));
writebuf[0] = op_action;
writebuf[1] = (char)(number_of_config_mobo >> 24);
writebuf[2] = (char)(number_of_config_mobo >> 16);
writebuf[3] = (char)(number_of_config_mobo >> 8);
writebuf[4] = (char)(number_of_config_mobo);
writebuf[(pnumb*5)+0] = (char)(pnumb >> 24);
writebuf[(pnumb*5)+1] = (char)(pnumb >> 16);
writebuf[(pnumb*5)+2] = (char)(pnumb >> 8);
writebuf[(pnumb*5)+3] = (char)(pnumb);
writebuf[(pnumb*5)+4] = action_offon;
write(sock,writebuf,(pnumb*5)+5);
if(verbose_flag){
printf("%s: sending action frame to switch:\n",name);
for(i=0;i<(pnumb*5)+5;i++)
printf("0x%.2x ",writebuf[i]);
printf("\n");
}
/******************************************
***
*** Send Configuration Request packet to switch
***
*****************************************/
memset(writebuf,0,sizeof(writebuf));
writebuf[0] = configuration_request;
writebuf[1] = boardnum;
write(sock,writebuf,2*(sizeof(char)));
if(verbose_flag){
printf("%s: sending Request Configuration Frame from switch:\n",name);
printf("0x%.2x 0x%.2x\n",writebuf[0],writebuf[1]);
}
/*******************************************
***
*** Read Switch Status Message
***
******************************************/
while(success_off == 0){
if(debug_flag){
printf("%s: Status does not indicate port %d being rebooted. Looking again\n",name,pnumb);}
if(wait_frame(message_status)){
n = read(sock,readbuf,1); /* Rackswitch status */
read_more = 1;
while(read_more){ /* Date & time */
n = read(sock,readbuf,1);
if(readbuf[0] == '\0'){
read_more = 0;
}
else{
read_more = 1;
}
}
number_of_temp = 0;
n = read(sock,readbuf,1);
number_of_temp = readbuf[0];
for(i=0;i<number_of_temp;i++){
read_more = 1;
while(read_more){
n = read(sock,readbuf,1); /* Temprature input ID */
n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */
n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */
n = read(sock,readbuf,1); /* Temprature Alarm */
}
}
/* number of motherboards, 4 byte */
number_of_section_config_mobo = 0;
for(i=4;i>0;i--){
read_more = 1;
while(read_more){
n=read(sock,readbuf,1);
if(n == 1){
read_more = 0;
number_of_section_config_mobo = number_of_section_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
}
}
}
for(i=0;i<number_of_section_config_mobo;i++){
this_mobo = 0;
for(j=4;j>0;j--){
read_more = 1;
while(read_more){
n=read(sock,readbuf,1);
if(n == 1){
read_more = 0;
this_mobo = this_mobo + (int)(readbuf[0]<<(8*(j-1)));
}
}
}
if(debug_flag){printf("%s: port %d is currently ",name,this_mobo);}
n = read(sock,readbuf,1); /* Motherboard status */
if(debug_flag){printf("0x%.2x\n",readbuf[0]);}
if((pnumb == this_mobo) && ((readbuf[0] == 0x02)||(readbuf[0] == 0x03))){
success_off = 1;
if(verbose_flag){printf("%s: Status shows port %d being rebooted\n",name,this_mobo);}
}
} /* end number_of_section_mobo loop */
if(!success_off){
if(verbose_flag){printf("%s: Status shows port %d NOT being rebooted, asking for status again\n",name,pnumb);}
}
}
else{
if(debug_flag){fprintf(stderr,"%s: Did not receive Switch Status Message\n",name);}
exit(DID_FAILURE);
}
}
if(success_off){
if(!quiet_flag){
printf("success: %s: successfully told RackSwitch to reboot port %d\n",name,pnumb);
}
alarm(0);
exit_status = DID_SUCCESS;
}
return(exit_status);
}
/* And that is it. There is no more.
* Maybe there should be more?
* Or maybe not?
* But there is no more
*/
bedrock/fence/agents/vixel/ 0040700 0007452 0007452 00000000000 10073325704 015516 5 ustar alewis alewis bedrock/fence/agents/vixel/fence_vixel.pl 0100700 0007452 0007452 00000010453 10015057457 020350 0 ustar alewis alewis #!/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::Telnet ();
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
# 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="";
$SISTINA_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
sub usage
{
print "Usage:\n\n";
print "$pname [options]\n\n";
print "Options:\n";
print " -a <ip> IP address or hostname of switch\n";
print " -h Usage\n";
print " -n <num> Port number to disable\n";
print " -p <string> Password for login\n";
print " -V version\n\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 "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
if (@ARGV > 0) {
getopts("a:hn:p:V") || 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 '-p' flag specified." unless defined $opt_p;
fail_usage "No '-n' flag specified." unless defined $opt_n;
} else {
get_options_stdin();
fail "failed: no IP address for the Vixel." unless defined $opt_a;
fail "failed: no password provided." unless defined $opt_p;
fail "failed: no port number specified." unless defined $opt_n;
}
#
# Set up and log in
#
$t = new Net::Telnet;
$t->open($opt_a);
$t->waitfor('/assword:/');
$t->print($opt_p);
($out, $match)= $t->waitfor(Match => '/\>/', Match => '/assword:/');
if ($match =~ /assword:/) {
fail "failed: incorrect password\n";
} elsif ( $match !~ />/ ) {
fail "failed: timed out waiting for prompt\n";
}
$t->print("config");
$t->waitfor('/\(config\)\>/');
$t->print("zone");
$t->waitfor('/\(config\/zone\)\>/');
#
# Do the command
#
$cmd = "config $opt_n \"\"";
$t->print($cmd);
$t->waitfor('/\(config\/zone\)\>/');
$t->print("apply");
($text, $match) = $t->waitfor('/\>/');
if ($text !~ /[Oo][Kk]/) {
fail "failed: error from switch\n";
}
$t->print("exit");
print "success: zonedisable $opt_n\n";
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("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 "name" ) { }
elsif ($name eq "passwd" )
{
$opt_p = $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";
#> exit 2;
}
}
}
bedrock/fence/agents/vixel/Makefile 0100600 0007452 0007452 00000002572 10015057457 017166 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_vixel.pl
TARGET= fence_vixel
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
$(TARGET): $(SOURCE)
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/rib/ 0040700 0007452 0007452 00000000000 10073325704 015143 5 ustar alewis alewis bedrock/fence/agents/rib/fence_rib.pl 0100700 0007452 0007452 00000035205 10015057457 017424 0 ustar alewis alewis #!/usr/bin/perl
$|=1;
use IO::Socket;
use IO::Select;
use IPC::Open3;
use Getopt::Std;
# 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="v5.2.0 \"Lrrr\"";
$SISTINA_COPYRIGHT=("Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
$SISTINA_COPYRIGHT=("Copyright (C) 2004 Red Hat, Inc. All rights reserved.
$SISTINA_COPYRIGHT=("
$SISTINA_COPYRIGHT=("This copyrighted material is made available to anyone wishing to use,
$SISTINA_COPYRIGHT=("modify, copy, or redistribute it subject to the terms and conditions
$SISTINA_COPYRIGHT=("of the GNU General Public License v.2.
$BUILD_DATE="(built Fri Jul 25 06:10:15 PDT 2003)";
#END_VERSION_GENERATION
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
################################################################################
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -a <ip> IP address or hostname of RILOE card\n";
print " -h usage\n";
print " -l <name> Login name\n";
print " -n <num> local port for stunnel (default 8888)\n";
print " -o <string> Action: reboot (default), off, on or status\n";
print " -p <string> Login password\n";
print " -q quiet mode\n";
print " -V version\n";
print " -v verbose\n";
exit 0;
}
sub diedie
{
if (defined $stunnel_pid)
{
kill 9, $stunnel_pid;
waitpid $stunnel_pid,0;
}
print STDERR "@_";
exit 1;
}
sub sendsock
{
my ($sock, $msg, $junk) = @_;
print $sock $msg;
if ($verbose)
{
chomp $msg;
print "SEND: $msg\n"
}
}
# This will slurp up all the data on the socket. If nothing is available after 10 seconds, the
# function will return all the data that has been read so far. If $mode is defined, the function
# will return immediately following the initial packet terminator "<END_RIBCL/>" The RILOE has
# a nasty timing issue. The header packet must be sent, a reply recived and then the command
# packet needs to be sent before the riloe times out the command. This takes on the order
# of seconds. If the command times out, the connection through stunnel is broken.
#
# FIXME -- this feels like a kludge. There has to be a better way to make this work.
#
sub receive_response
{
my ($sock,$mode) = @_;
$mode = 0 unless defined $mode;
my $count=0;
my $buffer = "";
my $selector = IO::Select->new();
$selector->add($sock);
while (@ready = $selector->can_read(10))
{
my $buf;
my $rd = sysread $sock, $buf, 512;
diedie "sysread error: $!\n" if (!defined $rd);
print "READ:($rd,$mode) $buf\n" if ($verbose);
last unless ($rd);
$buffer="$buffer$buf";
last if ( $buffer =~ /<END_RIBCL\/>$/mi && $mode==1 );
}
return $buffer;
}
sub chld_reaper
{
if (waitpid($stunnel_pid, WNOHANG))
{
my $status = $?;
print "REAPER: status $status on $stunnel_pid\n" if ($verbose);
if ($status != 0 )
{
print STDERR "stunnel error\n" ;
close_stunnel();
exit 1;
}
}
}
sub pipe_reaper
{
print STDERR "pipe error\n" ;
kill 9, $stunnel_pid;
waitpid($stunnel_pid, WNOHANG);
close_stunnel();
exit 1;
}
sub open_stunnel()
{
if ( $stunnel_version == 3 )
{
# create an SSL tunnel. By default, stunnel will background itself.
# specying -f keeps it in the forground and makes it easy to identify and kill
# later.
$cmd = "stunnel -d localhost:$localport -r $hostname -c -f ";
}
elsif ( $stunnel_version == 4 )
{
$cmd = "stunnel /dev/stdin";
}
else
{
die "unkown stunnel version\n";
}
print "cmd: $cmd\n" if ($verbose);
$stunnel_pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd);
$SIG{CHLD} = \&chld_reaper;
$SIG{PIPE} = \&pipe_reaper;
if ( $stunnel_version == 4 )
{
print CMD_IN "foreground = yes\n";
print CMD_IN "client = yes\n";
print CMD_IN "debug = 7\n";
print CMD_IN "[443]\n";
print CMD_IN "accept = $localport\n";
print CMD_IN "connect = $hostname\n";
close CMD_IN;
}
# give stunnel some time to startup.
sleep 2;
}
sub close_stunnel()
{
# clean up stunnel
$SIG{CHLD}= 'DEFAULT';
kill 9, "$stunnel_pid";
$selector = IO::Select->new();
$selector->add(*CMD_ERR, *CMD_OUT);
while (@ready = $selector->can_read)
{
foreach $fh (@ready)
{
if (fileno($fh) == fileno(CMD_ERR))
{
# FIXME -- icky blocking read
my $line = <CMD_ERR>;
print "stunnel STDERR: $line" if ($verbose && defined $line);
}
else
{
# FIXME -- icky blocking read
my $line = <CMD_OUT>;
print "stunnel STDOUT: $line" if ($verbose && defined $line);
}
$selector->remove($fh) if eof($fh);
}
}
close(CMD_IN);
close(CMD_OUT);
close(CMD_ERR);
waitpid $stunnel_pid,0;
}
sub open_socket()
{
printf "Creating an ssl stunnel from localhost:$localport to $hostname\n" if $verbose;
$socket = IO::Socket::INET->new(PeerAddr => 'localhost',
PeerPort => $localport,
Proto => 'tcp',
Type => SOCK_STREAM)
or diedie "Can't connect to localhost:$localport: $@\n";
return $socket;
}
sub power_off
{
my $response = set_power_state ("N");
my @response = split /\n/,$response;
foreach my $line (@response)
{
if ($line =~ /MESSAGE='(.*)'/)
{
my $msg = $1;
if ($msg eq "No error")
{
$agent_status = 0;
next;
}
elsif ($msg eq "Host power is already OFF.")
{
$agent_status = 0;
print "warning: $msg\n" unless defined $quiet;
}
else
{
$agent_status = 1;
print STDERR "error: $msg\n";
}
}
}
return $agent_status;
}
sub power_on
{
my $response = set_power_state ("Y");
my @response = split /\n/,$response;
foreach my $line (@response)
{
if ($line =~ /MESSAGE='(.*)'/)
{
my $msg = $1;
if ($msg eq "No error")
{
$agent_status = 0;
next;
}
elsif ($msg eq "Host power is already ON.")
{
$agent_status = 0;
print "warning: $msg\n" unless defined $quiet;
}
else
{
$agent_status = 1;
print STDERR "error: $msg\n";
}
}
}
return $agent_status;
}
sub power_status
{
my $response = get_power_state ();
my @response = split /\n/,$response;
foreach my $line (@response)
{
if ($line =~ /MESSAGE='(.*)'/)
{
my $msg = $1;
if ($msg eq "No error")
{
$agent_status = 0;
next;
}
else
{
$agent_status = 1;
print STDERR "error: $msg\n";
}
}
elsif ($line =~ /HOST POWER=\"(.*)\"/)
{
$agent_status = 0;
print "power is $1\n";
}
}
return $agent_status;
}
sub set_power_state
{
my $state = shift;
my $response = "";
if (!defined $state || ( $state ne "Y" && $state ne "N") )
{
diedie "illegal state\n";
}
$socket = open_socket;
sendsock $socket, "<?xml version=\"1.0\"?>\r\n";
$response = receive_response($socket,1);
#> printf "Closed because no more answers\n" if ($verbose && !defined($answer));
print "Sending power-o".(($state eq "Y")?"n":"ff")."\n" if ($verbose);
sendsock $socket, "<RIBCL VERSION=\"1.2\">\n";
sendsock $socket, " <LOGIN USER_LOGIN = \"$username\" PASSWORD = \"$passwd\">\n";
sendsock $socket, " <SERVER_INFO MODE = \"write\">\n";
sendsock $socket, " <SET_HOST_POWER HOST_POWER = \"$state\"/>\n";
sendsock $socket, " </SERVER_INFO>\n";
sendsock $socket, " </LOGIN>\n";
sendsock $socket, "</RIBCL>\n";
$response = receive_response($socket);
print "Closing connection\n" if ($verbose);
close($socket);
return $response;
}
sub get_power_state
{
my $response = "";
$socket = open_socket;
sendsock $socket, "<?xml version=\"1.0\"?>\r\n";
$response = receive_response($socket,1);
#> printf "Closed because no more answers\n" if ($verbose && !defined($answer));
print "Sending get-status\n" if ($verbose);
sendsock $socket, "<RIBCL VERSION=\"1.2\">\n";
sendsock $socket, " <LOGIN USER_LOGIN = \"$username\" PASSWORD = \"$passwd\">\n";
sendsock $socket, " <SERVER_INFO MODE = \"read\">\n";
sendsock $socket, " <GET_HOST_POWER_STATUS/>\n";
sendsock $socket, " </SERVER_INFO>\n";
sendsock $socket, " </LOGIN>\n";
sendsock $socket, "</RIBCL>\n";
$response = receive_response($socket);
print "Closing connection\n" if ($verbose);
close($socket);
return $response;
}
sub fail
{
($msg)=@_;
print $msg unless defined $quiet;
exit 1;
}
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;
}
elsif ($name eq "action" )
{
$action = $val;
}
# DO NOTHING -- this field is used by fenced or stomithd
elsif ($name eq "agent" ) { }
# FIXME -- depricated. use "hostname" instead.
elsif ($name eq "fm" )
{
(my $dummy,$hostname) = split /\s+/,$val;
print STDERR "Depricated \"fm\" entry detected. refer to man page.\n";
}
elsif ($name eq "hostname" )
{
$hostname = $val;
}
elsif ($name eq "localport" )
{
$localport = $val;
}
elsif ($name eq "login" )
{
$username = $val;
}
# FIXME -- depreicated residue of old fencing system
elsif ($name eq "name" ) { }
elsif ($name eq "passwd" )
{
$passwd = $val;
}
elsif ($name eq "verbose" )
{
$verbose = $val;
}
# FIXME should we do more error checking?
# Excess name/vals will be eaten for now
else
{
fail "parse error: unknown option \"$opt\"\n";
#> exit 2;
}
}
}
sub fail_usage
{
($msg)=@_;
print STDERR $msg if $msg;
print STDERR "Please use '-h' for usage.\n";
exit 1;
}
sub version
{
print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n";
print "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
# get stunnel version. version 3.x of stunnel uses "-V" to print the version
# where as version 4.x uses "-version". We must handle both cases to deal with
# stunnel's brokeness.
#open VER,"stunnel -V |" or
sub get_stunnel_version
{
$stunnel_pid = open3 (*CMD_IN,*CMD_OUT,*CMD_OUT,"stunnel -V") or
die "open3 error: $!";
while (<CMD_OUT>)
{
if ($_ =~ /^stunnel (\d+)\..* on .*/)
{
$stunnel_version = $1;
}
}
close CMD_IN;
close CMD_OUT;
$status = waitpid ($stunnel_pid,0);
if ( $status != 0 )
{
$stunnel_pid = open3 (*CMD_IN,*CMD_OUT,*CMD_OUT,"stunnel -version") or
die "open3 error: $!";
while (<CMD_OUT>)
{
if ($_ =~ /^stunnel (\d+)\..* on .*/)
{
$stunnel_version = $1;
}
}
close CMD_IN;
close CMD_OUT;
$status = waitpid ($stunnel_pid,0);
}
}
################################################################################
# MAIN
# since we might be running tcsh and not a real shell where we can
# divert stderr, we'll just use sh. hopefully it's really bash.
$_ = system "sh -c 'which stunnel > /dev/null 2>&1'";
diedie "stunnel not found\n" if $_;
$stunnel_version = 0;
get_stunnel_version();
$action = "reboot";
if (@ARGV > 0) {
getopts("a:hl:n:o:p:qvV") || fail_usage ;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
fail_usage "No '-a' flag specified." unless defined $opt_a;
$hostname = $opt_a;
fail_usage "No '-l' flag specified." unless defined $opt_l;
$username = $opt_l;
fail_usage "No '-p' flag specified." unless defined $opt_p;
$passwd = $opt_p;
$action = $opt_o if defined $opt_o;
fail_usage "Unrecognised action '$action' for '-o' flag"
unless $action=~ /^(off|on|reboot|status)$/;
$localport = $opt_n if defined $opt_n;
$quiet = 1 if defined $opt_q;
$verbose = 1 if defined $opt_v;
} else {
get_options_stdin();
fail "no host\n" unless defined $hostname;
fail "no login name\n" unless defined $username;
fail "no password\n" unless defined $passwd;
fail "unrecognised action: $action\n"
unless $action=~ /^(off|on|reboot|status)$/;
}
$localport = 8888 unless defined ($localport);
$hostname = "$hostname:443" unless ($hostname =~ /:/);
#> $msg = "<?xml version=\"1.0\"?>\r\n";
$agent_status = -1;
### Setup stunnel from localhost:$localport to $hostname ($hostname can be in hostname:port format)
open_stunnel;
#foreach my $sig (keys %SIG) { $SIG{$sig} = sub {print "*** SIGNAL $sig DETECTED ***\n"}; }
foreach ($action)
{
/on/ and do
{
power_on;
};
/off/ and do
{
power_off;
};
/reboot/ and do
{
power_off;
diedie "unexpected error\n" if ($agent_status < 0);
$agent_status = -1;
power_on;
diedie "unexpected error\n" if ($agent_status < 0);
};
/status/ and do
{
power_status;
};
}
close_stunnel();
# $agent_status should have been set at this point. die to avoid false success.
diedie "unexpected error\n" if ($agent_status < 0);
if ($agent_status == 0)
{
print "success\n" unless defined $quiet;
exit 0
}
else
{
print "failure\n" unless defined $quiet;
exit 1
}
################################################################################
bedrock/fence/agents/rib/Makefile 0100600 0007452 0007452 00000002564 10015057457 016614 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_rib.pl
TARGET= fence_rib
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
fence_rib: $(SOURCE)
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/manual/ 0040700 0007452 0007452 00000000000 10073325704 015644 5 ustar alewis alewis bedrock/fence/agents/manual/Makefile 0100600 0007452 0007452 00000002374 10015057456 017313 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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.
##
###############################################################################
###############################################################################
TARGET= fence_manual fence_ack_manual
fence_manual_SOURCE= manual.c
fence_ack_manual_SOURCE= ack.c
top_srcdir=../../..
INCLUDE= -I${top_srcdir}/include -I${top_srcdir}/config
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: ${TARGET}
fence_manual: ${fence_manual_SOURCE:.c=.o}
${CC} ${CFLAGS} ${LDFLAGS} ${fence_manual_SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@
fence_ack_manual: ${fence_ack_manual_SOURCE:.c=.o}
${CC} ${CFLAGS} ${LDFLAGS} ${fence_ack_manual_SOURCE:.c=.o} ${LOADLIBES} ${LDLIBS} -o $@
copytobin: all
cp ${TARGET} ${top_srcdir}/bin
clean:
rm -f *.o ${TARGET}
bedrock/fence/agents/manual/ack.c 0100600 0007452 0007452 00000006274 10015057456 016560 0 ustar alewis alewis /******************************************************************************
*******************************************************************************
**
** 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.
**
*******************************************************************************
******************************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "fence_release.cf"
#include "copyright.cf"
char *pname = NULL;
int quiet_flag = 0;
int override_flag = 0;
void print_usage(void)
{
printf("Usage:\n");
printf("\n");
printf("%s [options]\n"
"\n"
"Options:\n"
" -h usage\n"
" -O override\n"
" -s <ip> IP address of machine which was manually fenced\n"
" -V Version information\n", pname);
}
int main(int argc, char **argv)
{
int error, fd;
char line[256];
char *ipaddr = NULL;
char response[3];
int c;
memset(line, 0, 256);
pname = argv[0];
while ((c = getopt(argc, argv, "hOs:qV")) != -1)
{
switch(c)
{
case 'h':
print_usage();
exit(0);
case 'O':
override_flag = 1;
break;
case 's':
ipaddr = optarg;
break;
case 'q':
quiet_flag = 1;
break;
case 'V':
printf("%s %s (built %s %s)\n", pname, FENCE_RELEASE_NAME,
__DATE__, __TIME__);
printf("%s\n", SISTINA_COPYRIGHT);
exit(0);
break;
case ':':
case '?':
fprintf(stderr, "Please use '-h' for usage.\n");
exit(1);
break;
default:
fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c);
exit(1);
break;
}
}
if (!ipaddr)
{
if(!quiet_flag)
print_usage();
exit(1);
}
if(!override_flag)
{
printf("\nWarning: If the machine with IP address \"%s\" has not been\n"
"manually fenced (i.e. power cycled or disconnected from all\n"
"storage devices) the GFS file system may become corrupted and all\n"
"its data unrecoverable! Please verify that the above IP address\n"
"correctly matches the machine you just rebooted (or disconnected).\n",
ipaddr);
printf("\nAre you certain you want to continue? [yN] ");
scanf("%s", response);
if (tolower(response[0] != 'y'))
{
printf("%s operation canceled.\n", pname);
exit(1);
}
}
fd = open("/tmp/fence_manual.fifo", O_WRONLY | O_NONBLOCK);
if (fd < 0)
{
perror("can't open /tmp/fence_manual.fifo");
exit(1);
}
sprintf(line, "meatware ok\n");
error = write(fd, line, 256);
if (error < 0)
{
perror("can't write to /tmp/fence_manual.fifo");
exit(1);
}
if(!quiet_flag)
printf("done\n");
return(0);
}
bedrock/fence/agents/manual/manual.c 0100600 0007452 0007452 00000011705 10015057456 017272 0 ustar alewis alewis /******************************************************************************
*******************************************************************************
**
** 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.
**
*******************************************************************************
******************************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <syslog.h>
#include "fence_release.cf"
#include "copyright.cf"
char *pname = NULL;
char args[256];
char name[256];
char ipaddr[256];
char path[256];
char fname[256];
int quiet_flag = 0;
void print_usage(void)
{
printf("Usage:\n");
printf("\n");
printf("%s [options]\n"
"\n"
"Options:\n"
" -h usage\n"
" -q quiet\n"
" -s <ip> IP address of machine to fence\n"
" -V Version\n",pname);
}
void get_options(int argc, char **argv)
{
int c, rv;
char *curr;
char *rest;
char *value;
if (argc > 1)
{
while ((c = getopt(argc, argv, "hs:p:qV")) != -1)
{
switch(c)
{
case 'h':
print_usage();
exit(0);
case 's':
strcpy(ipaddr, optarg);
break;
case 'q':
quiet_flag = 1;
break;
case 'p':
strcpy(path, optarg);
break;
case 'V':
printf("%s %s (built %s %s)\n", pname, FENCE_RELEASE_NAME,
__DATE__, __TIME__);
printf("%s\n", SISTINA_COPYRIGHT);
exit(0);
break;
case ':':
case '?':
fprintf(stderr, "Please use '-h' for usage.\n");
exit(1);
break;
default:
fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c);
exit(1);
break;
}
}
}
else
{
if ((rv = read(0, args, 255)) < 0)
{
if(!quiet_flag)
printf("failed: no input\n");
exit(1);
}
curr = args;
while ((rest = strchr(curr, '\n')) != NULL){
*rest = 0;
rest++;
if ((value = strchr(curr, '=')) == NULL){
printf("failed: invalid input\n");
exit(1);
}
*value = 0;
value++;
if (!strcmp(curr, "agent")){
strcpy(name, value);
pname = name;
}
if (!strcmp(curr, "ipaddr"))
strcpy(ipaddr, value);
curr = rest;
}
}
if (!strlen(path))
strcpy(path, "tmp");
}
int main(int argc, char **argv)
{
int error, fd, lfd;
char line[256], *mw, *ok;
struct flock lock;
openlog("fence_manual", 0, LOG_DAEMON);
memset(args, 0, 256);
memset(name, 0, 256);
memset(ipaddr, 0, 256);
memset(path, 0, 256);
memset(fname, 0, 256);
pname = argv[0];
get_options(argc, argv);
if (ipaddr[0] == 0)
{
if(!quiet_flag)
printf("failed: %s no IP addr\n", name);
exit(1);
}
/* Serialize multiple fence_manual's by locking a lock file */
memset(fname, 0, 256);
sprintf(fname, "/%s/fence_manual.lock", path);
lfd = open(fname, O_WRONLY | O_CREAT,
(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
if (lfd < 0)
{
if (!quiet_flag)
printf("failed: %s %s lockfile open error\n", pname, ipaddr);
exit(1);
}
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
error = fcntl(lfd, F_SETLKW, &lock);
if (error < 0)
{
if (!quiet_flag)
printf("failed: fcntl errno %d\n", errno);
exit(1);
}
/* It's our turn to use the fifo */
syslog(LOG_CRIT, "Node %s requires hard reset. Run \"fence_ack_manual -s %s\""
" after power cycling the machine.\n",
ipaddr, ipaddr);
umask(0);
memset(fname, 0, 256);
sprintf(fname, "/%s/fence_manual.fifo", path);
error = mkfifo(fname, (S_IRUSR | S_IWUSR));
if (error && errno != EEXIST)
{
if (!quiet_flag)
printf("failed: %s mkfifo error\n", pname);
exit(1);
}
fd = open(fname, O_RDONLY);
if (fd < 0)
{
if (!quiet_flag)
printf("failed: %s %s open error\n", pname, ipaddr);
exit(1);
}
/* Get result from ack_manual */
memset(line, 0, 256);
error = read(fd, line, 256);
if (error < 0)
{
if(!quiet_flag)
printf("failed: %s %s read error\n", pname, ipaddr);
exit(1);
}
mw = strstr(line, "meatware");
ok = strstr(line, "ok");
if (!mw || !ok)
{
if(!quiet_flag)
printf("failed: %s %s improper message\n", pname, ipaddr);
exit(1);
}
if(!quiet_flag)
printf("success: %s %s\n", pname, ipaddr);
unlink("/tmp/fence_manual.fifo");
return 0;
}
bedrock/fence/agents/baytech/ 0040700 0007452 0007452 00000000000 10073325704 016006 5 ustar alewis alewis bedrock/fence/agents/baytech/Makefile 0100600 0007452 0007452 00000002566 10015057456 017460 0 ustar alewis alewis ###############################################################################
###############################################################################
##
## 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_XXX.pl
TARGET= fence_XXX
top_srcdir=../../..
include ${top_srcdir}/make/defines.mk
include ${top_srcdir}/make/flags.mk
all: $(TARGET)
$(TARGET): $(SOURCE)
: > $(TARGET)
awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/fence_release.cf perl FENCE_RELEASE_NAME >> $(TARGET)
${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf perl SISTINA_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)
bedrock/fence/agents/baytech/fence_baytech.pl 0100700 0007452 0007452 00000035156 10015057456 021136 0 ustar alewis alewis #!/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.
##
###############################################################################
###############################################################################
# This fencing agent is written for the Baytech RPC27-20nc in conjunction with
# a Cyclades terminal server. The Cyclades TS exports the RPC's serial port
# via a Telnet interface. Other interfaces, such as SSH, are possible.
# However, this script relys upon the assumption that Telnet is used. Future
# features to this agent would allow the agent to work with a mulitude of
# different communication protocols such as Telnet, SSH or Kermit.
#
# The other assumption that is made is that Outlet names do not end in space.
# The name "Foo" and "Foo " are identical when the RPC prints them with
# the status command.
use Net::Telnet;
use Getopt::Std;
# 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="";
$SISTINA_COPYRIGHT="";
$BUILD_DATE="";
#END_VERSION_GENERATION
# Get the program name from $0 and strip directory names
$_=$0;
s/.*\///;
my $pname = $_;
sub rpc_error
{
if (defined $error_message && $error_message ne "")
{
chomp $error_message;
die "$error_message\n";
}
else
{
die "read timed-out\n"
}
}
sub usage
{
print "Usage:\n";
print "\n";
print "$pname [options]\n";
print "\n";
print "Options:\n";
print " -a host host to connect to\n";
print " -D debugging output\n";
print " -h usage\n";
print " -l string user name\n";
print " -o string action: On,Off,Status or Reboot (default)\n";
print " -n string outlet name\n";
print " -p string password\n";
print " -V version\n";
exit 0;
}
sub fail
{
($msg)=@_;
print $msg."\n" unless defined $quiet;
$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 "$SISTINA_COPYRIGHT\n" if ( $SISTINA_COPYRIGHT );
exit 0;
}
# Get operating paramters, either with getopts or from STDIN
sub get_options
{
$action = "Reboot";
if (@ARGV > 0) {
getopts("n:l:p:o:a:VhD") || fail_usage ;
usage if defined $opt_h;
version if defined $opt_V;
fail_usage "Unkown parameter." if (@ARGV > 0);
} else {
get_options_stdin();
}
fail "failed: must specify hostname" unless defined $opt_a;
$host=$opt_a;
$port=23 unless ($opt_a =~ /:/);
$action = $opt_o if defined $opt_o;
fail "failed: unrecognised action: $action"
unless $action=~ /^(Off|On|Reboot|status)$/i;
fail "failed: no outletname" unless defined $opt_n;
$outlet = $opt_n;
$debug=$opt_D if defined $opt_D;
$quiet=$opt_q if defined $opt_q;
$user=$opt_l if defined $opt_l;
$passwd=$opt_p if defined $opt_p;
if(defined $passwd && !defined $user)
{
fail "failed: password given without username";
}
}
# Get options from STDIN
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" ) { }
elsif ($name eq "host" )
{
$opt_a = $val;
}
elsif ($name eq "login" )
{
$opt_l = $val;
}
elsif ($name eq "passwd" )
{
$opt_p = $val;
}
elsif ($name eq "action" )
{
$opt_o = $val;
}
elsif ($name eq "outlet" )
{
$opt_n = $val;
}
else
{
fail "parse error: unknown option \"$opt\"";
}
}
}
# Get a bunch of lines. The newlines must terminate complete lines.
sub getlines
{
my $data=$t->get();
return undef unless defined $data;
my @chars = split //,$data;
my @lines;
my $line="";
for (my $i=0;$i<@chars;$i++)
{
$line = $line.$chars[$i];
next unless $chars[$i] eq "\n";
$lines[@lines] = $line;
$line = "";
}
$lines[@lines] = $line unless $line eq "";
return @lines;
}
# Fill the global input buffer of lines read. All lines are terminated with
# a newline. If a line is not terminated, the next call to fill buffer will
# append the last line of the input buffer with the first line that it gets from
# getlines()
sub fill_buffer
{
my @lines = getlines();
return undef unless @lines;
if(@buffer)
{
if ( $buffer[$#buffer]=~/\n/) { }
else
{
$buffer[$#buffer] = $buffer[$#buffer].$lines[0];
shift @lines;
}
}
foreach (@lines)
{
push @buffer,$_;
}
}
#
# ($p_index,@data) = get_match @patterns;
#
# searches the input buffers for the patterns specified by the regeps in
# @patterns, when a match is found, all the lines through the matched
# pattern line are removed from the global input buffer and returned in the
# array @data. The index into @patterns for the matching pattern is also
# returned.
sub get_match
{
my (@patterns) = @_;
$b_index = 0 unless defined $b_index;
fill_buffer() unless defined @buffer;
for(;;)
{
for(my $bi=$b_index; $bi<@buffer; $bi++)
{
for(my $pat=0; $pat<@patterns; $pat++)
{
if($buffer[$bi] =~ /$patterns[$pat]/)
{
$b_index = 0;
my @rtrn = splice(@buffer,0,$bi);
shift @buffer;
if($debug)
{
foreach (@rtrn) { print $_ }
print "$patterns[$pat] ";
}
return ($pat,@rtrn);
}
}
$b_index = $bi;
}
fill_buffer();
}
}
#
# ($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data;
#
# This parses the data @data and searches for an outlet named $outlet.
# The data will be in the form:
#
# Average Power: 0 Watts Apparent Power: 17 VA
#
# True RMS Voltage: 120.0 Volts
#
# True RMS Current: 0.1 Amps Maximum Detected: 0.2 Amps
#
# Internal Temperature: 19.5 C
#
# Outlet Circuit Breaker: Good
#
# 1)...Outlet 1 : Off 2)...Outlet 2 : Off
# 3)...Outlet 3 : On 4)...Outlet 4 : On
# 5)...Outlet 5 : On 6)...Outlet 6 : On
# 7)...Outlet 7 : On 8)...Outlet 8 : On
# 9)...Outlet 9 : On 10)...Outlet 10 : On
# 11)...Outlet 11 : On 12)...Outlet 12 : On
# 13)...Outlet 13 : On 14)...Outlet 14 : On
# 15)...Outlet 15 : On 16)...Outlet 16 : On
# 17)...Outlet 17 : On 18)...Outlet 18 : On
# 19)...Outlet 19 : On 20)...Outlet 20 : On Locked
#
sub parse_status
{
my $outlet = shift;
my @data = @_;
my $bt_num="";
my $bt_name="";
my $bt_state="";
my $bt_locked="";
# Verify that the Outlet name exists
foreach my $line (@data)
{
next unless $line =~ /^[ 12][0-9]\)\.\.\./;
my @entries = split /([ 12][0-9])\)\.\.\./,$line;
foreach my $entry (@entries)
{
next if $entry eq "";
if($entry =~ /^([ 12][0-9])$/)
{
$bt_num = $1;
}
elsif($entry =~ /^(.{15}) : (On|Off)(.*)/)
{
$bt_name = $1;
$bt_state = $2;
$bt_locked = $3;
$_ = $bt_name;
s/\s*$//;
$bt_name = $_;
$_ = $bt_locked;
s/\s*$//;
$bt_locked = $_;
last if ($bt_name eq $outlet);
$bt_name = "";
next;
}
else
{
die "parse error: $entry";
}
}
last if ($bt_name ne "");
}
if ($bt_name eq "")
{
$bt_num=undef;
$bt_name=undef;
$bt_state=undef;
$bt_locked=undef;
}
return ($bt_num,$bt_name,$bt_state,$bt_locked);
}
##########################################################################
#
# Main
get_options;
if (defined $port)
{
$t = new Net::Telnet(Host=>$host, Port=>$port) or
die "Unable to connect to $host:$port: ".($!?$!:$_)."\n";
}
else
{
$t = new Net::Telnet(Host=>$host) or
die "Unable to connect to $host: ".($!?$!:$_)."\n";
}
#> DEBUG $t->dump_log("LOG");
$t->print("\n");
my @patterns;
$prompt_user="^Enter user name:";
$prompt_pass="^Enter Password:";
$prompt_cmd="^RPC-27>";
$prompt_confirm_yn="^.*\\(Y/N\\)\\?";
$patterns[0]=$prompt_user;
$patterns[1]=$prompt_pass;
$patterns[2]=$prompt_cmd;
$patterns[3]=$prompt_confirm_yn;
my $p_index;
my @data;
my $bt_num="";
my $bt_name="";
my $bt_state="";
my $bt_locked="";
my $exit=1;
($p_index,@data) = get_match @patterns;
#
# Set errmode after first get_match. This allows for more descriptive errors
# when handling unexpected error conditions
#
$t->errmode(\&rpc_error);
# At this point, the username is unknown. We'll just
# pass in an empty passwd so that we can get back to the
# login prompt.
#
# FIXME
# If this is the third login failure for this switch, an
# additional newline will need to be made sent. This script
# does not handle that case at this time. This will cause
# a timeout on read and cause this to fail. Rerunning the
# script ought to work though.
if ($patterns[$p_index] eq $prompt_pass)
{
$t->print("\n");
($p_index,@data) = get_match @patterns;
}
# Enter user name:
#
# Depending how the RPC is configured, a user name may not be required.
# We will only deal with usernames if prompted.
#
# If there is no user/passwd given as a parameter, but the switch
# expects one, rather than just fail, we will first try to
# get the switch in a known state
my $warn_user="yes";
my $warn_passwd="yes";
$error_message = "Invalid user/password";
for (my $retrys=0; $patterns[$p_index] eq $prompt_user ; $retrys++)
{
$warn_passwd = "yes";
if(defined $user)
{
$t->print("$user\n");
$warn_user = "no";
}
else
{
$t->print("\n");
}
($p_index,@data) = get_match @patterns;
# Enter Password:
#
# Users don't have to have passwords either. We will only check
# that the user specified a password if we were prompted by the
# RPC.
if ($patterns[$p_index] eq $prompt_pass)
{
if(defined $passwd)
{
$t->print("$passwd\n");
$warn_passwd = "no";
}
else
{
$t->print("\n");
}
($p_index,@data) = get_match @patterns;
}
#
# If a valid user name is given, but not a valid password, we
# will loop forever unless we limit the number of retries
#
# set the user to "" so we stop entering a valid username and
# force the login proccess to fail
#
if ($retrys>2)
{
$user = "";
}
elsif ($retrys>10)
{
die "maximum retry count exceeded\n";
}
}
#
# reset errmode to die()
#
$t->errmode("die");
# all through with the login/passwd. If we see any other prompt it is an
# error.
if ($patterns[$p_index] ne $prompt_cmd)
{
$t->print("\n");
die "bad state: '$patterns[$p_index]'";
}
if (defined $user && ($warn_user eq "yes"))
{
warn "warning: user parameter ignored\n";
}
if (defined $passwd && ($warn_passwd eq "yes"))
{
warn "warning: passwd parameter ignored\n";
}
# We are now logged in, no need for these patterns. We'll strip these
# so that we don't have to keep searching for patterns that shouldn't
# appear.
shift @patterns;
shift @patterns;
# Get the current status of a particular outlet. Explicitly pass
# the status command in case the RPC is not configured to report the
# status on each command completion.
$t->print("status\n");
($p_index,@data) = get_match @patterns;
($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data;
if (!defined $bt_name )
{
# We have problems if there is not outlet named $outlet
print "Outlet \'$outlet\' not found\n";
$exit=1;
}
elsif ($action =~ /status/i)
{
print "Outlet '$bt_name' is $bt_state and is ".
(($bt_locked eq "")?"not ":"")."Locked\n";
$exit=0;
}
elsif ($bt_locked ne "")
{
# Report an error if an outlet is locked since we can't actually
# issue commands on a Locked outlet. This will prevent false
# successes.
print "Outlet '$bt_name' is Locked\n";
$exit=1;
}
elsif (($action =~ /on/i && $bt_state eq "On") ||
($action =~ /off/i && $bt_state eq "Off") )
{
# No need to issue the on/off command since we are already in
# the desired state
print "Outlet '$bt_name' is already $bt_state\n";
$exit=0;
}
elsif ($action =~ /o(n|ff)/i)
{
# On/Off command
$t->print("$action $bt_num\n");
($p_index,@data) = get_match @patterns;
# Confirmation prompting maybe enabled in the switch. If it is,
# we enter 'Y' for yes.
if ($patterns[$p_index] eq $prompt_confirm_yn)
{
$t->print("y\n");
($p_index,@data) = get_match @patterns;
}
$t->print("status\n");
($p_index,@data) = get_match @patterns;
($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet,@data;
if ($bt_state =~ /$action/i)
{
print "success: outlet='$outlet' action='$action'\n";
$exit=0;
}
else
{
print "fail: outlet='$outlet' action='$action'\n";
$exit=1;
}
}
elsif ($action =~ /reboot/i)
{
# Reboot command
$t->print("$action $bt_num\n");
($p_index,@data) = get_match @patterns;
# Confirmation prompting maybe enabled in the switch. If it is,
# we enter 'Y' for yes.
if ($patterns[$p_index] eq $prompt_confirm_yn)
{
$t->print("y\n");
($p_index,@data) = get_match @patterns;
}
# The reboot command is annoying. It reports that the outlet will
# reboot in 9 seconds. Then it has a countdown timer. We first
# look for the "Rebooting... 9" message, then we parse the remaining
# output to verify that it reaches 0 without skipping anything.
my $pass=0;
foreach (@data)
{
chomp;
my $line = $_;
# There is a countdown timer that prints a number, then sleeps a
# second, then prints a backspace and then another number
#
# /^Rebooting\.\.\. 9\b8\b7\b6\b5\b4\b3\b2\b1\b0\b$/
if($line =~/^Rebooting\.\.\..*0[\b]$/)
{
$pass=1;
last;
}
}
if ($pass)
{
print "success: outlet='$outlet' action='$action'\n";
$exit=0;
}
else
{
print "fail: outlet='$outlet' action='$action'\n";
$exit=1;
}
}
else
{
die "bad state";
}
# Clean up. If we don't tell it to logout, then anybody else can log onto
# the serial port and have access to the switch without authentication (when
# enabled)
$t->print("logout\n");
$t->close;
exit $exit;