From a5b44375738cd348790d4c077a7ad79154153ab6 Mon Sep 17 00:00:00 2001 From: otubo Date: Fri, 12 Aug 2011 02:30:12 +0000 Subject: [PATCH] Solving bug #3390333 git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10274 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/ivm.pm | 157 +++++++++++++- xCAT-server/share/xcat/cons/ivm | 325 ++++++++++++++++++++++++++++ xCAT-server/xCAT-server.spec | 2 +- 3 files changed, 471 insertions(+), 13 deletions(-) create mode 100755 xCAT-server/share/xcat/cons/ivm diff --git a/xCAT-server/lib/xcat/plugins/ivm.pm b/xCAT-server/lib/xcat/plugins/ivm.pm index b832ecd23..f35fd6919 100644 --- a/xCAT-server/lib/xcat/plugins/ivm.pm +++ b/xCAT-server/lib/xcat/plugins/ivm.pm @@ -3,30 +3,45 @@ package xCAT_plugin::ivm; use strict; use xCAT::PPC; - +use xCAT::DBobjUtils; ########################################################################## # Command handler method from tables ########################################################################## sub handled_commands { return { - rpower => 'nodehm:power,mgt', - rvitals => 'nodehm:mgt', - rinv => 'nodehm:mgt', - mkvm => 'nodehm:mgt', - rmvm => 'nodehm:mgt', - lsvm => 'nodehm:mgt', - chvm => 'nodehm:mgt', - rscan => 'nodehm:mgt', - getmacs => 'nodehm:mgt', - rnetboot => 'nodehm:mgt' - } + rpower => 'nodehm:power,mgt', + rvitals => 'nodehm:mgt', + rinv => 'nodehm:mgt', + mkvm => 'nodehm:mgt', + rmvm => 'nodehm:mgt', + lsvm => 'nodehm:mgt', + chvm => 'nodehm:mgt', + rscan => 'nodehm:mgt', + getmacs => 'nodehm:getmac,mgt', + rnetboot => 'nodehm:mgt', + rspconfig => 'nodehm:mgt', + rflash => 'nodehm:mgt', + mkhwconn => 'nodehm:mgt', + rmhwconn => 'nodehm:mgt', + lshwconn => 'nodehm:mgt', + renergy => 'nodehm:mgt', + gethmccon => 'nodehm:cons', + }; } + ########################################################################## # Pre-process request from xCat daemon ########################################################################## sub preprocess_request { + my ($arg1, $arg2, $arg3) = @_; + if ($arg1->{command}->[0] eq "gethmccon") { #Can handle it here and now + my $node = $arg1->{noderange}->[0]; + my $callback = $arg2; + gethmccon($node,$callback); + return []; + } xCAT::PPC::preprocess_request(__PACKAGE__,@_); } @@ -38,7 +53,125 @@ sub process_request { xCAT::PPC::process_request(__PACKAGE__,@_); } +########################################################################## +# get hcp and id for rcons with fsp +########################################################################## +sub gethmccon { + + my $node = shift; + my $callback = shift; + my $otherhcp = shift; + my @attribs = qw(id parent hcp); + my %tabs = (); + my $rsp; + + + + ################################## + # Open databases needed + ################################## + foreach ( qw(ppc vpd nodetype) ) { + $tabs{$_} = xCAT::Table->new($_); + + if ( !exists( $tabs{$_} )) { + #return( sprintf( $errmsg{DB_UNDEF}, $_ )); + $rsp->{node}->[0]->{error}=["open table $_ error"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + } + + ################################# + # Get node type + ################################# + my $type = xCAT::DBobjUtils->getnodetype($node); + + #my ($type) = grep( /^(lpar|osi)$/, @types ); + + if ( !defined( $type ) or !($type =~/lpar|osi|ppc/) ) { + #return( "Invalid node type: $ent->{nodetype}" ); + $rsp->{node}->[0]->{error}=["Invalid node type: $type"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + ################################# + # Get attributes + ################################# + my ($att) = $tabs{ppc}->getAttribs({'node'=>$node}, @attribs ); + if ( !defined( $att )) { + #return( sprintf( $errmsg{NODE_UNDEF}, "ppc" )); + $rsp->{node}->[0]->{error}=["node is not defined in ppc table"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + ################################# + # Verify required attributes + ################################# + foreach my $at ( @attribs ) { + if ( !exists( $att->{$at} )) { + #return( sprintf( $errmsg{NO_ATTR}, $at, "ppc" )); + $rsp->{node}->[0]->{error}=["Can't find node tarribute $at in ppc table"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + } + ################################# + # 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" )); + $rsp->{node}->[0]->{error}=["Can't find node tarribute in vpd table"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + ################################ + # Verify both vpd attributes + ################################ + foreach ( @attrs ) { + if ( !exists( $vpd->{$_} )) { + #return( sprintf( $errmsg{NO_ATTR}, $_, "vpd" )); + $rsp->{node}->[0]->{error}=["Can't find node tarribute in vpd table"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + } + ################################ + # Get username and passwd + ################################ + my $hwtype = "ivm"; + my $host; + if ($otherhcp) { + $host = $otherhcp; + } else { + $host = $att->{hcp}; + } + my @cred = xCAT::PPCdb::credentials( $host, $hwtype ); + if ( !defined(@cred) ) + { + $rsp->{node}->[0]->{error}=["Can't username and passwd for the ivm"]; + $rsp->{node}->[0]->{errorcode}=[1]; + $callback->($rsp); + return $rsp; + } + + $rsp = {node=>[{name=>[$node]}]}; + $rsp->{node}->[0]->{mtms}->[0] = "$vpd->{mtm}*$vpd->{serial}"; + $rsp->{node}->[0]->{host}->[0] = $host; + $rsp->{node}->[0]->{lparid}->[0] = $att->{id}; + $rsp->{node}->[0]->{cred}->[0] = join ',', @cred; + $callback->($rsp); + return $rsp; +} 1; diff --git a/xCAT-server/share/xcat/cons/ivm b/xCAT-server/share/xcat/cons/ivm new file mode 100755 index 000000000..d5c2aa63c --- /dev/null +++ b/xCAT-server/share/xcat/cons/ivm @@ -0,0 +1,325 @@ +#!/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); + + + + diff --git a/xCAT-server/xCAT-server.spec b/xCAT-server/xCAT-server.spec index e595a0425..6768512f0 100644 --- a/xCAT-server/xCAT-server.spec +++ b/xCAT-server/xCAT-server.spec @@ -95,7 +95,7 @@ cp share/xcat/ib/netboot/sles/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/ chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/cons/* chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/scripts/* chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/sles/* -ln -sf /%{prefix}/share/xcat/cons/hmc $RPM_BUILD_ROOT/%{prefix}/share/xcat/cons/ivm +cp share/xcat/cons/ivm $RPM_BUILD_ROOT/%{prefix}/share/xcat/cons/ivm cp lib/xcat/plugins/* $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin/*