From c21d86f955be6add2f749a863a3697e52bf19a73 Mon Sep 17 00:00:00 2001 From: yinle Date: Thu, 7 Apr 2011 06:54:08 +0000 Subject: [PATCH] Fix bug 3261047: ExtTab loads user tables for every perl process. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9235 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/share/xcat/cons/fsp | 352 +++++++++++++++++++------------- 1 file changed, 210 insertions(+), 142 deletions(-) diff --git a/xCAT-server/share/xcat/cons/fsp b/xCAT-server/share/xcat/cons/fsp index 9a80b7326..b8ff6e016 100755 --- a/xCAT-server/share/xcat/cons/fsp +++ b/xCAT-server/share/xcat/cons/fsp @@ -1,123 +1,161 @@ #!/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 xCAT::PPCdb; +#use Getopt::Long; +#use xCAT::Table; +#use xCAT::PPCdb; use Expect; -use xCAT::DBobjUtils; +#use xCAT::DBobjUtils; use Data::Dumper; +require File::Basename; +import File::Basename; +my $scriptname = $0; ############################################## # Globals ############################################## my $verbose = 0; my $node; +my $ips; +my $id; ########################################## # 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 { +#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); -} +# 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,82 +163,86 @@ sub parse_args { # Open remote console ########################################################################## sub invoke_cmd { - - my @attribs = qw(id parent hcp); - my %tabs = (); + my $node = shift; + my $fsp_ip = shift; + my $id = shift; + #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}, $_ )); - } - } + #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/; - + #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" )); - } + #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" )); - } + #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}" ); - } + #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" )); - } + #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" )); - } - } + #foreach my $at ( @attribs ) { + # if ( !exists( $att->{$at} )) { + # return( sprintf( $errmsg{NO_ATTR}, $at, "ppc" )); + # } + #} + # + #my $fsp_name = $att->{hcp}; + #my $id = $att->{id}; + + #use xcatd to get the attribute $fsp_name and $id of the node. - my $fsp_name = $att->{hcp}; - my $id = $att->{id}; - -# my $fsp_api ="/opt/xcat/sbin/fsp-api"; + #my $fsp_api ="/opt/xcat/sbin/fsp-api"; my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api"; my $action = "console"; my $type = "0"; - my $fsp_ip = (); + #my $fsp_ip = (); my $Rc = 0; - $fsp_ip = xCAT::Utils::getNodeIPaddress( $fsp_name ); - if(!defined($fsp_ip)) { - return "Failed to get the $fsp_name\'s ip"; - } + #$fsp_ip = xCAT::Utils::getNodeIPaddress( $fsp_name ); + #if(!defined($fsp_ip)) { + # return "Failed to get the $fsp_name\'s ip"; + #} my $cmd = "$fsp_api -a $action -t $type:$fsp_ip:$id:$node:\r"; -# print "cmd: $cmd\n"; + #print "cmd: $cmd\n"; my $running_failed_code = "Reason code: 0x1000000"; my $fsp_standby_msg = "Reason code: 0x1300"; my $timeout = 30; @@ -244,10 +286,36 @@ sub invoke_cmd { ############################################## # Start main body of code ############################################## -if ( parse_args() ) { - exit(1); +#if ( parse_args() ) { +# exit(1); +#} +sub getans { + my $rsp = shift; + if ($rsp->{node}) { + $ips = $rsp->{node}->[0]->{fsp_ip}->[0]; + $id = $rsp->{node}->[0]->{id}->[0]; + } } -my $result = invoke_cmd(); + +my $cmdref={ + command=>["getfspcon"], + arg=>["text"], + noderange=>[$ARGV[0]] +}; +xCAT::Client::submit_request($cmdref,\&getans); +until ($ips and $id) { + 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($node, $ips, $id); if ( $result ne "0" ) { print STDERR "$node: $result\n"; exit(1);