mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 01:26:38 +00:00
If cons script is waiting, goconserver could not aware of the status of the console connection. This patch check the environment when running the script, if it is gocons and retrying is needed, exit immediately.
229 lines
6.2 KiB
Perl
Executable File
229 lines
6.2 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
use Fcntl qw(:DEFAULT :flock);
|
|
|
|
sub get_lock {
|
|
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
|
|
$| = 1;
|
|
print "Acquiring startup lock...";
|
|
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
|
|
print "done\n";
|
|
}
|
|
truncate(LOCKHANDLE, 0);
|
|
print LOCKHANDLE $$ . "\n";
|
|
}
|
|
|
|
sub release_lock {
|
|
truncate(LOCKHANDLE, 0);
|
|
flock(LOCKHANDLE, LOCK_UN);
|
|
}
|
|
|
|
BEGIN
|
|
{
|
|
use Time::HiRes qw(sleep);
|
|
use File::Path;
|
|
use Fcntl qw(:DEFAULT :flock);
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
my $sleepint = int(rand(10));
|
|
use lib "$::XCATROOT/lib/perl";
|
|
require xCAT::Client;
|
|
require xCAT::Utils;
|
|
use strict;
|
|
use Expect;
|
|
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
|
require File::Basename;
|
|
|
|
umask 0077;
|
|
mkpath("/tmp/xcat/");
|
|
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
|
|
xCAT::Utils::console_sleep(15, "Unable to open lock file");
|
|
exit 0;
|
|
}
|
|
get_lock();
|
|
|
|
##############################################
|
|
# Globals
|
|
##############################################
|
|
my $verbose = 0;
|
|
my $node;
|
|
my $host;
|
|
my $lparid;
|
|
my $mtms;
|
|
my @cred;
|
|
my $credencial;
|
|
my $fsp_ip;
|
|
my $id;
|
|
my $hcps;
|
|
my $result;
|
|
|
|
##########################################################################
|
|
# Open remote console thourgh fsp
|
|
##########################################################################
|
|
sub invoke_fsp {
|
|
|
|
my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api";
|
|
my $action = "console";
|
|
my $type = "0";
|
|
my $Rc = 0;
|
|
|
|
if (!(-e $fsp_api) && !(-x $fsp_api)) {
|
|
return "please check the $fsp_api";
|
|
}
|
|
|
|
my $cmd = "$fsp_api -a $action -t $type:$fsp_ip:$id:$node:\r";
|
|
|
|
#print "cmd: $cmd\n";
|
|
my $running_failed_code = "Reason code: 0x1000000";
|
|
my $fsp_standby_msg = "Reason code: 0x1300";
|
|
my $timeout = 30;
|
|
my $failed = 0;
|
|
my $exp = new Expect;
|
|
$exp->log_stdout(1);
|
|
$exp->spawn($cmd) or die "Can't spawn $cmd\r\n";
|
|
|
|
my @result = $exp->expect($timeout,
|
|
[ "$running_failed_code",
|
|
sub {
|
|
$failed = 1;
|
|
} ],
|
|
[ "$fsp_standby_msg",
|
|
sub {
|
|
$failed = 2;
|
|
|
|
} ],
|
|
[ "Session closed, back from open_vterm",
|
|
sub {
|
|
$failed = 3;
|
|
|
|
} ]
|
|
);
|
|
if ($failed == 1) {
|
|
$exp->hard_close();
|
|
return ("Virtual terminal is already connected");
|
|
|
|
}
|
|
if ($failed == 2) {
|
|
$exp->hard_close();
|
|
return ("Failed to open the console. Please check the related FSP's status");
|
|
|
|
}
|
|
if ($failed == 3) {
|
|
$exp->hard_close();
|
|
return ("Failed to open the console. Please check the related FSP's IP");
|
|
|
|
}
|
|
|
|
|
|
my $escape = "\030";
|
|
$exp->send("\r");
|
|
$exp->interact(\*STDIN, $escape);
|
|
|
|
$exp->hard_close();
|
|
|
|
return (0);
|
|
}
|
|
|
|
##########################################################################
|
|
# Open remote console through hmc
|
|
##########################################################################
|
|
sub invoke_hmc {
|
|
|
|
my $type = "lpar";
|
|
my $hwtype = "hmc";
|
|
my %request = (
|
|
ppcretry => 1,
|
|
verbose => $verbose
|
|
);
|
|
#################################
|
|
# Get userid and password
|
|
#################################
|
|
@cred = split(/,/, $credencial);
|
|
$request{$host}{cred} = \@cred;
|
|
#################################
|
|
# Connect to the remote server
|
|
#################################
|
|
my @exp = xCAT::PPCcli::connect(\%request, $hwtype, $host);
|
|
if (ref($exp[0]) ne "Expect") {
|
|
return ($exp[0]);
|
|
}
|
|
#################################
|
|
# Open console connection
|
|
#################################
|
|
my $result = xCAT::PPCcli::mkvterm(\@exp, $type, $lparid, $mtms);
|
|
my $Rc = shift(@$result);
|
|
|
|
if ($Rc != SUCCESS) {
|
|
return (@$result[0]);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
##############################################
|
|
# Start main body of code
|
|
##############################################
|
|
sub getans {
|
|
my $rsp = shift;
|
|
if ($rsp->{node}) {
|
|
$hcps = $rsp->{node}->[0]->{hcp};
|
|
if ($rsp->{node}->[0]->{errorcode}) {
|
|
print STDERR "$rsp->{node}->[0]->{error}";
|
|
}
|
|
}
|
|
}
|
|
my $cmdref = {
|
|
command => ["getmulcon"],
|
|
arg => ["text"],
|
|
noderange => [ $ARGV[0] ]
|
|
};
|
|
xCAT::Client::submit_request($cmdref, \&getans);
|
|
until ($hcps) {
|
|
release_lock(); #Let other clients have a go
|
|
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
|
|
xCAT::Utils::console_sleep($sleepint, "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n");
|
|
get_lock();
|
|
xCAT::Client::submit_request($cmdref, \&getans);
|
|
}
|
|
release_lock(); #done with xcatd, can run with near impunity
|
|
|
|
$node = $ARGV[0];
|
|
my $c = scalar(keys %{ ${$hcps}[0] });
|
|
for my $thishcp (keys %{ ${$hcps}[0] }) {
|
|
my $nt = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{nodetype} }[0];
|
|
if ($nt =~ /^(fsp)$/) {
|
|
$fsp_ip = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{fsp_ip} }[0];
|
|
$id = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{id} }[0];
|
|
if ($fsp_ip and $id) {
|
|
$result = invoke_fsp();
|
|
} else {
|
|
print STDERR "fsp_ip or id is not available\n";
|
|
}
|
|
}
|
|
elsif ($nt =~ /^(hmc)$/) {
|
|
$host = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{host} }[0];
|
|
$lparid = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{lparid} }[0];
|
|
$mtms = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{mtms} }[0];
|
|
$credencial = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{credencial} }[0];
|
|
if ($host and $lparid and $mtms and $credencial) {
|
|
$result = invoke_hmc();
|
|
} else {
|
|
print STDERR "hcp or lparid or mtms or user/passwd is not available\n";
|
|
}
|
|
}
|
|
|
|
if ($result eq 0) {
|
|
last;
|
|
}
|
|
##############
|
|
#Once every hcp is tried, if the $res!=0, it will return -1;
|
|
###############
|
|
$c--;
|
|
if ($c == 0) {
|
|
print STDERR "$node: $result\n";
|
|
exit(1)
|
|
}
|
|
}
|
|
exit(0);
|