mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9266 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			232 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			232 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';
 | |
|     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);
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |