git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@13206 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			361 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			361 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| 
 | |
| package xCAT::FSPinv;
 | |
| use strict;
 | |
| use Getopt::Long;
 | |
| use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
 | |
| require xCAT::Usage;
 | |
| require xCAT::PPCinv;
 | |
| require xCAT::FSPUtils;
 | |
| use XML::Simple;
 | |
| #use Data::Dumper;
 | |
| 
 | |
| ##########################################
 | |
| # Maps fsp-api attributes to text
 | |
| ##########################################
 | |
| my @licmap = (
 | |
|     ["ecnumber",               "Release Level  "],
 | |
|     ["activated_level",        "Active Level   "],
 | |
|     ["installed_level",        "Installed Level"],
 | |
|     ["accepted_level",         "Accepted Level "],
 | |
|     ["curr_ecnumber_a",        "Release Level A"],
 | |
|     ["curr_level_a",           "Level A        "],
 | |
|     ["curr_power_on_side_a",        "Current Power on side A"],
 | |
|     ["curr_ecnumber_b",        "Release Level B"],
 | |
|     ["curr_level_b",           "Level B        "],
 | |
|     ["curr_power_on_side_b",        "Current Power on side B"],
 | |
|     ["curr_ecnumber_primary",  "Release Level Primary"],
 | |
|     ["curr_level_primary",     "Level Primary  "],
 | |
|     ["curr_power_on_side_primary",  "Current Power on side Primary"],
 | |
|     ["curr_ecnumber_secondary","Release Level Secondary"],
 | |
|     ["curr_level_secondary",   "Level Secondary"],
 | |
|     ["curr_power_on_side_secondary","Current Power on side Secondary"]
 | |
| );
 | |
| 
 | |
| ##########################################################################
 | |
| # Parse the command line for options and operands 
 | |
| ##########################################################################
 | |
