#!/usr/bin/env perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html use Fcntl qw(:DEFAULT :flock); use strict; 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)); #Stagger start to avoid overwhelming conserver/xCATd print "Opening console in " . (2 + (0.5 * $sleepint)) . " seconds...\n"; sleep $sleepint; } my $sleepint = int(rand(10)); use lib "$::XCATROOT/lib/perl"; require xCAT::Client; use strict; #use Getopt::Long; #use xCAT::Table; #use xCAT::PPCdb; use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); use Data::Dumper; require File::Basename; import File::Basename; my $scriptname = $0; ############################################## # Globals ############################################## my $verbose = 0; my $node; my $host; my $lparid; my $mtms; my @cred; my $credencial; ########################################## # Database errors ########################################## #my %errmsg = ( # NODE_UNDEF =>"Node not defined in '%s' database", # NO_ATTR =>"'%s' not defined in '%s' database", # DB_UNDEF =>"'%s' database not defined" #); ########################################################################## # Parse the command line for options and operands ########################################################################## #sub parse_args { # # my %opt = (); # my @VERSION = qw( 2.0 ); # # ############################################# # # Responds with usage statement # ############################################# # local *usage = sub { # # my $cmd = __FILE__; # $cmd =~ s/.*([\w]{3}$)/$1/; # # if ( defined( $_[0] )) { # print STDERR "$_[0]\n"; # } # my @msg = ( # "$cmd -h|--help\n", # "$cmd -v|--version\n", # "$cmd singlenode [-V|-Verbose]\n" ); # print STDERR @msg; # }; # ############################################# # # Process command-line arguments # ############################################# # if ( !defined( @ARGV )) { # usage( "No node specified" ); # return(1); # } # ############################################# # # Checks case in GetOptions, allows opts # # to be grouped (e.g. -vx), and terminates # # at the first unrecognized option. # ############################################# # $Getopt::Long::ignorecase = 0; # Getopt::Long::Configure( "bundling" ); # # if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) { # usage(); # return(1); # } # ####################################### # # Option -h for Help # ####################################### # if ( exists( $opt{h} )) { # usage(); # return(1); # } # ####################################### # # Option -v for version # ####################################### # if ( exists( $opt{v} )) { # print STDERR \@VERSION; # return(1); # } # ####################################### # # Option -V for verbose output # ####################################### # if ( exists( $opt{V} )) { # $verbose = 1; # } # ####################################### # # Check for "-" with no option # ####################################### # if ( grep(/^-$/, @ARGV )) { # usage( "Missing option: -" ); # return(1); # } # ####################################### # # Get node # ####################################### # if ( !defined( $ARGV[0] )) { # usage( "No node specified" ); # return(1); # } # ####################################### # # Check for extra argument # ####################################### # $node = shift @ARGV; # if ( defined( $ARGV[0] )) { # usage( "Invalid Argument: $ARGV[0]" ); # return(1); # } # return(0); #} ########################################################################## # Open remote console ########################################################################## sub invoke_cmd { #my @attribs = qw(id parent hcp); #my %tabs = (); # ################################### ## Open databases needed ################################### #foreach ( qw(ppc vpd nodetype) ) { # $tabs{$_} = xCAT::Table->new($_); # # if ( !exists( $tabs{$_} )) { # return( sprintf( $errmsg{DB_UNDEF}, $_ )); # } #} ################################### ## Get node power type ################################### #my $hwtype = __FILE__; #$hwtype =~ s/.*([\w]{3})$/$1/; # ################################## ## Get node type ################################## #my ($ent) = $tabs{nodetype}->getNodeAttribs($node, ["nodetype"] ); #if ( !defined( $ent )) { # return( sprintf( $errmsg{NODE_UNDEF}, "nodetype" )); #} ################################## ## Check for type ################################## #if ( !exists( $ent->{nodetype} )) { # return( sprintf( $errmsg{NO_ATTR}, $ent->{nodetype},"nodetype" )); #} ################################## ## Check for valid "type" ################################## #my @types = split /,/, $ent->{nodetype}; #my ($type) = grep( /^(lpar|osi)$/, @types ); # #if ( !defined( $type )) { # return( "Invalid node type: $ent->{nodetype}" ); #} ################################## ## Get attributes ################################## #my ($att) = $tabs{ppc}->getAttribs({'node'=>$node}, @attribs ); # #if ( !defined( $att )) { # return( sprintf( $errmsg{NODE_UNDEF}, "ppc" )); #} ################################## ## Verify required attributes ################################## #foreach my $at ( @attribs ) { # if ( !exists( $att->{$at} )) { # return( sprintf( $errmsg{NO_ATTR}, $at, "ppc" )); # } #} ################################## ## Find MTMS in vpd database ################################## #my @attrs = qw(mtm serial); #my ($vpd) = $tabs{vpd}->getNodeAttribs($att->{parent}, \@attrs ); # #if ( !defined( $vpd )) { # return( sprintf( $errmsg{NODE_UNDEF}, "vpd" )); #} ################################# ## Verify both vpd attributes ################################# #foreach ( @attrs ) { # if ( !exists( $vpd->{$_} )) { # return( sprintf( $errmsg{NO_ATTR}, $_, "vpd" )); # } #} #my $mtms = "$vpd->{mtm}*$vpd->{serial}"; #my $host = $att->{hcp}; #my $lparid = $att->{id}; #$type = "lpar"; my $type = "lpar"; my $hwtype = "ivm"; 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 ############################################## #if ( parse_args() ) { # exit(1); #} sub getans { my $rsp = shift; if ($rsp->{node}) { $host = $rsp->{node}->[0]->{host}->[0]; $lparid = $rsp->{node}->[0]->{lparid}->[0]; $mtms = $rsp->{node}->[0]->{mtms}->[0]; $credencial = $rsp->{node}->[0]->{cred}->[0]; } } my $cmdref = { command => ["gethmccon"], arg => ["text"], noderange => [ $ARGV[0] ] }; xCAT::Client::submit_request($cmdref, \&getans); until ($lparid and $host and $mtms) { 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 $result = invoke_cmd($host, $lparid, $mtms); if ($result ne "0") { print STDERR "$node: $result\n"; exit(1); } exit(0);