HMC alternative: FSPflash (firmware upgrade -- disruptive ,commit, recover)
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4842 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										648
									
								
								perl-xCAT/xCAT/FSPflash.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										648
									
								
								perl-xCAT/xCAT/FSPflash.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,648 @@ | ||||
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html | ||||
|  | ||||
| package xCAT::FSPflash; | ||||
| use strict; | ||||
| use Getopt::Long; | ||||
| use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); | ||||
| use xCAT::Usage; | ||||
| use xCAT::PPCinv; | ||||
| use xCAT::DSHCLI; | ||||
| use xCAT::Table; | ||||
| use Getopt::Long; | ||||
| use File::Spec; | ||||
| use xCAT::PPCrflash; | ||||
| use Data::Dumper; | ||||
| use xCAT::Utils; | ||||
| use xCAT::FSPinv; | ||||
| use POSIX "WNOHANG"; | ||||
| use Storable qw(freeze thaw); | ||||
| use Thread qw(yield); | ||||
|  | ||||
| my $packages_dir= (); | ||||
| my $activate	= (); | ||||
| my $verbose	= 0; | ||||
| $::POWER_DEST_DIR               = "/tmp"; | ||||
| my $release_level; | ||||
| my $active_level; | ||||
| my @dirlist; | ||||
|  | ||||
| ####################################### | ||||
| # This flag tracks the operation to be performed.  If set, it means we need | ||||
| # to commit a previously applied update or else recover from one. | ||||
| ####################################### | ||||
| my $housekeeping = undef; | ||||
|  | ||||
| ##################################### | ||||
| #For -V|--verbose,put the $msg into @value | ||||
| ################################### | ||||
| sub dpush { | ||||
| 	my $value = shift; | ||||
| 	my $msg = shift; | ||||
|  | ||||
| 	if($verbose == 1) { | ||||
| 		push(@$value,$msg); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ########################################################################## | ||||
| # Parse the command line for options and operands  | ||||
| ########################################################################## | ||||
| sub parse_args { | ||||
|     xCAT::PPCrflash::parse_args(@_); | ||||
| } | ||||
|  | ||||
| ########################################################################## | ||||
| # Invokes the callback with the specified message                     | ||||
| ########################################################################## | ||||
| sub send_msg { | ||||
|  | ||||
|     my $request = shift; | ||||
|     my $ecode   = shift; | ||||
|     my %output; | ||||
|  | ||||
|     ################################################# | ||||
|     # Called from child process - send to parent | ||||
|     ################################################# | ||||
|     if ( exists( $request->{pipe} )) { | ||||
|         my $out = $request->{pipe}; | ||||
|  | ||||
|         $output{errorcode} = $ecode; | ||||
|         $output{data} = \@_; | ||||
|         print $out freeze( [\%output] ); | ||||
|         print $out "\nENDOFFREEZE6sK4ci\n"; | ||||
|     } | ||||
|     ################################################# | ||||
|     # Called from parent - invoke callback directly | ||||
|     ################################################# | ||||
|     elsif ( exists( $request->{callback} )) { | ||||
|         my $callback = $request->{callback}; | ||||
|  | ||||
|         $output{errorcode} = $ecode; | ||||
|         $output{data} = \@_; | ||||
|         $callback->( \%output ); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| #-------------------------------------------------------------------------# | ||||
| # get_lic_filenames - construct and validate the lup filenames for each   # | ||||
| # each node                                                               # | ||||
| #-------------------------------------------------------------------------# | ||||
| # | ||||
| sub get_lic_filenames { | ||||
| 	my $mtms = shift; | ||||
| 	my $upgrade_required = 0;	 | ||||
| 	my $msg = undef; | ||||
| 	my $filename; | ||||
|  | ||||
| 	if(! -d $packages_dir) { | ||||
|               $msg = "The directory $packages_dir doesn't exist!"; | ||||
|               return ("","","", $msg, -1); | ||||
|         } | ||||
|          | ||||
| 	#print "opening directory and reading names\n"; | ||||
|         opendir DIRHANDLE, $packages_dir; | ||||
|         @dirlist= readdir DIRHANDLE; | ||||
|         closedir DIRHANDLE; | ||||
|  | ||||
|         @dirlist = File::Spec->no_upwards( @dirlist ); | ||||
|  | ||||
|         # Make sure we have some files to process | ||||
|         # | ||||
|         if( !scalar( @dirlist ) ) { | ||||
|         	$msg = "directory $packages_dir is empty"; | ||||
|                 return ("","","",$msg, -1); | ||||
|         } | ||||
|  | ||||
|         $release_level =~/(\w{4})(\d{3})/; | ||||
|         my $pns = $1; | ||||
| 	my $fff = $2; | ||||
| 		 | ||||
| 	#Find the latest version lic file | ||||
|         @dirlist = grep /\.rpm$/, @dirlist; | ||||
|         @dirlist = grep /$1/, @dirlist; | ||||
|         if( !scalar( @dirlist ) ) { | ||||
| 		$msg = "There isn't a package suitable for $mtms"; | ||||
|                 return ("","","",$msg, -1); | ||||
| 	} | ||||
|         if( scalar(@dirlist) > 1) { | ||||
|          # Need to find the latest version package. | ||||
|         	@dirlist =reverse sort(@dirlist); | ||||
|                 my $t = "\n"; | ||||
|                 foreach $t(@dirlist) { | ||||
|                        $msg =$msg."$t\t"; | ||||
|                 } | ||||
|          } | ||||
|  | ||||
|          $filename = File::Spec->catfile( $packages_dir, $dirlist[0] ); | ||||
|          $dirlist[0] =~ /(\w{4})(\d{3})_(\w{3})_(\d{3}).rpm$/; | ||||
|     	############## | ||||
|     	#If the release levels are different, it will be upgrade_required. | ||||
|     	############# | ||||
|     	if($fff ne $2) { | ||||
| 	    	$upgrade_required = 1; | ||||
|     	} else { | ||||
|  | ||||
|        	 if(($pns eq $1) && ($4 <= $active_level)) { | ||||
|     		$msg = $msg. "Upgrade $mtms $activate!"; | ||||
| 	#	if($activate ne "concurrent") { | ||||
| 	#		$msg = "Option --actviate's value should be disruptive"; | ||||
| 	#		return ("", "","", $msg, -1); | ||||
| 	#	} | ||||
| 	  } else { | ||||
| 		$msg = $msg . "Upgrade $mtms disruptively!"; | ||||
|            if($activate ne "disruptive") { | ||||
| 	    		$msg = "Option --activate's value shouldn't be concurrent, and it must be disruptive"; | ||||
| 			return ("", "","", $msg, -1); | ||||
| 		} | ||||
|        	 }  | ||||
| 	} | ||||
|         #print "filename is $filename\n"; | ||||
| 	my $xml_file_name = $filename; | ||||
| 	$xml_file_name =~ s/(.+\.)rpm/\1xml/; | ||||
| 	#print "check_licdd_update: source xml file is $xml_file_name\n"; | ||||
|  | ||||
| 	if( ( -z $filename)|| ( -z $xml_file_name) ) { | ||||
| 		$msg = "The package $filename or xml $xml_file_name is empty" ; | ||||
| 		return ("", "", "", $msg, -1); | ||||
| 	} | ||||
| 		 | ||||
| 	return ($filename, $xml_file_name ,$upgrade_required, $msg, 0); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| sub get_one_mtms { | ||||
| 	my $exp = shift; | ||||
|         my $bpa = shift; | ||||
|         my $cmd = "lssyscfg -r cage -e $bpa"; | ||||
|         my $mtms; | ||||
|         my $msg; | ||||
|  | ||||
|         my $values = xCAT::PPCcli::send_cmd( $exp, $cmd ); | ||||
|         my $Rc = shift(@$values); | ||||
|  | ||||
|         ##################################### | ||||
|         # Return error | ||||
|         ##################################### | ||||
|         if ( $Rc != SUCCESS ) { | ||||
|                 $msg = "ERROR: Failed to find a CEC managed by $bpa on the HMC"; | ||||
|                 return ("", $msg); | ||||
|         } | ||||
|  | ||||
|         foreach (@$values) { | ||||
|                 if( $_ =~ /cage_num=(\w*),contents=sys,type_model_serial_num=(\w+)-(\w+)\*(\w+),loc_code=(\w+).(\w+).(\w+)/) { | ||||
|                         $mtms = "$2-$3*$4"; | ||||
|                         last; | ||||
|                 } | ||||
|         } | ||||
|  | ||||
| 	 | ||||
| 	#print "the managed system is $mtms!\n"; | ||||
| 	return ($mtms, $msg);	 | ||||
| } | ||||
|  | ||||
| sub process_node { | ||||
| 	my $req = shift; | ||||
| 	my $node    = shift; | ||||
|  | ||||
| 	my $tab = xCAT::Table->new("vpd"); | ||||
| 	my $msg; | ||||
| 	unless ($tab) { | ||||
| 		$msg = "ERROR: Unable to open basic ppc table for configuration"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
|         | ||||
| 	print "in process_node1, node $node\n"; | ||||
| 	print Dumper($node); | ||||
| 	my $ent = $tab->getNodeAttribs($node, ['serial', 'mtm']);	 | ||||
| 	print "in process_node\n"; | ||||
| 	print Dumper($ent); | ||||
|  | ||||
| 	my $serial = $ent->{'serial'}; | ||||
| 	my $mtm	   = $ent->{'mtm'}; | ||||
| 	################################# | ||||
| 	#Get node | ||||
| 	################################# | ||||
| 	print "in get_related_fsp_bpa(), serial = $serial, mtm= $mtm\n"; | ||||
| 	my @ents = $tab->getAllAttribsWhere("serial=\"$serial\" and mtm=\"$mtm\"", 'node'); | ||||
| 	if (@ents < 0) { | ||||
| 		$msg = "failed to get the FSPs or BPAs whose mtm is $mtm, serial is $serial!"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
| 	my $e; | ||||
| 	print Dumper(@ents); | ||||
| 	foreach $e (@ents) { | ||||
| 		if($e->{node} ne $node) { | ||||
| #			push @{$req->{node}},$e->{node}; | ||||
| 			push @{$req->{noderange}},$e->{node}; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| sub get_related_fsp_bpa { | ||||
| 	my $mtm    = shift; | ||||
| 	my $serial = shift; | ||||
| 	my $tab = xCAT::Table->new("vpd"); | ||||
| 	my $msg; | ||||
| 	unless ($tab) { | ||||
| 		$msg = "ERROR: Unable to open basic ppc table for configuration"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
| 	################################# | ||||
| 	#Get node | ||||
| 	################################# | ||||
| 	print "in get_related_fsp_bpa(), serial = $serial, mtm= $mtm\n"; | ||||
| 	my @ent = $tab->getAllAttribsWhere("serial=\"$serial\" and mtm=\"$mtm\"", 'node'); | ||||
| 	if (@ent < 0) { | ||||
| 		$msg = "failed to get the FSPs or BPAs whose mtm is $mtm, serial is $serial!"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
| 	return(\@ent); | ||||
|  | ||||
| } | ||||
|  | ||||
| sub get_hcp_id { | ||||
| 	my $node = shift; | ||||
| 	 | ||||
| 	my $tab = xCAT::Table->new("ppc"); | ||||
| 	my $msg; | ||||
| 	unless ($tab) { | ||||
| 		$msg = "ERROR: Unable to open basic ppc table for configuration"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
| 	################################# | ||||
| 	#Get node | ||||
| 	################################# | ||||
| 	my @ent = $tab->getNodeAttribs($node, ['hcp', 'id']);	 | ||||
| 	if (@ent < 0) { | ||||
| 		$msg = "failed to get the hcp and id of $node!"; | ||||
| 		return ("", $msg); | ||||
| 	} | ||||
| 	return($ent[0]->{hcp}, $ent[0]->{id}); | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ########################################################################## | ||||
| # Forks a process to run the action command | ||||
| ########################################################################## | ||||
| sub fork_cmd { | ||||
|  | ||||
|     my $node_name    = shift; | ||||
|     my $attrs  	     = shift; | ||||
|     my $action       = shift; | ||||
|     my $pipe ; | ||||
|      | ||||
|     ####################################### | ||||
|     # Pipe childs output back to parent | ||||
|     ####################################### | ||||
|     my $parent; | ||||
|     my $child; | ||||
|     pipe $parent, $child; | ||||
|     my $pid = xCAT::Utils->xfork; | ||||
|     my $res; | ||||
|  | ||||
|     if ( !defined($pid) ) { | ||||
|         ################################### | ||||
|         # Fork error | ||||
|         ################################### | ||||
|         print "Fork error:!"; | ||||
|         return undef; | ||||
|     } | ||||
|     elsif ( $pid == 0 ) { | ||||
|         ################################### | ||||
|         # Child process | ||||
|         ################################### | ||||
|         close( $parent ); | ||||
|         $pipe = $child; | ||||
|  | ||||
|         $res = action( $node_name, $attrs, $action ); | ||||
| 	print "res\n"; | ||||
| 	print Dumper($res); | ||||
| 	my %output; | ||||
| 	$output{node} = $node_name; | ||||
| 	$output{ret} = @$res[2]; | ||||
| 	$output{contents} = @$res[1]; | ||||
| #	print $pipe %output; | ||||
| #	print $pipe freeze(\%output); | ||||
| 	my @outhash; | ||||
| 	push @outhash,\%output; | ||||
| 	print $pipe freeze([@outhash]); | ||||
| #	print $pipe "good";	 | ||||
| 	print $pipe "\nENDOFFREEZE6sK4ci\n"; | ||||
| 	exit(0); | ||||
|     } | ||||
|     else { | ||||
|         ################################### | ||||
|         # Parent process | ||||
|         ################################### | ||||
|         close( $child ); | ||||
|         return( $parent, $pid ); | ||||
|     } | ||||
|     return(0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| sub action { | ||||
|     my $node_name  = shift; | ||||
|     my $attrs      = shift; | ||||
|     my $action     = shift; | ||||
| #    my $user 	   = "HMC"; | ||||
| #    my $password   = "abc123"; | ||||
|     my $fsp_api    ="/home/fsp-api";  | ||||
|     my $id         = 1; | ||||
|     my $fsp_name   = (); | ||||
|     my $fsp_ip     = (); | ||||
|     my $target_list=(); | ||||
|     my $type = (); # fsp|lpar -- 0. BPA -- 1 | ||||
|     my @result; | ||||
|     my $Rc = 0 ; | ||||
|     my %outhash = (); | ||||
|     my $res;     | ||||
|      | ||||
|     $id = $$attrs[0]; | ||||
|     $fsp_name = $$attrs[3];  | ||||
|  | ||||
|     my %objhash = ();  | ||||
|     $objhash{$fsp_name} = "node"; | ||||
|     my %myhash      = xCAT::DBobjUtils->getobjdefs(\%objhash); | ||||
|     my $password    = $myhash{$fsp_name}{"passwd.hscroot"}; | ||||
|     print "fspname:$fsp_name password:$password\n"; | ||||
|     print Dumper(%myhash); | ||||
|     if(!$password ) { | ||||
| 	$res = "The password.hscroot of $fsp_name in ppcdirect table is empty"; | ||||
| 	return ([$node_name, $res, -1]); | ||||
|     } | ||||
|     #   my $user = "HMC"; | ||||
|     my $user = "hscroot"; | ||||
| #    my $cred = $request->{$fsp_name}{cred}; | ||||
| #    my $user = @$cred[0]; | ||||
| #    my $password = @$cred[1]; | ||||
|       | ||||
|     if($action =~ /^commit$/) { $action = "code_commit"} | ||||
|     if($action =~ /^recover$/) { $action = "code_reject"} | ||||
|     if($action =~ /^disruptive$/) { $action = "code_update"} | ||||
|     if($action =~ /^concurrent$/) { | ||||
|         $res = "\'$action\' option not supported in FSPflash.Please use disruptive mode"; | ||||
|         return ([$node_name, $res, -1]); | ||||
|     } | ||||
|    | ||||
|      | ||||
|     if($$attrs[4] =~ /^fsp$/) { | ||||
|         $type = 0; | ||||
|         $id = 0; | ||||
|     } else {  | ||||
| 	$type = 1; | ||||
|     }  | ||||
|  | ||||
|     ############################ | ||||
|     # Get IP address | ||||
|     ############################ | ||||
|     $fsp_ip = xCAT::Utils::get_hdwr_ip($fsp_name); | ||||
|     if($fsp_ip == -1) { | ||||
|         $res = "Failed to get the $fsp_name\'s ip"; | ||||
|         return ([$node_name, $res, -1]);	 | ||||
|     } | ||||
| 	 | ||||
|     print "fsp name: $fsp_name\n"; | ||||
|     print "fsp ip: $fsp_ip\n"; | ||||
|  | ||||
|     my $cmd = "$fsp_api -a $action -u $user -p $password -t $type:$fsp_ip:$id:$node_name: -d /install/packages_fw/"; | ||||
|  | ||||
|     print "cmd: $cmd\n";  | ||||
|     $SIG{CHLD} = ();  | ||||
|     my $res = xCAT::Utils->runcmd($cmd, -1); | ||||
|     #my $res = "good";  | ||||
|     $Rc = $::RUNCMD_RC; | ||||
|     #$Rc = -1; | ||||
|     ################## | ||||
|     # output the prompt | ||||
|     ################# | ||||
|     #$outhash{ $node_name } = $res; | ||||
|       | ||||
|     return( [$node_name,$res, $Rc] );  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ########################## | ||||
| #Performs Licensed Internal Code (LIC) update support for HMC-attached POWER5 and POWER6 Systems | ||||
| ########################### | ||||
| sub rflash { | ||||
|  | ||||
|     my $request = shift; | ||||
|     my $hash    = shift; | ||||
|     my $exp     = shift; | ||||
|     my $subreq  = $request->{subreq}; | ||||
|     my $hwtype  = @$exp[2]; | ||||
|     my @result; | ||||
|     my $timeout    = $request->{ppctimeout}; | ||||
|     my $housekeeping = $request->{housekeeping}; | ||||
|     $packages_dir = $request->{opt}->{p}; | ||||
|     $activate = $request->{opt}->{activate};	 | ||||
|  | ||||
|     my $mtms; | ||||
|     my $h; | ||||
|     my $user; | ||||
| 	 | ||||
|     my $tmp_file; #the file handle of the stanza | ||||
|     my $rpm_file; | ||||
|     my $xml_file; | ||||
|     my @rpm_files; | ||||
|     my @xml_files; | ||||
|     my $upgrade_required; | ||||
|     my $stanza = undef; | ||||
|     my $mtms_t;	 | ||||
|     my @value; | ||||
|     my %infor; | ||||
|     my $role ; #0x01: BPC A, BPC B; 0x01: Primary or only FSP, 0x02: Backup FSP | ||||
|   | ||||
|     print "in Directflash \n"; | ||||
|     print Dumper($request); | ||||
|     print Dumper($hash); | ||||
|  | ||||
|     #################################### | ||||
|     # Power commands are grouped by hardware control point | ||||
|     # In Direct attach support, the hcp is the related fsp.   | ||||
|     #################################### | ||||
|      | ||||
|     # Example of $hash.     | ||||
|     #VAR1 = { | ||||
|     #	          '9110-51A*1075ECF' => { | ||||
|     #                                   'Server-9110-51A-SN1075ECF' => [ | ||||
|     #    	                                                          0, | ||||
|     #		                                                          0, | ||||
|     #									  '9110-51A*1075ECF', | ||||
|     #									  'Server-9110-51A-SN1075ECF', | ||||
|     #									  'fsp', | ||||
|     #									  0 | ||||
|     #									  ] | ||||
|     #					 } | ||||
|     # 	   }; | ||||
|     my $flag = 0; | ||||
|     my $flag2 = 0; | ||||
|     while (my ($mtms,$h) = each(%$hash) ) { | ||||
| 	# | ||||
| 	#For one mtms, it just needs to do the operation one time. | ||||
| 	# | ||||
|         $flag += 1; | ||||
| 	if($flag > 1) { | ||||
| 	    last;	 | ||||
| 	}	 | ||||
| 	 | ||||
| 	$mtms =~ /(\w+)-(\w+)\*(\w+)/; | ||||
| 	my $mtm    = "$1-$2"; | ||||
| 	my $serial = $3; | ||||
| 		 | ||||
| 	 | ||||
|         while (my ($name,$d) = each(%$h) ) { | ||||
|        	    $flag2 += 1; | ||||
| 	    if($flag2 > 1) { | ||||
| 	        last;	 | ||||
|  	    } | ||||
|             my $values  = xCAT::FSPinv::action( $name, $d, "list_firmware_level");  | ||||
| 	    # my $level = xCAT::PPCcli::lslic( $exp, $d, $timeout ); | ||||
|             my $Rc = shift(@$values); | ||||
| 	    my $level = $$values[0]->{$name}; | ||||
| 	    ##################################### | ||||
| 	    # Return error | ||||
|       	    ##################################### | ||||
|            if ( $Rc != SUCCESS ) { | ||||
|                 push @value, [$name,$level,$Rc]; | ||||
|                 next; | ||||
|            } | ||||
|              | ||||
| 	   if (( $level =~ /curr_level_primary/ ) || ( $level =~ /curr_level_a/ )) { | ||||
|                 $role = 0x01; | ||||
| 	   } else { | ||||
| 	  	$role = 0x02;  | ||||
| 	   } | ||||
| 	   	    | ||||
| 	   if ( $level =~ /ecnumber=(\w+)/ ) { | ||||
|                 $release_level = $1; | ||||
|                 &dpush( \@value, [$name,"$mtms :release level:$1"]); | ||||
| 	   } | ||||
| 				 | ||||
| 	   if ( $level =~ /activated_level=(\w+)/ ) { | ||||
|                 $active_level = $1; | ||||
|                 &dpush( \@value, [$name,"$mtms :activated level:$1"]); | ||||
| 	   }	 | ||||
| 	    | ||||
| 	   my $msg;	 | ||||
| 	   if(!defined($housekeeping)) {	    | ||||
| 	   my $flag = 0;	 | ||||
| 	   ($rpm_file, $xml_file, $upgrade_required,$msg, $flag) = &get_lic_filenames($mtms); | ||||
| 	   if( $flag == -1) { | ||||
| 		push (@value, [$name,"$mtms: $msg"]); | ||||
| 	        push (@value, [$name,"Failed to upgrade the firmware of $name"]); | ||||
| 		return (\@value); | ||||
| 	   } | ||||
| 	   dpush ( \@value, [$name, $msg]); | ||||
| 	   } | ||||
| 	   my $nodes = get_related_fsp_bpa( $mtm, $serial); | ||||
| 	   print Dumper($nodes);  | ||||
| 	   my $i     = 0; | ||||
| 	   my $flag  = 0; | ||||
| 	   my $c = @$nodes; | ||||
| 	   my $name2 = undef; | ||||
| 	   if ($c == 1 && $role == 0x01 ) { | ||||
| 			 | ||||
| 	   } | ||||
| 	   if ($c == 1 && $role == 0x02 ) { | ||||
| 	    | ||||
|                 push(@result,[$name, "$name\'s role is  Backup FSP or BPC side B). Please configure the Primary FSP or BPC side A.", -1]);  | ||||
| 	   } | ||||
| 	   if($c == 2 && $role == 0x01 ) { | ||||
| 	   	if($$nodes[0]->{node} eq $name) { | ||||
| 			$i = 0; | ||||
| 			$name2 = $$nodes[1]->{node};  #Secondary FSP or BPC side B. | ||||
| 		} else { | ||||
| 			$name2 = $name;          #Secondary FSP or BPC side B. | ||||
| 			$name  = $$nodes[1]->{node}; #the Primary FSP or BPC side A. | ||||
| 		} | ||||
| 	   } | ||||
|  | ||||
| 	   if($c ==2 && $role == 0x02) { | ||||
| 	  	if($$nodes[0]->{node} eq $name) { | ||||
| 			$name2 = $name; # Secondary FSP or BPC side B. | ||||
| 			$name  = $$nodes[1]->{node};#the Primary FSP or BPC side A. | ||||
| 		} else { | ||||
| 			$name2 = $$nodes[1]->{node};  #Secondary FSP or BPC side B. | ||||
| 		}  | ||||
| 	   } | ||||
| 	   print "name: $name, name2: $name2\n"; | ||||
| 	   | ||||
| 	   my $children = 0;  | ||||
| 	   $SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) {print "child exit\n";$children--;} };  | ||||
| 	   my $fds = new IO::Select; | ||||
|  	   my $pipe; | ||||
| 	   if(defined($name2) ) { | ||||
| 		my($hcp, $id) = get_hcp_id($name2); | ||||
| 		my @dt = ($id, @$d[1], $mtms, $hcp, @$d[4], 0); | ||||
| 	    | ||||
|      		if( defined( $housekeeping ) ) { | ||||
|                     ($pipe) = fork_cmd( $name2, \@dt, $housekeeping ); | ||||
| 	       	 | ||||
| 	        } else { | ||||
| 	            ($pipe) = fork_cmd( $name2, \@dt, $activate); | ||||
| 	        } | ||||
|                 if ( $pipe ) { | ||||
| 	            $fds->add( $pipe ); | ||||
| 		    $children++; | ||||
| 	        } | ||||
| 	        sleep(5);  | ||||
|            } | ||||
| 	   $pipe = undef;   | ||||
| 	   if( defined( $housekeeping ) ) { | ||||
| 	        ($pipe) = fork_cmd( $name, $d, $housekeeping ); | ||||
| 	       	 | ||||
| 	   } else { | ||||
| 	        ($pipe) = fork_cmd( $name, $d, $activate ); | ||||
| 	   } | ||||
|            if ( $pipe ) { | ||||
| 	        $fds->add( $pipe ); | ||||
| 		$children++; | ||||
| 	   } | ||||
| 	   print "count:\n"; | ||||
| 	   print $fds->count; | ||||
| 	   print "children:$children\n"; | ||||
| 	   while ( $fds->count > 0 or $children > 0 ) { | ||||
| 	        my @ready_fds = $fds->can_read(1); | ||||
| 		foreach my $rfh (@ready_fds) { | ||||
| 		     my $val = <$rfh>; | ||||
| 		     if( defined($val)) { | ||||
| 		         while($val !~ /ENDOFFREEZE6sK4ci/) { | ||||
| 		             $val .=  <$rfh>; | ||||
| 			 }  | ||||
| 			 my $resp = thaw($val); | ||||
| 			 foreach my $t( @$resp ) { | ||||
| 			    print Dumper($t); | ||||
| 			    push @result, [$t->{node}, $t->{contents}, $t->{ret}]; | ||||
| 		         } | ||||
| 			 next; | ||||
| 		    } | ||||
| 		    $fds->remove($rfh); | ||||
| 		    close($rfh); | ||||
| 	        } | ||||
|        	   }		    | ||||
| 	          | ||||
|         } | ||||
|     } | ||||
|     push(@value, @result); | ||||
|     return (\@value);	 | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| 1; | ||||
|  | ||||
|  | ||||
| @@ -94,7 +94,7 @@ sub firmware { | ||||
|             # Return error | ||||
|             ##################################### | ||||
|             if ( $Rc != SUCCESS ) { | ||||
|                 push @result, [$name,@$values[0],$Rc]; | ||||
|                 push @result, [$name,$data->{$name},$Rc]; | ||||
|                 next;  | ||||
|             } | ||||
|              | ||||
|   | ||||
| @@ -11,7 +11,7 @@ use xCAT::Table; | ||||
| use Getopt::Long; | ||||
| use File::Spec; | ||||
| use POSIX qw(tmpnam); | ||||
| use xCAT::FSPflash.pm; | ||||
| use xCAT::FSPflash; | ||||
|  | ||||
|  | ||||
| my $packages_dir= (); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user