358 lines
9.3 KiB
Perl
Executable File
358 lines
9.3 KiB
Perl
Executable File
#!/bin/perl
|
||
#
|
||
# kreset -- reset a machine that we've got a connection via the annex box
|
||
#
|
||
# $Header: /proj/irix6.5.7m/isms/eoe/cmd/ktools/RCS/kreset,v 1.20 1997/12/08 19:29:16 cwilson Exp $
|
||
# $Modified: Mon Dec 8 20:06:54 1997 by cwilson $
|
||
#
|
||
#
|
||
|
||
$REVISION = '$Revision: 1.20 $';
|
||
$REVISION =~ s/.*(\d\.\d+).*/$1/;
|
||
|
||
$KTOOLS_HOME = '/usr/annex'; # here lie dragons
|
||
$KWHO = "$KTOOLS_HOME/kwho"; # don't rely on PATH
|
||
$PORTSFILE = "$KTOOLS_HOME/ktools.map"; # when NIS isn't here.
|
||
|
||
require 'newgetopt.pl';
|
||
require 'chat2.pl';
|
||
|
||
@sync = (255,255,255,255,255,255,255,255,255,255,255,
|
||
255,255,255,255,255,01);
|
||
|
||
%house_table = (
|
||
A, 0x60,
|
||
B, 0xE0,
|
||
C, 0x20,
|
||
D, 0xA0,
|
||
E, 0x10,
|
||
F, 0x90,
|
||
G, 0x50,
|
||
H, 0xD0,
|
||
I, 0x70,
|
||
J, 0xF0,
|
||
K, 0x30,
|
||
L, 0xB0,
|
||
M, 0x00,
|
||
N, 0x80,
|
||
O, 0x40,
|
||
P, 0xC0,
|
||
);
|
||
|
||
# there's some clever way of calculating this...
|
||
%unit_table = (
|
||
1, "0x00, 0x80",
|
||
2, "0x00, 0x40",
|
||
3, "0x00, 0x20",
|
||
4, "0x00, 0x10",
|
||
5, "0x00, 0x08",
|
||
6, "0x00, 0x04",
|
||
7, "0x00, 0x02",
|
||
8, "0x00, 0x01",
|
||
9, "0x80, 0x00",
|
||
10, "0x40, 0x00",
|
||
11, "0x20, 0x00",
|
||
12, "0x10, 0x00",
|
||
13, "0x08, 0x00",
|
||
14, "0x04, 0x00",
|
||
15, "0x02, 0x00",
|
||
16, "0x01, 0x00",
|
||
);
|
||
|
||
|
||
|
||
&Usage if !&NGetOpt( "f", "noyp", "power", "nmi", "off", "on" );
|
||
|
||
# If running under IRIX (nothing else is currently supported, but soon to happen)
|
||
# check to see if we're running yp. Note that as of Irix 6.5 (kudzu) nsd replaces
|
||
# yp.
|
||
#
|
||
$uname = `/bin/uname -sr`;
|
||
|
||
if ($uname =~ /IRIX/) {
|
||
if ($uname =~ /6\.5/) {
|
||
`/etc/chkconfig nsd`;
|
||
} else {
|
||
`/etc/chkconfig yp`;
|
||
}
|
||
}
|
||
|
||
$KWHO .= ' -noyp' if $opt_noyp || $? ;
|
||
$KWHO .= " -m $NIS_MAP" if $opt_m;
|
||
|
||
print (stderr "Sorry, you can't use the ktools with the -noyp option until you copy\n" .
|
||
"the ktools configuration file, ktools.map, to your system.\n"), exit 1 if $opt_noyp && !-e $PORTSFILE;
|
||
|
||
close stdin;
|
||
|
||
&Usage, exit(1) if $#ARGV != 0;
|
||
|
||
@kwho = `$KWHO $ARGV[0]`;
|
||
|
||
if (!(@result2=grep(/$ENV{USER}/, @kwho))) {
|
||
print STDERR "Not connected to any hosts\n";
|
||
if ($opt_f) {
|
||
print STDERR "But since you used the -f option, I'll reset it anyway.\n";
|
||
} else { exit(1); }
|
||
}
|
||
|
||
if (!$opt_f) {
|
||
if (!(@result3=grep(/^$ARGV[0]/, @result2))) {
|
||
print STDERR "Host not found/connected. Connected hosts are:\n";
|
||
print @result2;
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
$sysinfo = &ypmatch($ARGV[0]);
|
||
$reset = (split('`', $sysinfo))[16]; $reset =~ s/\s//g;
|
||
|
||
if (!$reset) {
|
||
print "No reset line connected, unable to reset machine.\n";
|
||
&checkversion;
|
||
exit(0);
|
||
}
|
||
|
||
|
||
#
|
||
# Reset via system controller
|
||
#
|
||
if ($reset eq 'sc') {
|
||
# everest system, use system controller to reset system
|
||
$sc = (split(',', (split('`', $sysinfo))[17]))[1];
|
||
$annex = (split('`', $sysinfo))[15];
|
||
if (!$sc) { #
|
||
print "No system controller line connected, unable to reset machine.\n";
|
||
&checkversion;
|
||
exit(0);
|
||
}
|
||
|
||
die "Sorry, can't power-off the system via the system controller"
|
||
if $opt_off;
|
||
|
||
print "Attempting to ";
|
||
if ($opt_power) { print "power-cycle"; $tstring = "c"; }
|
||
elsif ($opt_nmi) { print "send an NMI to"; $tstring = "n"}
|
||
else { print "reset"; $tstring = "r"; }
|
||
|
||
print " the system via the System Controller port.\n" .
|
||
"This may fail if the controller port is busy.\n";
|
||
|
||
print `(echo $tstring; sleep 2;echo c
|
||
) | telnet $annex 50$sc`;
|
||
#
|
||
# Reset via SN0 entry-level system controller
|
||
#
|
||
} elsif ($reset eq 'elsc') {
|
||
# SN0 system with entry-level system controller, use system controller to reset system
|
||
$sc = (split(',', (split('`', $sysinfo))[17]))[1];
|
||
$annex = (split('`', $sysinfo))[15];
|
||
if (!$sc) { #
|
||
print "No system controller line connected, unable to reset machine.\n";
|
||
&checkversion;
|
||
exit(0);
|
||
}
|
||
|
||
print "Attempting to ";
|
||
if ($opt_power) { print "power-cycle"; $tstring = "pwr c"; }
|
||
elsif ($opt_nmi) { print "send an NMI to"; $tstring = "nmi"}
|
||
elsif ($opt_off) { print "power off"; $tstring = "pwr d"; }
|
||
elsif ($opt_on) { print "power on"; $tstring = "pwr u"; }
|
||
else { print "reset"; $tstring = "rst"; }
|
||
|
||
print " the system via the System Controller port.\n" .
|
||
"This may fail if the controller port is busy.\n";
|
||
|
||
print `(echo $tstring; sleep 2;echo c
|
||
) | telnet $annex 50$sc`;
|
||
#
|
||
# Reset via vme relay board
|
||
#
|
||
} elsif ($reset =~ /^vme_relay/) {
|
||
($reset_machine, $port) = $reset =~ /^vme_relay:(\S+):(\d+)/;
|
||
die "Incomplete reset entry for $ARGV[0]:\n\t$reset\n" .
|
||
"Unable to reset machine.\n" if (! length($port));
|
||
die "Sorry, can't power-off the system via reset board in $reset_machine"
|
||
if $opt_off;
|
||
|
||
print "Resetting $ARGV[0] via reset board in $reset_machine...";
|
||
system ("rsh guest\@$reset_machine /usr/annex/real_reset " . $ARGV[0] );
|
||
print "done.\n";
|
||
#
|
||
# Reset via x10 controller hooked up to an annex box
|
||
#
|
||
} elsif ($reset =~ /^x10_annex/) {
|
||
($x10_box, $info) = $reset =~ /^x10_annex:(\S+):(.*)/;
|
||
die "Incomplete reset entry for $ARGV[0]:\n\t$reset\n" .
|
||
"Unable to reset machine.\n" if (! length($x10_box) || !length($info));
|
||
|
||
die "Can't send an NMI, sorry.\n" if $opt_nmi;
|
||
|
||
($reset) = $info =~ /reset=(\w+)/;
|
||
($power) = $info =~ /power=(\w+)/;
|
||
|
||
# option to get number of seconds of delay between turning a system
|
||
# off and on, this is needed for IP30 - this is an optional field
|
||
($restart_delay) = $info =~ /restart_delay=(\w+)/;
|
||
|
||
$opt_power = 1 if $reset eq 'power';
|
||
|
||
print "Attempting to " ,
|
||
$opt_power ? "power-cycle " : "reset ",
|
||
"the system via the X10 box $x10_box.\n";
|
||
|
||
if ($opt_off) {
|
||
($housecode, $unit) = $power =~ /(\S)(\d+)/;
|
||
&reset_via_x10('off', $housecode, $unit, $x10_box);
|
||
}
|
||
elsif ($opt_power) {
|
||
($housecode, $unit) = $power =~ /(\S)(\d+)/;
|
||
|
||
&reset_via_x10('cycle', $housecode, $unit, $x10_box);
|
||
} else {
|
||
($housecode, $unit) = $reset =~ /(\S)(\d+)/;
|
||
|
||
&reset_via_x10('on', $housecode, $unit, $x10_box);
|
||
}
|
||
} else {
|
||
#
|
||
# old style entry, remove this once the ktools file has been
|
||
# updated
|
||
#
|
||
($reset_machine, $port) = $reset =~ /(\S+):(\d+)/;
|
||
die "Incomplete reset entry for $ARGV[0]:\n\t$reset\n" .
|
||
"Unable to reset machine.\n" if (! length($port));
|
||
|
||
print "Resetting $ARGV[0] via reset board in $reset_machine...";
|
||
system ("rsh guest\@$reset_machine /usr/annex/real_reset " . $ARGV[0] );
|
||
print "done.\n";
|
||
}
|
||
|
||
&checkversion;
|
||
|
||
######################################################################
|
||
|
||
|
||
|
||
sub reset_via_x10 {
|
||
local($cmd, $housecode, $unit, $x10) = @_;
|
||
local($my_reset_delay,$sec);
|
||
|
||
if ($cmd eq 'cycle') {
|
||
# off
|
||
&reset_via_x10('off', $housecode, $unit, $x10);
|
||
if (!$restart_delay) {
|
||
$my_reset_delay = 2; # if not set, use default
|
||
}
|
||
else {
|
||
$my_reset_delay = $restart_delay;
|
||
}
|
||
# sleep
|
||
select((select(STDOUT), $| = 1)[0]); # force flush after every write
|
||
print "Power Off - waiting $my_reset_delay seconds before turning power back on ";
|
||
$sec = 0;
|
||
while ($sec < $my_reset_delay) {
|
||
print ".";
|
||
sleep 1;
|
||
$sec++;
|
||
}
|
||
print " - Power On\n";
|
||
select((select(STDOUT), $| = 0)[0]); # unforce flush after every write
|
||
# on
|
||
&reset_via_x10('on', $housecode, $unit, $x10);
|
||
};
|
||
|
||
$cmd = 2 if $cmd eq 'on';
|
||
$cmd = 3 if $cmd eq 'off';
|
||
|
||
$housecode =~ tr/[a-z]/[A-Z]/;
|
||
|
||
die "Invalid configuration\n" if (!$house_table{$housecode} || !$unit_table{$unit} ||
|
||
!$x10);
|
||
|
||
$chksum = ($cmd +
|
||
eval(join("+", split(/,/, $unit_table{$unit}))) +
|
||
$house_table{$housecode}) % 0x100;
|
||
|
||
|
||
local($sysinfo) = &ypmatch($x10);
|
||
die "Unable to determine where $x10 is\n" if !length($sysinfo);
|
||
|
||
$annex = (split('`', $sysinfo))[15];
|
||
($port = (split('`', $sysinfo))[17]) =~ s/r//;
|
||
|
||
|
||
$Control = &chat'open_port($annex, 50 . $port) || #'
|
||
die "Couldn't open $annex CLI port $port, $!.\n";
|
||
|
||
|
||
$string = pack("c24", (@sync, $cmd, $house_table{$housecode},
|
||
eval($unit_table{$unit}), $chksum));
|
||
|
||
&chat'print($Control, $string);#';
|
||
|
||
# this sleep is necessary, don't quite know why.
|
||
sleep 1;
|
||
|
||
&chat'close($Control);
|
||
|
||
}
|
||
|
||
|
||
|
||
# checkversion:
|
||
# check to make sure that we've got the latest version of this
|
||
#
|
||
sub checkversion {
|
||
$nis_version = &ypmatch("kreset_version");
|
||
|
||
if (!$nis_version) {
|
||
printf(stderr "\n$0: unable to find kreset_version in ktools NIS map.\n");
|
||
} else {
|
||
if ($nis_version > $REVISION) {
|
||
printf(stderr "\n NOTICE: A newer version of $0 is available. \n Please upgrade at your earliest convenience\n");
|
||
printf(stderr " for added functionality and bug fixes.\n Install from dist.engr:/sgi/hacks/ktools\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
#
|
||
# ypmatch:
|
||
# do the ypmatch thing
|
||
#
|
||
sub ypmatch {
|
||
local($foo) = $opt_noyp ? `grep ^$_[0] $PORTSFILE` : `ypmatch -k $_[0] ktools 2>&1`;
|
||
|
||
if ($opt_noyp) {
|
||
if ($foo !~ /$_[0]/) { return 0; }
|
||
$foo =~ s/(.*)$_[0]\s*(.*)/$2/;
|
||
} else {
|
||
if ($foo !~ /$_[0]:/) { return 0; }
|
||
$foo =~ s/(.*)$_[0]: (.*)/$2/;
|
||
}
|
||
$foo;
|
||
}
|
||
|
||
#
|
||
# Usage: print usage info
|
||
#
|
||
sub Usage {
|
||
print "Usage: kreset [-f] [-noyp] [-power] [-nmi] [-off] <systemname>\n",
|
||
"\t-f\tForcefully reset regardless if console is held\n",
|
||
"\t-noyp\tUse if no YP (NIS) ktools map is available\n",
|
||
"\t-power\tPower cycle the system (if possible)\n",
|
||
"\t-nmi\tSend an NMI to the system (if possible)\n";
|
||
"\t-off\tShut off system power(if possible)\n";
|
||
|
||
}
|
||
|
||
|
||
format mach =
|
||
@<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
$_, $Conf{$_}
|
||
.
|
||
format note =
|
||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
$_
|
||
.
|
||
|
||
|