| sub parse_args {
 | |
| #    xCAT::PPCinv::parse_args(@_);
 | |
|     my $request = shift;
 | |
|     my $command = $request->{command};
 | |
|     my $args    = $request->{arg};
 | |
|     my %opt     = ();
 | |
| #    my @rinv    = qw(bus config model serial firm all);
 | |
|     my @rinv    = qw( deconfig firm );
 | |
| 
 | |
|     #############################################
 | |
|     # Responds with usage statement
 | |
|     #############################################
 | |
|     local *usage = sub {
 | |
|         my $usage_string = xCAT::Usage->getUsage($command);
 | |
|         return( [ $_[0], $usage_string] );
 | |
|     };
 | |
|     #############################################
 | |
|     # Process command-line arguments
 | |
|     #############################################
 | |
|     if ( !defined( $args )) {
 | |
|         return(usage( "No command specified" )); 
 | |
|     }
 | |
|     #############################################
 | |
|     # Checks case in GetOptions, allows opts
 | |
|     # to be grouped (e.g. -vx), and terminates
 | |
|     # at the first unrecognized option.
 | |
|     #############################################
 | |
|     @ARGV = @$args;
 | |
|     $Getopt::Long::ignorecase = 0;
 | |
|     Getopt::Long::Configure( "bundling" );
 | |
| 
 | |
|     if ( !GetOptions( \%opt, qw(V|verbose x) )) { 
 | |
|         return( usage() );
 | |
|     }
 | |
|     ####################################
 | |
|     # Check for "-" with no option
 | |
|     ####################################
 | |
|     if ( grep(/^-$/, @ARGV )) {
 | |
|         return(usage( "Missing option: -" ));
 | |
|     }
 | |
|     ####################################
 | |
|     # Unsupported command
 | |
|     ####################################
 | |
|     my ($cmd) = grep(/^$ARGV[0]$/, @rinv );
 | |
|     if ( !defined( $cmd )) {
 | |
|         return(usage( "Invalid command: $ARGV[0]" ));
 | |
|     }
 | |
|     ####################################
 | |
|     # Check for an extra argument
 | |
|     ####################################
 | |
|     shift @ARGV;
 | |
|     if ( defined( $ARGV[0] )) {
 | |
|         return(usage( "Invalid Argument: $ARGV[0]" ));
 | |
|     }
 | |
|     if (exists($opt{x}) and $cmd !~ /^deconfig$/) {
 | |
|         return (usage("Option '-x' can't work with '$cmd'"));
 | |
|     }
 | |
|     ####################################
 | |
|     # Set method to invoke 
 | |
|     ####################################
 | |
|     $request->{method} = $cmd; 
 | |
|     return( \%opt );
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| ##########################################################################
 | |
| # Returns FSP/BPA firmware information
 | |
| ##########################################################################
 | |
| sub firmware {
 | |
| 
 | |
|     my $request = shift;
 | |
|     my $hash    = shift;
 | |
|     my @result;
 | |
|  
 | |
|     # print "in FSPinv \n";
 | |
|     #print Dumper($request);
 | |
|     #print Dumper($hash);
 | |
| 
 | |
|     ####################################
 | |
|     # FSPinv with firm command is grouped by hardware control point
 | |
|     # In FSPinv, the hcp is the related fsp.  
 | |
|     ####################################
 | |
|     
 | |
|     # Example of $hash.    
 | |
|     #VAR1 = {
 | |
|     #	          '9110-51A*1075ECF' => {
 | |
|     #                                   'Server-9110-51A-SN1075ECF' => [
 | |
|     #    	                                                          0,
 | |
|     #		                                                          0,
 | |
|     #                           									  '9110-51A*1075ECF',
 | |
|     #							                            		  'fsp1_name',
 | |
|     #				                            					  'fsp',
 | |
|     #									                               0
 | |
|     #									                               ]
 | |
|     #					                }
 | |
|     # 	   };
 | |
| 
 | |
|     while (my ($mtms,$h) = each(%$hash) ) {
 | |
|         while (my ($name,$d) = each(%$h) ) {
 | |
| 
 | |
|             #####################################
 | |
|             # Command only supported on FSP/BPA/LPARs 
 | |
|             #####################################
 | |
|             if ( @$d[4] !~ /^(cec|frame|fsp|bpa|lpar|blade)$/ ) {
 | |
|                 push @result, 
 | |
|                     [$name,"Information only available for CEC/FSP/Frame/BPA/LPAR",RC_ERROR];
 | |
|                 next; 
 | |
|             }
 | |
| 	       #################
 | |
| 	       #For support on  Lpars, the flag need to be changed.
 | |
| 	       ##########
 | |
| 	       if(@$d[4] eq "lpar")	{
 | |
| 		        @$d[4] = "fsp";
 | |
| 			    @$d[0] = 0;
 | |
| 	       }
 | |
|            my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "list_firmware_level");
 | |
|            my $Rc = @$values[2];
 | |
|    	       my $data = @$values[1];
 | |
|            #print "values";
 | |
|            #print Dumper($values); 
 | |
|            #####################################
 | |
|            # Return error
 | |
|            #####################################
 | |
|            if ( $Rc != SUCCESS ) {
 | |
|                 push @result, [$name,$data,$Rc];
 | |
|                 next; 
 | |
|             }
 | |
|             
 | |
| 	        #####################################
 | |
|             # Format fsp-api results
 | |
|             #####################################
 | |
|             my $val;
 | |
|             foreach $val ( @licmap ) {  
 | |
|                 if ( $data =~ /@$val[0]=(\w+)/ ) {
 | |
|                     push @result, [$name,"@$val[1]: $1",$Rc];
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return( \@result );
 | |
| }
 | |
| 
 | |
| 
 | |
| ##########################################################################
 | |
| # Returns firmware version 
 | |
| ##########################################################################
 | |
| sub firm {
 | |
|     return( firmware(@_) );
 | |
| }
 | |
| 
 | |
| ##########################################################################
 | |
| # Returns serial-number
 | |
| ##########################################################################
 | |
| sub serial {
 | |
| }
 | |
| 
 | |
| sub vpd {
 | |
| }
 | |
| 
 | |
| sub bus {
 | |
| }
 | |
| 
 | |
| sub deconfig {
 | |
| 
 | |
|     my $request = shift;
 | |
|     my $hash    = shift;
 | |
|     my @result;
 | |
|  
 | |
|     # print "in FSPinv \n";
 | |
|     #print Dumper($request);
 | |
|     #print Dumper($hash);
 | |
| 
 | |
|     ####################################
 | |
|     # FSPinv with deconfig command is grouped by hardware control point
 | |
|     # In FSPinv, the hcp is the related fsp.  
 | |
|     ####################################
 | |
|     
 | |
|     # Example of $hash.    
 | |
|     #VAR1 = {
 | |
|     #	          '9110-51A*1075ECF' => {
 | |
|     #                                   'Server-9110-51A-SN1075ECF' => [
 | |
|     #    	                                                          0,
 | |
|     #		                                                          0,
 | |
|     #                           									  '9110-51A*1075ECF',
 | |
|     #							                            		  'fsp1_name',
 | |
|     #				                            					  'fsp',
 | |
|     #									                               0
 | |
|     #									                               ]
 | |
|     #					                }
 | |
|     # 	   };
 | |
| 
 | |
|     while (my ($mtms,$h) = each(%$hash) ) {
 | |
|         while (my ($name,$d) = each(%$h) ) {
 | |
| 
 | |
|             #####################################
 | |
|             # Command only supported on FSP/BPA/LPARs 
 | |
|             #####################################
 | |
|             if ( @$d[4] !~ /^(cec|fsp)$/ ) {
 | |
|                 push @result, 
 | |
|                     [$name,"Deconfigured resource information only available for CEC/FSP",RC_ERROR];
 | |
|                 next; 
 | |
|             }
 | |
| 	    #################
 | |
| 	    #For support on  Lpars, the flag need to be changed.
 | |
| 	    ##########
 | |
| 	    #if(@$d[4] eq "lpar")	{
 | |
| 	    #    @$d[4] = "fsp";
 | |
| 	    #    @$d[0] = 0;
 | |
| 	    #}
 | |
| 	    my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "get_cec_deconfigured");
 | |
| 	    my $Rc = @$values[2];
 | |
| 	    my $data = @$values[1];
 | |
| 	    #print "values";
 | |
|             #print Dumper($values); 
 | |
|             #####################################
 | |
|             # Return error
 | |
|             #####################################
 | |
|             if ( $Rc != SUCCESS ) {
 | |
|                  push @result, [$name,$data,$Rc];
 | |
|                  next; 
 | |
|              }
 | |
|             
 | |
|  
 | |
| 	     #####################################
 | |
|              # Format fsp-api results
 | |
|              #####################################
 | |
|          #my $decfg = XMLin($data);
 | |
|          my $decfg;
 | |
|          eval {
 | |
|              $decfg = XMLin($data);
 | |
|          };
 | |
|          if( $@ ) {
 | |
|              push @result,[$name, "Error: there are some unreadable XML data from the firmware. It can't be parsed by 'xcatd'.", -1];
 | |
|              return (\@result);
 | |
|          }
 | |
|          if( exists($request->{opt}->{x})) {
 | |
|              push @result, [$name, "\n".$data, -1];
 | |
|              next;
 | |
|          }
 | |
| 	#print "decfg";
 | |
|         #print Dumper($decfg); 
 | |
| 	my $node =  $decfg->{NODE};
 | |
| 	if( defined($node) &&  exists($node->{Location_code}) ) {
 | |
|         my $Call_Out_Hardware_State ;
 | |
|         my $Call_Out_Method;
 | |
|         my $Location_code;
 | |
|         my $RID;
 | |
|         my $TYPE;
 | |
|         if(ref($node->{GARDRECORD}) ne "ARRAY") {
 | |
|            push @result,[$name,"NO Deconfigured resources", 0];
 | |
|            return( \@result );
 | |
|         }
 | |
|         push @result,[$name,"Deconfigured resources", 0];
 | |
|         push @result,[$name,"Location_code                RID   Call_Out_Method    Call_Out_Hardware_State   TYPE", 0];
 | |
|         push @result,[$name,"$node->{Location_code}         $node->{RID}", 0];
 | |
|         foreach my $unit(@{$node->{GARDRECORD}}) {
 | |
| 
 | |
| 		while (my ($key, $unit3) = each(%$unit) ) {
 | |
| 
 | |
|                    if($key eq "GARDUNIT") {
 | |
|                        if (ref($unit3) eq "HASH") {
 | |
|                            $Call_Out_Hardware_State = $unit3->{Call_Out_Hardware_State};
 | |
|                            $Call_Out_Method = $unit3->{Call_Out_Method};
 | |
|                            $Location_code = $unit3->{Location_code};
 | |
|                            $RID = $unit3->{RID};
 | |
|                            $TYPE = $unit3->{TYPE};
 | |
| 
 | |
|                            push @result,[$name,"$Location_code     $RID    $Call_Out_Method            $Call_Out_Hardware_State            $TYPE",0];
 | |
|                        } elsif(ref($unit3) eq "ARRAY")  {
 | |
| 
 | |
|                                   foreach my $unit4(@$unit3) {
 | |
|                                      $Call_Out_Hardware_State = $unit4->{Call_Out_Hardware_State};
 | |
|                                      $Call_Out_Method = $unit4->{Call_Out_Method};
 | |
|                                      $Location_code = $unit4->{Location_code};
 | |
|                                      $RID = $unit4->{RID};
 | |
|                                     $TYPE = $unit4->{TYPE};
 | |
|                                      push @result,[$name,"$Location_code     $RID    $Call_Out_Method            $Call_Out_Hardware_State            $TYPE",0];
 | |
|                                   }
 | |
|                        }     
 | |
|                     }                   
 | |
|                  }
 | |
| 
 | |
| 
 | |
|          }
 | |
| 
 | |
|       } else {
 | |
|          push @result,[$name,"NO Deconfigured resources", 0];
 | |
|       } 
 | |
| 
 | |
| 	         
 | |
|         }
 | |
|     }
 | |
|     return( \@result );
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| ##########################################################################
 | |
| # Returns machine-type-model
 | |
| ##########################################################################
 | |
| sub model {
 | |
| }
 | |
| 
 | |
| ##########################################################################
 | |
| # Returns all inventory information
 | |
| ##########################################################################
 | |
| sub all {
 | |
| 
 | |
|     my @result = ( 
 | |
|         @{deconfig(@_)},
 | |
|         @{firmware(@_)} 
 | |
|     );       
 | |
|     return( \@result );
 | |
| }
 | |
| 
 | |
| 
 | |
| 1;
 | |
| 
 | |
| 
 |