From 5ca0bce03461bdb98add0a83d6108244f0f99a0d Mon Sep 17 00:00:00 2001 From: yinle Date: Fri, 8 Apr 2011 02:22:01 +0000 Subject: [PATCH] Fix 3261047: ExtTab loads user tables for every perl process git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9244 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/share/xcat/cons/hmc | 408 ++++++++++++++++++-------------- 1 file changed, 236 insertions(+), 172 deletions(-) diff --git a/xCAT-server/share/xcat/cons/hmc b/xCAT-server/share/xcat/cons/hmc index 266fae71b..63c0c7ada 100644 --- a/xCAT-server/share/xcat/cons/hmc +++ b/xCAT-server/share/xcat/cons/hmc @@ -1,122 +1,160 @@ #!/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)); #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 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; ########################################## # 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" -); +#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); -} +#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); +#} @@ -125,85 +163,87 @@ sub parse_args { ########################################################################## sub invoke_cmd { - my @attribs = qw(id parent hcp); - my %tabs = (); - + #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/; + # ################################## - # Open databases needed + ## Get node type ################################## - foreach ( qw(ppc vpd nodetype) ) { - $tabs{$_} = xCAT::Table->new($_); - - if ( !exists( $tabs{$_} )) { - return( sprintf( $errmsg{DB_UNDEF}, $_ )); - } - } + #my ($ent) = $tabs{nodetype}->getNodeAttribs($node, ["nodetype"] ); + #if ( !defined( $ent )) { + # return( sprintf( $errmsg{NODE_UNDEF}, "nodetype" )); + #} ################################## - # Get node power type + ## Check for type ################################## - my $hwtype = __FILE__; - $hwtype =~ s/.*([\w]{3})$/$1/; - + #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" )); + #} ################################# - # Get node type + ## Verify both vpd attributes ################################# - 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"; - + #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 = "hmc"; my %request = ( ppcretry => 1, verbose => $verbose @@ -213,7 +253,6 @@ sub invoke_cmd { ################################# my @cred = xCAT::PPCdb::credentials( $host, $hwtype ); $request{$host}{cred} = \@cred; - ################################# # Connect to the remote server ################################# @@ -232,15 +271,40 @@ sub invoke_cmd { } return(0); } - - ############################################## # Start main body of code ############################################## -if ( parse_args() ) { - exit(1); +#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]; + } } -my $result = invoke_cmd(); + +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);