Solving bug #3390333
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10274 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
							
								
								
									
										325
									
								
								xCAT-server/share/xcat/cons/ivm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										325
									
								
								xCAT-server/share/xcat/cons/ivm
									
									
									
									
									
										Executable file
									
								
							| @@ -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); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -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/* | ||||
|   | ||||
		Reference in New Issue
	
	Block a user