mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			235 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			6.3 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';
 | |
|     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
 | |
|     #################################
 | |
|     #my @cred = xCAT::PPCdb::credentials( $host, $hwtype );
 | |
|     @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);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |