# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html package xCAT::FSPbootseq; use Socket; use strict; use Getopt::Long; use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); use xCAT::NetworkUtils; use xCAT::FSPUtils; use xCAT::MsgUtils qw(verbose_message); #use Data::Dumper; ########################################################################## # Parse the command line for options and operands ########################################################################## sub parse_args { my $request = shift; my %opt = (); my $cmd = $request->{command}; my $args = $request->{arg}; my $node = $request->{node}; my $vers = my @VERSION = qw( 2.6 ); my @dev = qw(hfi net); ############################################# # Responds with usage statement ############################################# local *usage = sub { my $usage_string = xCAT::Usage->getUsage($cmd); return( [ $_[0], $usage_string] ); }; ############################################# # Process command-line arguments ############################################# if ( !defined( $args )) { return(usage( "Missing command with rbootseq in DFM, net or hfi ?" )); } ############################################# # 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(h|help V|verbose v|version ))) { return( usage() ); } #################################### # Option -h for Help #################################### #if ( exists( $opt{h} )) { # return( usage() ); #} #################################### # Option -v for version #################################### if ( exists( $opt{v} )) { return( \@VERSION ); } #################################### # Check for "-" with no option #################################### #if ( grep(/^-$/, @ARGV )) { # return(usage( "Missing option: -" )); #} #################################### # Check for an extra argument #################################### #if ( defined( $ARGV[0] )) { # return(usage( "Invalid Argument: $ARGV[0]" )); #} my $command = grep(/^$ARGV[0]$/, @dev ); if ( !defined( $command )) { return(usage( "Invalid command: $ARGV[0]" )); } if( $ARGV[0] =~/^hfi$/) { $opt{hfi} = 1; } elsif ( $ARGV[0] =~/^net$/) { $opt{net} = 1; } else { return(usage( "Invalid Argument: $ARGV[0]" )); } shift @ARGV; if ( defined( $ARGV[0] )) { return(usage( "Invalid Argument: $ARGV[0]" )); } #print "in parse_args:\n"; #print $command; #print Dumper(\%opt); my $nodetype = xCAT::DBobjUtils->getnodetype($$node[0], "ppc"); if( $nodetype =~ /^blade$/) { $request->{callback}->({data =>[ "After running rebootseq on the nodes successfully, it's required to run to make the setting be permanent"]}); } #################################### # Set method to invoke #################################### $request->{method} = $cmd; return( \%opt ); } ########################################################################## # set hfi/eth boot string ########################################################################## sub rbootseq { my $request = shift; my $d = shift; my $opt = $request->{opt}; my @output ; my $tooltype = 0; my $parameter; my $bootp_retries = 5; my $tftp_retries = 5; my $blksize = 512; my $hash; my $node_name = @$d[6]; my $o = @$d[7]; #print "in setbootseq:\n"; #print "request\n"; #print Dumper($request); #print "d"; #print Dumper($d); xCAT::MsgUtils->verbose_message($request, "rbootseq START for node:$node_name, type=$$d[4]."); if (!($$d[4] =~ /^(lpar|blade)$/)) { push @output, [$node_name, "\'boot\' command not supported for CEC or BPA", -1 ]; return (\@output); } # add checking the power state of the cec xCAT::MsgUtils->verbose_message($request, "rbootseq check machine state for node:$node_name."); my $power_state = xCAT::FSPUtils::fsp_api_action ($request, $node_name, $d, "cec_state", $tooltype); if ( @$power_state[2] != 0 ) { push @output, [$node_name, @$power_state[1], -1 ]; return (\@output); } unless (@$power_state[1] and @$power_state[1] =~ /operating|standby/) { my $machine; my $state; if ($$d[4] eq 'blade') { $machine = "blade"; $state = "on"; } else { $machine = "CEC"; $state = "power on"; } push @output, [$node_name, "\'boot\' command can only support while the $machine is in the \'$state\' state", -1]; return (\@output); } if( $opt->{net} ) { my $mactab = xCAT::Table->new( 'mac'); unless($mactab) { push @output, [$node_name, "Cannot open mac table", -1 ]; return (\@output); } my $mac_hash = $mactab->getNodeAttribs( $node_name,[qw(mac)]); my $mac = $mac_hash->{mac}; if( !defined($mac) ) { push @output, [$node_name, "No mac address in mac table", -1 ]; } $mactab->close(); if( $mac =~ /\| /) { #01:02:03:04:05:0E!node5|01:02:03:05:0F!node6-eth1 my @mac_t = split(/\|/,$mac); my $m; my $m_t; foreach $m (@mac_t) { if(($m =~ /([\w:]{12})!$node_name/) || ($m =~ /([\w:]{17})!$node_name/)) { $m_t = $1; last; } } if( !defined($m_t)) { $mac = $mac_t[0]; } else { $mac = $m_t; } } if( $mac =~ /\:/) { $mac =~ s/\://g; } if($mac =~/^(\w{12})$/) { $parameter = "mac=$mac:speed=auto,duplex=auto,$o->{server},,$o->{client},$o->{gateway},$bootp_retries,$tftp_retries,$o->{netmask},$blksize"; } else { push @output, [$node_name, "The mac address in mac table could NOT be used for rbootseq with -net. HFI mac , or other wrong format?", -1 ]; return( \@output ); } xCAT::MsgUtils->verbose_message($request, "rbootseq <$node_name> net=$parameter"); } if( $opt->{hfi}) { $parameter = "/hfi-iohub/hfi-ethernet:$o->{server},,$o->{client},$o->{gateway},$bootp_retries,$tftp_retries,$o->{netmask},$blksize"; xCAT::MsgUtils->verbose_message($request, "rbootseq <$node_name> hfi=$parameter"); } xCAT::MsgUtils->verbose_message($request, "rbootseq set_lpar_bootstring for node:$node_name."); my $res = xCAT::FSPUtils::fsp_api_action ($request, $node_name, $d, "set_lpar_bootstring", $tooltype, $parameter); #print "In boot, state\n"; #print Dumper($res); my $Rc = @$res[2]; my $data = @$res[1]; ################################## # Output error ################################## xCAT::MsgUtils->verbose_message($request, "rbootseq return:$Rc."); if ( $Rc != SUCCESS ) { push @output, [$node_name,$data,$Rc]; } else { push @output,[$node_name, "Success", 0]; } return( \@output ); } 1;