#!/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] \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 = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $_ .