From 2779f579e12c86d13895b8bb3780ad18a204aa9b Mon Sep 17 00:00:00 2001 From: linggao Date: Wed, 25 Mar 2009 02:56:58 +0000 Subject: [PATCH] performance tuning for node status updating for ipmi, blade,PPC, xen and kvm git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2976 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/perl/xCAT/PPC.pm | 129 ++++++++++++--------- xCAT-server/lib/perl/xCAT/SvrUtils.pm | 3 - xCAT-server/lib/xcat/plugins/aixinstall.pm | 15 ++- xCAT-server/lib/xcat/plugins/blade.pm | 93 +++++++++------ xCAT-server/lib/xcat/plugins/ipmi.pm | 111 ++++++++++++------ xCAT-server/lib/xcat/plugins/kvm.pm | 95 +++++++++------ xCAT-server/lib/xcat/plugins/pxe.pm | 12 +- xCAT-server/lib/xcat/plugins/xen.pm | 96 +++++++++------ xCAT-server/lib/xcat/plugins/yaboot.pm | 11 +- 9 files changed, 354 insertions(+), 211 deletions(-) diff --git a/xCAT-server/lib/perl/xCAT/PPC.pm b/xCAT-server/lib/perl/xCAT/PPC.pm index d2083afde..e2d192362 100644 --- a/xCAT-server/lib/perl/xCAT/PPC.pm +++ b/xCAT-server/lib/perl/xCAT/PPC.pm @@ -124,9 +124,9 @@ sub process_command { } #get new node status - my %nodestat=(); + my %oldnodestatus=(); #saves the old node status + my @allerrornodes=(); my $check=0; - my $newstat; my $global_check=1; if ($sitetab) { (my $ref) = $sitetab->getAttribs({key => 'nodestatus'}, 'value'); @@ -135,51 +135,58 @@ sub process_command { } } - if ($request->{command} eq 'rpower') { - my $subcommand=$request->{op}; + my $command=$request->{command}; + if (($command eq 'rpower') || ($command eq 'rnetboot')) { + my $subcommand="temp"; + if ($command eq 'rpower') { $subcommand=$request->{op}; } if (($global_check) && ($subcommand ne 'stat') && ($subcommand ne 'status') && ($subcommand ne 'state')) { - $check=1; + $check=1; my $noderange = $request->{node}; my @allnodes=@$noderange; - - if ($subcommand eq 'off') { $newstat=$::STATUS_POWERING_OFF; } - else { $newstat=$::STATUS_BOOTING;} - foreach (@allnodes) { $nodestat{$_}=$newstat; } - - if ($subcommand ne 'off') { + + #save the old status + my $nodelisttab = xCAT::Table->new('nodelist'); + if ($nodelisttab) { + my $tabdata = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']); + foreach my $node (@allnodes) + { + my $tmp1 = $tabdata->{$node}->[0]; + if ($tmp1) { + if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; } + else { $oldnodestatus{$node}=""; } + } + } + } + #print "oldstatus:" . Dumper(\%oldnodestatus); + + #set the new status to the nodelist.status + my %newnodestatus=(); + my $newstat; + if (($subcommand eq 'off') || ($subcommand eq 'softoff')) { + my $newstat=$::STATUS_POWERING_OFF; + $newnodestatus{$newstat}=\@allnodes; + } else { #get the current nodeset stat if (@allnodes>0) { - my $nsh={}; + my $nsh={}; my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); - if ($ret) { trace( $request, $msg );} - else { + if (!$ret) { foreach (keys %$nsh) { - my $currstate=$nsh->{$_}; - $nodestat{$_}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "rpower"); - } - } - } - } - } - } elsif ($request->{command} eq 'rnetboot') { - $check=1; - my $noderange = $request->{node}; - my @allnodes=@$noderange; - #get the current nodeset stat - if (@allnodes>0) { - my $nsh={}; - my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); - if ($ret) { trace( $request, $msg );} - else { - foreach (keys %$nsh) { - my $currstate=$nsh->{$_}; - $nodestat{$_}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "netboot"); + my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, $command); + $newnodestatus{$newstat}=$nsh->{$_}; + } + } else { + trace( $request, $msg ); + } } } + #print "newstatus" . Dumper(\%newnodestatus); + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); } } + ####################################### # Fork process ####################################### @@ -192,12 +199,12 @@ sub process_command { foreach ( @$nodes ) { while ( $children > $request->{ppcmaxp} ) { - my $errornodes={}; - child_response( $callback, $fds, $errornodes); + my $handlednodes={}; + child_response( $callback, $fds, $handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } Time::HiRes::sleep(0.1); @@ -224,12 +231,12 @@ sub process_command { # Process responses from children ####################################### while ( $fds->count > 0 or $children > 0 ) { - my $errornodes={}; - child_response( $callback, $fds, $errornodes); + my $handlednodes={}; + child_response( $callback, $fds, $handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } Time::HiRes::sleep(0.1); @@ -238,11 +245,11 @@ sub process_command { #drain one more time my $rc=1; while ( $rc>0 ) { - my $errornodes={}; - $rc=child_response( $callback, $fds, $errornodes); + my $handlednodes={}; + $rc=child_response( $callback, $fds, $handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } @@ -252,6 +259,24 @@ sub process_command { trace( $request, $msg ); } + if ($check) { + #print "allerrornodes=@allerrornodes\n"; + #revert the status back for there is no-op for the nodes + my %old=(); + foreach my $node (@allerrornodes) { + my $stat=$oldnodestatus{$node}; + if (exists($old{$stat})) { + my $pa=$old{$stat}; + push(@$pa, $node); + } + else { + $old{$stat}=[$node]; + } + } + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1); + } + + return(0); } @@ -259,21 +284,11 @@ sub process_command { # updateNodeStatus ########################################################################## sub updateNodeStatus { - my $nodestat=shift; - my $errornodes=shift; - my %node_status=(); - foreach my $node (keys(%$errornodes)) { - if ($errornodes->{$node} == -1) { next;} #has error, not updating status - my $stat=$nodestat->{$node}; - if (exists($node_status{$stat})) { - my $pa=$node_status{$stat}; - push(@$pa, $node); - } - else { - $node_status{$stat}=[$node]; - } + my $handlednodes=shift; + my $allerrornodes=shift; + foreach my $node (keys(%$handlednodes)) { + if ($handlednodes->{$node} == -1) { push(@$allerrornodes, $node); } } - xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1); } ########################################################################## diff --git a/xCAT-server/lib/perl/xCAT/SvrUtils.pm b/xCAT-server/lib/perl/xCAT/SvrUtils.pm index 716c2a88b..9c23ec38c 100644 --- a/xCAT-server/lib/perl/xCAT/SvrUtils.pm +++ b/xCAT-server/lib/perl/xCAT/SvrUtils.pm @@ -40,9 +40,6 @@ sub getNodesetStates my $tab = xCAT::Table->new('noderes'); if (!$tab) { return (1, "Unable to open noderes table."); } - #initialize all nodes - foreach (@nodes) { $hashref->{$_} = "undefined"; } - my @aixnodes = (); my @pxenodes = (); my @yabootnodes = (); diff --git a/xCAT-server/lib/xcat/plugins/aixinstall.pm b/xCAT-server/lib/xcat/plugins/aixinstall.pm index f5f669bb3..bce620755 100644 --- a/xCAT-server/lib/xcat/plugins/aixinstall.pm +++ b/xCAT-server/lib/xcat/plugins/aixinstall.pm @@ -5783,7 +5783,8 @@ sub is_me Arguments: nodes --- a pointer to an array of nodes states -- a pointer to a hash table. This hash will be filled by this - function node and key and the nodeset stat as the value. + function. The key is the nodeset status and the value is a pointer + to an array of nodes. Returns: (return code, error message) =cut @@ -5806,6 +5807,7 @@ sub getNodesetStates { my $nttabdata=$nttab->getNodesAttribs(\@nodes,['node', 'profile']); foreach my $node (@nodes) { my $tmp1=$nttabdata->{$node}->[0]; + my $stat; if ($tmp1) { my $profile=$tmp1->{profile}; if ( ! exists($nimimage{$profile})) { @@ -5813,8 +5815,15 @@ sub getNodesetStates { if (defined($tmp)) { $nimimage{$profile} = $tmp->{nimtype}; } else { $nimimage{$profile}="undefined";} } - $hashref->{$node}=$nimimage{$profile}; - } else {$hashref->{$node}="undefined";} + $stat=$nimimage{$profile}; + } else {$stat="undefined";} + if (exists($hashref->{$stat})) { + my $pa=$hashref->{$stat}; + push(@$pa, $node); + } + else { + $hashref->{$stat}=[$node]; + } } $nttab->close(); $nimtab->close(); diff --git a/xCAT-server/lib/xcat/plugins/blade.pm b/xCAT-server/lib/xcat/plugins/blade.pm index 45de93629..0f87097f4 100644 --- a/xCAT-server/lib/xcat/plugins/blade.pm +++ b/xCAT-server/lib/xcat/plugins/blade.pm @@ -2822,33 +2822,62 @@ sub dompa { } #get new node status - my %nodestat=(); + my %oldnodestatus=(); #saves the old node status + my @allerrornodes=(); my $check=0; - my $nsh={}; - my $global_check=1; my $sitetab = xCAT::Table->new('site'); if ($sitetab) { (my $ref) = $sitetab->getAttribs({key => 'nodestatus'}, 'value'); if ($ref) { - if ($ref->{value} =~ /0|N|n/) { $global_check=0; } + if ($ref->{value} =~ /0|n|N/) { $global_check=0; } } } if ($command eq 'rpower') { - if (($global_check) && ($args->[0] ne 'stat') && ($args->[0] ne 'status')) { + if (($global_check) && ($args->[0] ne 'stat') && ($args->[0] ne 'status') && ($args->[0] ne 'state')) { $check=1; my @allnodes=keys %{$mpahash->{$mpa}->{nodes}}; - #get the current nodeset stat - if (@allnodes>0) { - my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); - if ($ret) { xCAT::MsgUtils->message('S', "Cannot update node status: $msg\n"); } + #save the old status + my $nodelisttab = xCAT::Table->new('nodelist'); + if ($nodelisttab) { + my $tabdata = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']); + foreach my $node (@allnodes) + { + my $tmp1 = $tabdata->{$node}->[0]; + if ($tmp1) { + if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; } + else { $oldnodestatus{$node}=""; } + } + } } + #print "oldstatus:" . Dumper(\%oldnodestatus); + + #set the new status to the nodelist.status + my %newnodestatus=(); + my $newstat; + if (($args->[0] eq 'off') || ($args->[0] eq 'softoff')) { + my $newstat=$::STATUS_POWERING_OFF; + $newnodestatus{$newstat}=\@allnodes; + } else { + #get the current nodeset stat + if (@allnodes>0) { + my $nsh={}; + my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); + if (!$ret) { + foreach (keys %$nsh) { + my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, "rpower"); + $newnodestatus{$newstat}=$nsh->{$_}; + } + } + } + } + #print "newstatus" . Dumper(\%newnodestatus); + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); } } - #print "\nglobal_check=$global_check, check=$check\n"; foreach $node (sort (keys %{$mpahash->{$mpa}->{nodes}})) { @@ -2867,16 +2896,8 @@ sub dompa { #print "output=@output\n"; #update the node status - if (($check) && (!$no_op)) { - my $stattmp=$output[0]; - if ($stattmp) { - my @atmp=split(' ', $stattmp); - my $newstat=$atmp[$#atmp]; - if (($newstat eq "on") || ($newstat eq "reset")) { - my $currstate=$nsh->{$node}; - $nodestat{$node}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "rpower"); - } else { $nodestat{$node}=$::STATUS_POWERING_OFF;} - } + if (($check) && ($no_op)) { + push(@allerrornodes, $node); } foreach(@output) { @@ -2915,25 +2936,21 @@ sub dompa { yield; } - #update the node status to the nodelist.status table if ($check) { - my %node_status=(); - - #foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove - - foreach my $node (keys %nodestat) { - my $stat=$nodestat{$node}; - if ($stat eq "no-op") { next; } - if (exists($node_status{$stat})) { - my $pa=$node_status{$stat}; - push(@$pa, $node); - } - else { - $node_status{$stat}=[$node]; - } - } - xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1); - + #print "allerrornodes=@allerrornodes\n"; + #revert the status back for there is no-op for the nodes + my %old=(); + foreach my $node (@allerrornodes) { + my $stat=$oldnodestatus{$node}; + if (exists($old{$stat})) { + my $pa=$old{$stat}; + push(@$pa, $node); + } + else { + $old{$stat}=[$node]; + } + } + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1); } #my $msgtoparent=freeze(\@outhashes); # = XMLout(\%output,RootName => 'xcatresponse'); #print $out $msgtoparent; #$node.": $_\n"; diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm index 2ac2722d2..d991b1a52 100644 --- a/xCAT-server/lib/xcat/plugins/ipmi.pm +++ b/xCAT-server/lib/xcat/plugins/ipmi.pm @@ -6022,6 +6022,16 @@ sub preprocess_request { return; } + if ($command eq "rpower") { + my $subcmd=$exargs[0]; + if ( ($subcmd ne 'stat') && ($subcmd ne 'state') && ($subcmd ne 'status') && ($subcmd ne 'on') && ($subcmd ne 'off') && ($subcmd ne 'softoff') && ($subcmd ne 'nmi')&& ($subcmd ne 'cycle') && ($subcmd ne 'reset') && ($subcmd ne 'boot')) { + $callback->({data=>["Unsupported command: $command $subcmd", $usage_string]}); + $request = {}; + return; + } + } + + if (!$noderange) { $usage_string=xCAT::Usage->getUsage($command); $callback->({data=>$usage_string}); @@ -6130,9 +6140,9 @@ sub process_request { } #get new node status - my %nodestat=(); + my %oldnodestatus=(); #saves the old node status + my @allerrornodes=(); my $check=0; - my $newstat; my $global_check=1; if ($sitetab) { (my $ref) = $sitetab->getAttribs({key => 'nodestatus'}, 'value'); @@ -6140,45 +6150,65 @@ sub process_request { if ($ref->{value} =~ /0|n|N/) { $global_check=0; } } } - + + if ($command eq 'rpower') { if (($global_check) && ($extrargs->[0] ne 'stat') && ($extrargs->[0] ne 'status') && ($extrargs->[0] ne 'state')) { $check=1; - my @allnodes; + my @allnodes=(); foreach (@donargs) { push(@allnodes, $_->[0]); } - if ($extrargs->[0] eq 'off') { $newstat=$::STATUS_POWERING_OFF; } - else { $newstat=$::STATUS_BOOTING;} - foreach (@allnodes) { $nodestat{$_}=$newstat; } - - if ($extrargs->[0] ne 'off') { + #save the old status + my $nodelisttab = xCAT::Table->new('nodelist'); + if ($nodelisttab) { + my $tabdata = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']); + foreach my $node (@allnodes) + { + my $tmp1 = $tabdata->{$node}->[0]; + if ($tmp1) { + if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; } + else { $oldnodestatus{$node}=""; } + } + } + } + #print "oldstatus:" . Dumper(\%oldnodestatus); + + #set the new status to the nodelist.status + my %newnodestatus=(); + my $newstat; + if (($extrargs->[0] eq 'off') || ($extrargs->[0] eq 'softoff')) { + my $newstat=$::STATUS_POWERING_OFF; + $newnodestatus{$newstat}=\@allnodes; + } else { #get the current nodeset stat if (@allnodes>0) { my $nsh={}; my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); if (!$ret) { foreach (keys %$nsh) { - my $currstate=$nsh->{$_}; - $nodestat{$_}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "rpower"); + my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, "rpower"); + $newnodestatus{$newstat}=$nsh->{$_}; } + } else { + $callback->({data=>$msg}); } } } + #print "newstatus" . Dumper(\%newnodestatus); + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); } } - #foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove - my $children = 0; $SIG{CHLD} = sub {my $kpid; do { $kpid = waitpid(-1, WNOHANG); if ($kpid > 0) { delete $bmc_comm_pids{$kpid}; $children--; } } while $kpid > 0; }; my $sub_fds = new IO::Select; foreach (@donargs) { while ($children > $ipmimaxp) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } $children++; @@ -6200,42 +6230,49 @@ sub process_request { $sub_fds->add($cfd) } while ($sub_fds->count > 0 and $children > 0) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } #Make sure they get drained, this probably is overkill but shouldn't hurt my $rc=1; while ( $rc>0 ) { - my $errornodes={}; - $rc=forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + $rc=forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } - } + } + + if ($check) { + #print "allerrornodes=@allerrornodes\n"; + #revert the status back for there is no-op for the nodes + my %old=(); + foreach my $node (@allerrornodes) { + my $stat=$oldnodestatus{$node}; + if (exists($old{$stat})) { + my $pa=$old{$stat}; + push(@$pa, $node); + } + else { + $old{$stat}=[$node]; + } + } + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1); + } } sub updateNodeStatus { - my $nodestat=shift; - my $errornodes=shift; - my %node_status=(); - foreach my $node (keys(%$errornodes)) { - if ($errornodes->{$node} == -1) { next;} #has error, not updating status - my $stat=$nodestat->{$node}; - if (exists($node_status{$stat})) { - my $pa=$node_status{$stat}; - push(@$pa, $node); - } - else { - $node_status{$stat}=[$node]; - } + my $handlednodes=shift; + my $allerrornodes=shift; + foreach my $node (keys(%$handlednodes)) { + if ($handlednodes->{$node} == -1) { push(@$allerrornodes, $node); } } - xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1); } diff --git a/xCAT-server/lib/xcat/plugins/kvm.pm b/xCAT-server/lib/xcat/plugins/kvm.pm index 13008d8b7..24d7d5161 100644 --- a/xCAT-server/lib/xcat/plugins/kvm.pm +++ b/xCAT-server/lib/xcat/plugins/kvm.pm @@ -891,9 +891,9 @@ sub process_request { } #get new node status - my %nodestat=(); + my %oldnodestatus=(); #saves the old node status + my @allerrornodes=(); my $check=0; - my $newstat; my $global_check=1; if ($sitetab) { (my $ref) = $sitetab->getAttribs({key => 'nodestatus'}, 'value'); @@ -902,32 +902,54 @@ sub process_request { } } + if ($command eq 'rpower') { my $subcommand=$exargs[0]; if (($global_check) && ($subcommand ne 'stat') && ($subcommand ne 'status')) { $check=1; my @allnodes=@$noderange; - if ($subcommand eq 'off') { $newstat=$::STATUS_POWERING_OFF; } - else { $newstat=$::STATUS_BOOTING;} - foreach (@allnodes) { $nodestat{$_}=$newstat; } - if ($subcommand ne 'off') { + #save the old status + my $nodelisttab = xCAT::Table->new('nodelist'); + if ($nodelisttab) { + my $tabdata = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']); + foreach my $node (@allnodes) + { + my $tmp1 = $tabdata->{$node}->[0]; + if ($tmp1) { + if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; } + else { $oldnodestatus{$node}=""; } + } + } + } + #print "oldstatus:" . Dumper(\%oldnodestatus); + + #set the new status to the nodelist.status + my %newnodestatus=(); + my $newstat; + if (($subcommand eq 'off') || ($subcommand eq 'softoff')) { + my $newstat=$::STATUS_POWERING_OFF; + $newnodestatus{$newstat}=\@allnodes; + } else { #get the current nodeset stat if (@allnodes>0) { my $nsh={}; my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); if (!$ret) { foreach (keys %$nsh) { - my $currstate=$nsh->{$_}; - $nodestat{$_}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "rpower"); + my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, "rpower"); + $newnodestatus{$newstat}=$nsh->{$_}; } + } else { + $callback->({data=>$msg}); } } } + #print "newstatus" . Dumper(\%newnodestatus); + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); } } - #foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove my $sent = $sitetab->getAttribs({key=>'masterimgdir'},'value'); if ($sent) { $xCAT_plugin::kvm::masterdir=$sent->{value}; @@ -937,11 +959,11 @@ sub process_request { foreach $hyp (sort (keys %hyphash)) { while ($children > $vmmaxp) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } $children++; @@ -962,46 +984,51 @@ sub process_request { $sub_fds->add($cfd); } while ($sub_fds->count > 0 or $children > 0) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } #Make sure they get drained, this probably is overkill but shouldn't hurt my $rc=1; while ( $rc>0 ) { - my $errornodes={}; - $rc=forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + $rc=forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } + } + + if ($check) { + #print "allerrornodes=@allerrornodes\n"; + #revert the status back for there is no-op for the nodes + my %old=(); + foreach my $node (@allerrornodes) { + my $stat=$oldnodestatus{$node}; + if (exists($old{$stat})) { + my $pa=$old{$stat}; + push(@$pa, $node); + } + else { + $old{$stat}=[$node]; + } + } + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1); } } sub updateNodeStatus { - my $nodestat=shift; - my $errornodes=shift; - my %node_status=(); - foreach my $node (keys(%$errornodes)) { - if ($errornodes->{$node} == -1) { next;} #has error, not updating status - my $stat=$nodestat->{$node}; - if (exists($node_status{$stat})) { - my $pa=$node_status{$stat}; - push(@$pa, $node); - } - else { - $node_status{$stat}=[$node]; - } + my $handlednodes=shift; + my $allerrornodes=shift; + foreach my $node (keys(%$handlednodes)) { + if ($handlednodes->{$node} == -1) { push(@$allerrornodes, $node); } } - xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1); } - - sub forward_data { my $callback = shift; my $fds = shift; diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index d90759ee5..ff4c537ad 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -353,7 +353,8 @@ sub process_request { Arguments: nodes --- a pointer to an array of nodes states -- a pointer to a hash table. This hash will be filled by this - function node and key and the nodeset stat as the value. + function. The key is the nodeset status and the value is a pointer + to an array of nodes. Returns: (return code, error message) =cut @@ -365,13 +366,18 @@ sub getNodesetStates { } my @nodes=@$noderef; my $hashref=shift; - if (@nodes>0) { foreach my $node (@nodes) { my $tmp=getstate($node); my @a=split(' ', $tmp); $stat = $a[0]; - $hashref->{$node}=$stat; + if (exists($hashref->{$stat})) { + my $pa=$hashref->{$stat}; + push(@$pa, $node); + } + else { + $hashref->{$stat}=[$node]; + } } } return (0, ""); diff --git a/xCAT-server/lib/xcat/plugins/xen.pm b/xCAT-server/lib/xcat/plugins/xen.pm index db32b8a27..fa3075449 100644 --- a/xCAT-server/lib/xcat/plugins/xen.pm +++ b/xCAT-server/lib/xcat/plugins/xen.pm @@ -751,9 +751,9 @@ sub process_request { } #get new node status - my %nodestat=(); + my %oldnodestatus=(); #saves the old node status + my @allerrornodes=(); my $check=0; - my $newstat; my $global_check=1; my $sitetab = xCAT::Table->new('site'); if ($sitetab) { @@ -763,41 +763,63 @@ sub process_request { } } + if ($command eq 'rpower') { my $subcommand=$exargs[0]; if (($global_check) && ($subcommand ne 'stat') && ($subcommand ne 'status')) { $check=1; my @allnodes=@$noderange; - if ($subcommand eq 'off') { $newstat=$::STATUS_POWERING_OFF; } - else { $newstat=$::STATUS_BOOTING;} - foreach (@allnodes) { $nodestat{$_}=$newstat; } - if ($subcommand ne 'off') { + #save the old status + my $nodelisttab = xCAT::Table->new('nodelist'); + if ($nodelisttab) { + my $tabdata = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']); + foreach my $node (@allnodes) + { + my $tmp1 = $tabdata->{$node}->[0]; + if ($tmp1) { + if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; } + else { $oldnodestatus{$node}=""; } + } + } + } + #print "oldstatus:" . Dumper(\%oldnodestatus); + + #set the new status to the nodelist.status + my %newnodestatus=(); + my $newstat; + if (($subcommand eq 'off') || ($subcommand eq 'softoff')) { + my $newstat=$::STATUS_POWERING_OFF; + $newnodestatus{$newstat}=\@allnodes; + } else { #get the current nodeset stat if (@allnodes>0) { my $nsh={}; my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh); if (!$ret) { foreach (keys %$nsh) { - my $currstate=$nsh->{$_}; - $nodestat{$_}=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($currstate, "rpower"); + my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, "rpower"); + $newnodestatus{$newstat}=$nsh->{$_}; } + } else { + $callback->({data=>$msg}); } } } + #print "newstatus" . Dumper(\%newnodestatus); + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1); } } - #foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove foreach $hyp (sort (keys %hyphash)) { while ($children > $vmmaxp) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } $children++; @@ -818,46 +840,52 @@ sub process_request { $sub_fds->add($cfd); } while ($sub_fds->count > 0 or $children > 0) { - my $errornodes={}; - forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } } #Make sure they get drained, this probably is overkill but shouldn't hurt my $rc=1; while ( $rc>0 ) { - my $errornodes={}; - $rc=forward_data($callback,$sub_fds,$errornodes); + my $handlednodes={}; + $rc=forward_data($callback,$sub_fds,$handlednodes); #update the node status to the nodelist.status table if ($check) { - updateNodeStatus(\%nodestat, $errornodes); + updateNodeStatus($handlednodes, \@allerrornodes); } - } + } + + if ($check) { + #print "allerrornodes=@allerrornodes\n"; + #revert the status back for there is no-op for the nodes + my %old=(); + foreach my $node (@allerrornodes) { + my $stat=$oldnodestatus{$node}; + if (exists($old{$stat})) { + my $pa=$old{$stat}; + push(@$pa, $node); + } + else { + $old{$stat}=[$node]; + } + } + xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1); + } } sub updateNodeStatus { - my $nodestat=shift; - my $errornodes=shift; - my %node_status=(); - foreach my $node (keys(%$errornodes)) { - if ($errornodes->{$node} == -1) { next;} #has error, not updating status - my $stat=$nodestat->{$node}; - if (exists($node_status{$stat})) { - my $pa=$node_status{$stat}; - push(@$pa, $node); - } - else { - $node_status{$stat}=[$node]; - } + my $handlednodes=shift; + my $allerrornodes=shift; + foreach my $node (keys(%$handlednodes)) { + if ($handlednodes->{$node} == -1) { push(@$allerrornodes, $node); } } - xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1); } - sub forward_data { my $callback = shift; my $fds = shift; diff --git a/xCAT-server/lib/xcat/plugins/yaboot.pm b/xCAT-server/lib/xcat/plugins/yaboot.pm index 0517eb5f4..bb44dd5d7 100644 --- a/xCAT-server/lib/xcat/plugins/yaboot.pm +++ b/xCAT-server/lib/xcat/plugins/yaboot.pm @@ -336,7 +336,8 @@ sub process_request { Arguments: nodes --- a pointer to an array of nodes states -- a pointer to a hash table. This hash will be filled by this - function node and key and the nodeset stat as the value. + function.The key is the nodeset status and the value is a pointer + to an array of nodes. Returns: (return code, error message) =cut @@ -354,7 +355,13 @@ sub getNodesetStates { my $tmp=getstate($node); my @a=split(' ', $tmp); $stat = $a[0]; - $hashref->{$node}=$stat; + if (exists($hashref->{$stat})) { + my $pa=$hashref->{$stat}; + push(@$pa, $node); + } + else { + $hashref->{$stat}=[$node]; + } } } return (0, "");