server/dep/ACE_wrappers/bin/PerlACE/ProcessVX.pm
cipherCOM 571f510ee4 [11162] Changed ACE lib to same version but with configure script
(based on cipherCOM's repo commit d3d8934)

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
2011-02-14 12:51:16 +03:00

464 lines
11 KiB
Perl

#! /usr/bin/perl
# $Id: ProcessVX.pm 89840 2010-04-12 09:36:32Z mcorino $
package PerlACE::ProcessVX;
use strict;
use English;
use POSIX qw(:time_h);
$PerlACE::ProcessVX::ExeSubDir = './';
$PerlACE::ProcessVX::DoVxInit = (defined $ENV{"ACE_RUN_VX_NO_INITIAL_REBOOT"}) ? 0 : 1;
$PerlACE::ProcessVX::VxDefGw = 1;
$PerlACE::ProcessVX::RebootTime = (defined $ENV{"ACE_RUN_VX_REBOOT_TIME"}) ? $ENV{"ACE_RUN_VX_REBOOT_TIME"} : 90;
$PerlACE::ProcessVX::ExeExt = ($PerlACE::VxWorks_RTP_Test) ? '.vxe' : '.out';
$PerlACE::ProcessVX::RebootCmd = $ENV{"ACE_RUN_VX_REBOOT_CMD"};
# Wait for the process to exit or kill after a time period
sub WaitKill ($)
{
my $self = shift;
my $timeout = shift;
my $status = $self->TimedWait ($timeout);
if ($status == -1) {
print STDERR "ERROR: $self->{EXECUTABLE} timedout\n";
$self->Kill ();
# Don't need to Wait since we are on Win32
$PerlACE::ProcessVX::DoVxInit = 1; # force reboot on next run
}
$self->{RUNNING} = 0;
return $status;
}
# Do a Spawn and immediately WaitKill
sub SpawnWaitKill ($)
{
my $self = shift;
my $timeout = shift;
if ($self->Spawn () == -1) {
return -1;
}
return $self->WaitKill ($timeout);
}
###############################################################################
### Some Accessors
sub Normalize_Executable_Name
{
my $self = shift;
my $executable = shift;
my $basename = basename ($executable);
my $dirname = dirname ($executable). '/';
$executable = $dirname.$PerlACE::ProcessVX::ExeSubDir.$basename.$PerlACE::ProcessVX::ExeExt;
## Installed executables do not conform to the ExeSubDir
if (! -e $executable && -e $dirname.$basename.$PerlACE::ProcessVX::ExeExt) {
$executable = $dirname.$basename.$PerlACE::ProcessVX::ExeExt;
}
return $executable;
}
sub Executable
{
my $self = shift;
if (@_ != 0) {
$self->{EXECUTABLE} = shift;
}
my $executable = $self->{EXECUTABLE};
if ($self->{IGNOREEXESUBDIR} == 0) {
$executable = $self->Normalize_Executable_Name ($executable);
}
else {
$executable = $executable.$PerlACE::ProcessVX::ExeExt;
}
return $executable;
}
sub Arguments
{
my $self = shift;
if (@_ != 0) {
$self->{ARGUMENTS} = shift;
}
return $self->{ARGUMENTS};
}
sub CommandLine ()
{
my $self = shift;
my $commandline = $self->Executable ();
if (defined $self->{ARGUMENTS}) {
$commandline .= ' '.$self->{ARGUMENTS};
}
return $commandline;
}
sub IgnoreExeSubDir
{
my $self = shift;
if (@_ != 0) {
$self->{IGNOREEXESUBDIR} = shift;
}
return $self->{IGNOREEXESUBDIR};
}
sub IgnoreHostRoot
{
my $self = shift;
if (@_ != 0) {
$self->{IGNOREHOSTROOT} = shift;
}
return $self->{IGNOREHOSTROOT};
}
sub delay_factor {
my($lps) = 128;
my($factor) = 1;
## Keep increasing the loops per second until the amount of time
## exceeds the number of clocks per second. The original code
## did not multiply $ticks by 8 but, for faster machines, it doesn't
## seem to return false values. The multiplication is done to minimize
## the amount of time it takes to determine the correct factor.
while(($lps <<= 1)) {
my($ticks) = clock();
for(my $i = $lps; $i >= 0; $i--) {
}
$ticks = clock() - $ticks;
if ($ticks * 8 >= CLOCKS_PER_SEC) {
$factor = 500000 / (($lps / $ticks) * CLOCKS_PER_SEC);
last;
}
}
return $factor;
}
sub iboot_cycle_power {
my $self = shift;
my $mode = shift;
# mode 0 is reboot, mode 1 is just shutdown
my ($iboot_host,
$iboot_outlet,
$iboot_user,
$iboot_passwd ) = ($ENV{'ACE_RUN_VX_IBOOT'},
$ENV{'ACE_RUN_VX_IBOOT_OUTLET'},
$ENV{'ACE_RUN_VX_IBOOT_USER'},
$ENV{'ACE_RUN_VX_IBOOT_PASSWORD'});
my $v = $ENV{'ACE_TEST_VERBOSE'};
if ($v) {
print "Using iBoot: $iboot_host\n";
if (defined $iboot_outlet) {
print "Using iBoot Outlet #: $iboot_outlet\n";
}
}
# There are three cases to handle here:
# 1. using a single-outlet iBoot
# 2. using a multi-outlet iBootBar with custom firmware
# 3. using a multi-outlet iBootBar with standard firmware
#
# In cases 1 & 2, we use the iPAL protocol; in case 3 we
# use a telnet connection and the command-line syntax.
#
# We determine that it's case #3 by the concurrent presence
# of an outlet number, an iboot username, and an iboot password
# in the environment.
#
if (defined($iboot_outlet) && defined($iboot_user) && defined($iboot_passwd)) {
# We perform case #3
# This case doesn't support shutdown
return if $mode == 1;
my $t = new Net::Telnet();
$t->prompt('/iBootBar \> /');
my $savedmode = $t->errmode();
$t->errmode("return");
my $retries = 5;
my $is_open = 0;
while ($retries--) {
my $r = $t->open($iboot_host);
if ($r == 1) {
$is_open = 1;
last;
}
}
continue {
print "Couldn't open connection; sleeping then retrying\n" if ($v);
sleep(5);
}
if (! $is_open) {
print "Unable to open $iboot_host.\n" if ($v);
return 0;
}
$t->errmode($savedmode);
# Simple login b/c Net::Telnet::login hardcodes the prompts
$t->waitfor('/User Name:\s*$/i');
$t->print($iboot_user);
$t->waitfor('/password:\s*/i');
$t->print($iboot_passwd);
$t->waitfor($t->prompt);
print "successfully logged in to $iboot_host\n" if ($v);
my $output = $t->cmd("set outlet $iboot_outlet cycle");
print "successfully cycled power on outlet $iboot_outlet\n" if ($v);
$t->close();
}
else {
# Perform cases 1 & 2
my $iboot;
my $text;
if (!defined($iboot_passwd)) {
$iboot_passwd = "PASS";
}
my $ipal_command_series;
if (defined $iboot_outlet) {
$ipal_command_series = ($mode == 0 ? ['E', 'D'] : ['E']);
} else {
$ipal_command_series = ($mode == 0 ? ['f', 'n'] : ['f']);
}
foreach my $ipal_cmd (@$ipal_command_series) {
my $retries = 3;
my $is_open = 0;
while ($retries--) {
$iboot = IO::Socket::INET->new ("$iboot_host");
if ($iboot) {
# if ACE_RUN_VX_IBOOT_OUTLET is defined, we're using
# the iBootBar, and we're using the iPAL Protocol
# to communicate with the iBootBar
if (defined $iboot_outlet) {
$iboot->send ("\e".$iboot_passwd."\e".$iboot_outlet.$ipal_cmd);
}
else {
$iboot->send ("\e".$iboot_passwd."\e$ipal_cmd\r");
}
$iboot->recv ($text,128);
print "iBoot is currently: $text\n" if ($v);
$iboot->close();
if (defined $iboot_outlet) {
$text = substr $text, $iboot_outlet - 1, 1;
if ($text eq "0" || $text eq "1") {
$is_open = 1;
last;
}
else {
print "iBoot is $text; sleeping then retrying\n" if ($v);
sleep(5);
}
}
else {
if ($text eq "OFF" || $text eq "ON") {
$is_open = 1;
last;
}
else {
print "iBoot is $text; sleeping then retrying\n" if ($v);
sleep(5);
}
}
}
else {
print "ERROR: FAILED to execute 'reboot' command!\n";
}
}
if (!$is_open) {
print "Unable to reboot using $iboot_host.\n" if ($v);
return 0;
}
}
}
}
sub reboot {
my $self = shift;
my $iboot;
my $text;
my $t;
my $ok;
my $target_login = $ENV{'ACE_RUN_VX_LOGIN'};
my $target_password = $ENV{'ACE_RUN_VX_PASSWORD'};
##
## initialize VxWorks kernel (reboot!) if needed
if ($PerlACE::ProcessVX::DoVxInit || $ENV{'ACE_RUN_VX_TGT_REBOOT'}) {
if (defined $ENV{'ACE_RUN_VX_REBOOT_TOOL'}) {
if (defined $ENV{'ACE_TEST_VERBOSE'}) {
print "Calling: $ENV{'ACE_RUN_VX_REBOOT_TOOL'}\n";
}
system ($ENV{'ACE_RUN_VX_REBOOT_TOOL'});
}
else {
if (defined $ENV{'ACE_RUN_VX_IBOOT'}) {
$self->iboot_cycle_power(0);
}
else {
if (defined $ENV{'ACE_TEST_VERBOSE'}) {
print "Executing 'reboot' command over Telnet to ".$ENV{'ACE_RUN_VX_TGTHOST'}.".\n";
}
$t = new Net::Telnet(Timeout => 10,
Prompt => '/-> $/',
Errmode => 'return');
$t->open($ENV{'ACE_RUN_VX_TGTHOST'});
$t->print("");
if (defined $target_login) {
$t->waitfor('/VxWorks login: $/');
$t->print("$target_login");
}
if (defined $target_password) {
$t->waitfor('/Password: $/');
$t->print("$target_password");
}
$ok = $t->waitfor('/-> $/');
if ($ok) {
$t->print($PerlACE::ProcessVX::RebootCmd);
}
else {
print "ERROR: FAILED to execute 'reboot' command!\n";
}
$t->close();
}
}
$PerlACE::ProcessVX::VxDefGw = 1;
$PerlACE::ProcessVX::DoVxInit = 0;
sleep($PerlACE::ProcessVX::RebootTime);
}
}
# Helper for spawning with list of kernel modules in a .vxtest file
sub handle_vxtest_file
{
my $self = shift;
my $vxtestfile = shift;
my $vx_ref = shift;
my $unld_ref = shift;
my $fh = new FileHandle;
if (open ($fh, $vxtestfile)) {
my $line1 = <$fh>;
chomp $line1;
while(<$fh>) {
$line1 = $_;
chomp $line1;
push @$vx_ref, "ld < lib$line1" . ".so";
unshift @$unld_ref, "unld \"lib$line1" . ".so\"";
}
close $fh;
} else {
return 0;
}
return 1;
}
# Load a file that is used as startup script. This script has to be
# located on the host system
sub handle_startup_script
{
my $script = shift;
my $cmds = shift;
my $fh = new FileHandle;
if (open ($fh, $script)) {
while(<$fh>) {
my $line1 = $_;
chomp $line1;
push @$cmds, "$line1";
}
close $fh;
} else {
return 0;
}
return 1;
}
### Check for -ExeSubDir commands, store the last one
my @new_argv = ();
for(my $i = 0; $i <= $#ARGV; ++$i) {
if ($ARGV[$i] eq '-ExeSubDir') {
if (defined $ARGV[$i + 1]) {
$PerlACE::ProcessVX::ExeSubDir = $ARGV[++$i].'/';
}
else {
print STDERR "You must pass a directory with ExeSubDir\n";
exit(1);
}
}
else {
push @new_argv, $ARGV[$i];
}
}
@ARGV = @new_argv;
$PerlACE::ProcessVX::WAIT_DELAY_FACTOR = $ENV{"ACE_RUNTEST_DELAY"};
if (defined $ENV{'ACE_TEST_WINCE'}) {
if ($OSNAME eq "MSWin32") {
require PerlACE::ProcessWinCE;
} else {
require PerlACE::ProcessWinCE_Unix;
}
} else {
if ($OSNAME eq "MSWin32") {
require PerlACE::ProcessVX_Win32;
}
else {
require PerlACE::ProcessVX_Unix;
}
}
###
sub kill_all
{
my $procmask = shift;
my $target = shift;
## NOT IMPLEMENTED YET
}
1;