#!/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'; umask 0077; mkpath("/tmp/xcat/"); unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) { sleep 15; print "Unable to open lock file"; exit 0; } get_lock(); } my $sleepint = int(rand(10)); use lib "$::XCATROOT/lib/perl"; require xCAT::Client; use strict; use Expect; use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); require File::Basename; import File::Basename; ############################################## # 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 print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n"; sleep $sleepint; 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);