added function for showing node status in nodelist table

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2230 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
linggao 2008-09-25 03:04:56 +00:00
parent 17ec0a6889
commit 1f661e7f08
13 changed files with 437 additions and 32 deletions

View File

@ -34,7 +34,22 @@ $::STATUS_NETBOOTING="netbooting";
$::STATUS_BOOTED="booted";
$::STATUS_POWERING_OFF="powering-off";
$::STATUS_DISCOVERING="discovering";
$::STATUS_DEFINED="defined";
$::STATUS_UNKNOWN="unknown";
#defined->[discovering]->installing->booting->->alive, defined->netbooting->booted->alive, alive/unreachable->booting->->alive, powering-off->unreachable, alive->unreachable
%::NEXT_NODESTAT_VAL=(
$::STATUS_DEFINED=>{$::STATUS_DISCOVERING=>1, $::STATUS_INSTALLING=>1, $::STATUS_NETBOOTING=>1, $::STATUS_POWERING_OFF=>1, $::STATUS_BOOTING=>1},
$::STATUS_DISCOVERING=>{$::STATUS_INSTALLING=>1},
$::STATUS_INSTALLING =>{$::STATUS_BOOTING=>1},
$::STATUS_BOOTING=>{$::STATUS_BOOTED=>1,$::STATUS_ACTIVE=>1, $::STATUS_INACTIVE=>1},
$::STATUS_NETBOOTING=>{$::STATUS_BOOTED=>1},
$::STATUS_BOOTED=>{$::STATUS_ACTIVE=>1, $::STATUS_INACTIVE=>1},
$::STATUS_ACTIVE=>{$::STATUS_INACTIVE=>1, $::STATUS_DISCOVERING=>1, $::STATUS_INSTALLING=>1, $::STATUS_NETBOOTING=>1, $::STATUS_POWERING_OFF=>1, $::STATUS_BOOTING=>1},
$::STATUS_INACTIVE=>{$::STATUS_ACTIVE=>1, $::STATUS_DISCOVERING=>1, $::STATUS_INSTALLING=>1, $::STATUS_NETBOOTING=>1, $::STATUS_POWERING_OFF=>1, $::STATUS_BOOTING=>1},
$::STATUS_POWERING_OFF=>{$::STATUS_INACTIVE=>1}
);
1;

View File

@ -14,7 +14,7 @@ use Socket;
use xCAT::PPCcli;
use xCAT::GlobalDef;
use xCAT::DBobjUtils;
use xCAT_monitoring::monitorctrl;
##########################################
# Globals
@ -127,6 +127,47 @@ sub process_command {
my $fds = new IO::Select;
my $hw;
my $sessions;
#get new node status
my %nodestat=();
my $errornodes={};
my $check=0;
my $newstat;
if ($request->{command} eq 'rpower') {
my $subcommand=$request->{arg}->[0];
if (($subcommand ne 'stat') && ($subcommand ne 'status') && ($subcommand ne 'state')) {
$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') {
#get the current nodeset stat
if (@allnodes>0) {
my $chaintab = xCAT::Table->new('chain');
my $tabdata=$chaintab->getNodesAttribs(\@allnodes,['node', 'currstate']);
foreach my $node (@allnodes) {
my $tmp1=$tabdata->{$node}->[0];
if ($tmp1) {
my $currstate=$tmp1->{currstate};
if ($currstate =~ /^install/) { $nodestat{$node}=$::STATUS_INSTALLING;}
elsif ($currstate =~ /^netboot/) { $nodestat{$node}=$::STATUS_NETBOOTING;}
}
}
}
}
}
} elsif ($request->{command} eq 'rnetboot') {
$check=1;
my $noderange = $request->{node};
my @allnodes=@$noderange;
foreach (@allnodes) { $nodestat{$_}=$::STATUS_NETBOOTING;}
}
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach ( @$nodes ) {
while ( $children > $request->{ppcmaxp} ) {
@ -154,7 +195,7 @@ sub process_command {
# Process responses from children
#######################################
while ( $children > 0 ) {
child_response( $callback, $fds );
child_response( $callback, $fds, $errornodes);
Time::HiRes::sleep(0.1);
}
if ( exists( $request->{verbose} )) {
@ -162,6 +203,28 @@ sub process_command {
my $msg = sprintf( "Total Elapsed Time: %.3f sec\n", $elapsed );
trace( $request, $msg );
}
#update the node status to the nodelist.status table
if ($check) {
my %node_status=();
foreach (keys(%$errornodes)) { $nodestat{$_}="error"; }
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach my $node (keys %nodestat) {
my $stat=$nodestat{$node};
if ($stat eq "error") { 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);
}
return(0);
}
@ -189,6 +252,7 @@ sub child_response {
my $callback = shift;
my $fds = shift;
my $errornodes=shift;
my @ready_fds = $fds->can_read(1);
foreach my $rfh (@ready_fds) {
@ -203,6 +267,10 @@ sub child_response {
}
my $responses = thaw($data);
foreach ( @$responses ) {
#save the nodes that has errors for node status monitoring
if ((exists($_->{errorcode})) && ($_->{errorcode} != 0)) {
if ($errornodes) { $errornodes->{$_->{node}->[0]->{name}->[0]}=1; }
}
$callback->( $_ );
}
next;

View File

@ -263,7 +263,7 @@ nodelist => {
descriptions => {
node => 'The hostname of a node in the cluster.',
groups => "A comma-delimited list of groups this node is a member of. Group names are arbitrary, except all nodes should be part of the 'all' group.",
status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, installing, installed, alive, powering-off, unreachable. The default value is defined. The possible status change sequenses are: defined->[discovering]->installing->installed->alive, defined->netbooting->booted->alive, alive/unreachable->booting->alive, alive->powering-off->unreachable, alive->unreachable',
status => 'The current status of this node. This attribute will be set by xCAT software. Valid values: defined, booting, netbooting, booted, discovering, installing, alive, powering-off, unreachable. The default value is defined. The possible status change sequenses are: defined->[discovering]->installing->booting->alive, defined->netbooting->booted->alive, alive/unreachable->booting->alive, alive->powering-off->unreachable, alive->unreachable',
comments => 'Any user-written notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
},

View File

@ -14,6 +14,7 @@ use xCAT::Utils;
use xCAT_plugin::notification;
use xCAT_monitoring::montbhandler;
use Sys::Hostname;
use xCAT::GlobalDef;
#the list stores the names of the monitoring plug-in and the file name and module names.
#the names are stored in the "name" column of the monitoring table.
@ -26,7 +27,6 @@ my $NODESTAT_MON_NAME;
my $masterpid;
1;
#-------------------------------------------------------------------------------
@ -540,6 +540,8 @@ sub processMonitoringTableChanges {
status -- a hash pointer of the node status. A key is a status string. The value is
an array pointer of nodes that have the same status.
for example: {alive=>["node1", "node1"], unreachable=>["node5","node100"]}
force -- 1 force the input values to be set.
-- 0 make sure if the input value is the next valid value.
Returns:
0 for successful.
non-0 for not successful.
@ -551,10 +553,32 @@ sub setNodeStatusAttributes {
if ($temp =~ /xCAT_monitoring::monitorctrl/) {
$temp=shift;
}
my $force=shift;
my $tab = xCAT::Table->new('nodelist',-create=>0,-autocommit=>1);
my %status_hash=%$temp;
my $tab = xCAT::Table->new('nodelist',-create=>0,-autocommit=>1);
#check if the next value is valid or not
if (!$force) {
foreach my $s (keys %status_hash) {
my @new_nodes=();
my $nodes=$status_hash{$s};
if ($nodes && (@$nodes>0)) {
my $tabdata=$tab->getNodesAttribs($nodes,['node', 'status']);
foreach my $node (@$nodes) {
my $tmp1=$tabdata->{$node}->[0];
if ($tmp1) {
my $status=$tmp1->{status};
if (!$status) {$status=$::STATUS_DEFINED; } #default is 'defined'
if ($::NEXT_NODESTAT_VAL{$status}->{$s}==1) { push(@new_nodes,$node); }
}
}
}
#print "newnodes=@new_nodes\n";
$status_hash{$s}=\@new_nodes;
} #end foreach
}
my %updates;
if ($tab) {
foreach (keys %status_hash) {

View File

@ -310,7 +310,15 @@ sub getMonNodesStatus {
my $status=$_->[2];
if ($status eq $::STATUS_ACTIVE) { push(@active_nodes, $node);}
elsif ($status eq $::STATUS_INACTIVE) { push(@inactive_nodes, $node);}
else { push(@unknown_nodes, $node);}
else {
my $need_active=0;
my $need_inactive=0;
if ($::NEXT_NODESTAT_VAL{$status}->{$::STATUS_ACTIVE}==1) { $need_active=1;}
if ($::NEXT_NODESTAT_VAL{$status}->{$::STATUS_INACTIVE}==1) { $need_inactive=1;}
if (($need_active==1) && ($need_inactive==0)) { push(@inactive_nodes, $node); } #put it into the inactive list so that the monitoring code can switch it to active.
elsif (($need_active==0) && ($need_inactive==1)) { push(@active_nodes, $node); } #put it into the active list so that the monitoring code can chane it to inactive.
elsif (($need_active==1) && ($need_inactive==1)) { push(@unknown_nodes, $node);} #unknow list so that the monitoring code can change it to active or inactive
}
}
}
@ -329,6 +337,8 @@ sub getMonNodesStatus {
status -- a hash pointer of the node status. A key is a status string. The value is
an array pointer of nodes that have the same status.
for example: {alive=>["node1", "node1"], unreachable=>["node5","node100"]}
force -- 1 force the input values to be set.
-- 0 make sure if the input value is the next valid value.
Returns:
0 for successful.
non-0 for not successful.
@ -339,7 +349,9 @@ sub setNodeStatusAttributes {
if ($temp =~ /xCAT_monitoring::xcatmon/) {
$temp=shift;
}
return xCAT_monitoring::monitorctrl->setNodeStatusAttributes($temp);
my $force=shift;
return xCAT_monitoring::monitorctrl->setNodeStatusAttributes($temp, $force);
}
#--------------------------------------------------------------------------------

View File

@ -1,6 +1,11 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::blade;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
#use Net::SNMP qw(:snmp INTEGER);
use xCAT::Table;
use Thread qw(yield);
@ -8,7 +13,10 @@ use xCAT::Utils;
use xCAT::Usage;
use IO::Socket;
use SNMP;
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
use strict;
#use warnings;
my %mm_comm_pids;
@ -2645,10 +2653,48 @@ sub dompa {
#Add a dummy node for eventlog to get non-blade events
$mpahash{$mpa}->{nodes}->{$mpa}=-1;
}
#get new node status
my %nodestat=();
my $check=0;
my $newstat;
if ($command eq 'rpower') {
if (($args->[0] ne 'stat') && ($args->[0] ne 'status')) {
$check=1;
my @allnodes=keys %{$mpahash->{$mpa}->{nodes}};
if ($args->[0] eq 'off') { $newstat=$::STATUS_POWERING_OFF; }
else { $newstat=$::STATUS_BOOTING;}
foreach (@allnodes) { $nodestat{$_}=$newstat; }
if ($args->[0] ne 'off') {
#get the current nodeset stat
if (@allnodes>0) {
my $chaintab = xCAT::Table->new('chain');
my $tabdata=$chaintab->getNodesAttribs(\@allnodes,['node', 'currstate']);
foreach my $node (@allnodes) {
my $tmp1=$tabdata->{$node}->[0];
if ($tmp1) {
my $currstate=$tmp1->{currstate};
if ($currstate =~ /^install/) { $nodestat{$node}=$::STATUS_INSTALLING;}
elsif ($currstate =~ /^netboot/) { $nodestat{$node}=$::STATUS_NETBOOTING;}
}
}
}
}
}
}
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach $node (sort (keys %{$mpahash->{$mpa}->{nodes}})) {
$curn = $node;
my ($rc,@output) = bladecmd($mpa,$node,$mpahash->{$mpa}->{nodes}->{$node},$mpahash->{$mpa}->{username},$mpahash->{$mpa}->{password},$command,@$args);
#update the node status
if (($check) && ($rc)) {
$nodestat{$node}="error";
}
foreach(@output) {
my %output;
@ -2680,6 +2726,27 @@ 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 "error") { 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);
}
#my $msgtoparent=freeze(\@outhashes); # = XMLout(\%output,RootName => 'xcatresponse');
#print $out $msgtoparent; #$node.": $_\n";
}

View File

@ -4,6 +4,8 @@ use xCAT::NodeRange;
use Data::Dumper;
use xCAT::Utils;
use Sys::Syslog;
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
use strict;
my $request;
@ -205,6 +207,7 @@ sub nextdestiny {
my $node;
$chaintab = xCAT::Table->new('chain');
my $chainents = $chaintab->getNodesAttribs(\@nodes,[qw(currstate currchain chain)]);
my %node_status=();
foreach $node (@nodes) {
unless($chaintab) {
syslog("local1|err","ERROR: $node requested destiny update, no chain table");
@ -226,16 +229,34 @@ sub nextdestiny {
$ref->{currchain} = $ref->{currstate};
}
$chaintab->setNodeAttribs($node,$ref); #$ref is in a state to commit back to db
#collect node status for certain states
if ($ref->{currstate} =~ /^boot/) {
my $stat="booting";
if (exists($node_status{$stat})) {
my $pa=$node_status{$stat};
push(@$pa, $node);
}
else {
$node_status{$stat}=[$node];
}
}
my %requ;
$requ{node}=[$node];
$requ{arg}=[$ref->{currstate}];
setdestiny(\%requ);
}
#setup the nodelist.status
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1);
if ($callnodeset) {
$subreq->({command=>['nodeset'],
node=> \@nodes,
arg=>['enact']});
}
}

View File

@ -4,8 +4,15 @@
#(C)IBM Corp
package xCAT_plugin::ipmi;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use warnings "all";
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
use POSIX qw(ceil floor);
use Storable qw(store_fd retrieve_fd thaw freeze);
@ -5542,12 +5549,45 @@ sub process_request {
return;
}
#get new node status
my %nodestat=();
my $errornodes={};
my $check=0;
my $newstat;
if ($command eq 'rpower') {
if (($extrargs->[0] ne 'stat') && ($extrargs->[0] ne 'status') && ($extrargs->[0] ne 'state')) {
$check=1;
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') {
#get the current nodeset stat
if (@allnodes>0) {
my $chaintab = xCAT::Table->new('chain');
my $tabdata=$chaintab->getNodesAttribs(\@allnodes,['node', 'currstate']);
foreach my $node (@allnodes) {
my $tmp1=$tabdata->{$node}->[0];
if ($tmp1) {
my $currstate=$tmp1->{currstate};
if ($currstate =~ /^install/) { $nodestat{$node}=$::STATUS_INSTALLING;}
elsif ($currstate =~ /^netboot/) { $nodestat{$node}=$::STATUS_NETBOOTING;}
}
}
}
}
}
}
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) { forward_data($callback,$sub_fds); }
while ($children > $ipmimaxp) { forward_data($callback,$sub_fds, $errornodes); }
$children++;
my $cfd;
my $pfd;
@ -5556,24 +5596,50 @@ sub process_request {
$pfd->autoflush(1);
my $child = xCAT::Utils->xfork();
unless (defined $child) { die "Fork failed" };
if ($child == 0) {
if ($child == 0) {
close($cfd);
donode($pfd,$_->[0],$_->[1],$_->[2],$_->[3],$ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
my $rrc=donode($pfd,$_->[0],$_->[1],$_->[2],$_->[3],$ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
close($pfd);
exit(0);
}
exit(0);
}
$bmc_comm_pids{$child}=1;
close ($pfd);
$sub_fds->add($cfd)
}
while ($sub_fds->count > 0 and $children > 0) {
forward_data($callback,$sub_fds);
forward_data($callback,$sub_fds,$errornodes);
}
while (forward_data($callback,$sub_fds)) {} #Make sure they get drained, this probably is overkill but shouldn't hurt
while (forward_data($callback,$sub_fds, $errornodes)) {} #Make sure they get drained, this probably is overkill but shouldn't hurt
#update the node status to the nodelist.status table
if ($check) {
my %node_status=();
foreach (keys(%$errornodes)) { $nodestat{$_}="error"; }
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach my $node (keys %nodestat) {
my $stat=$nodestat{$node};
if ($stat eq "error") { 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);
}
}
sub forward_data { #unserialize data from pipe, chunk at a time, use magic to determine end of data structure
my $callback = shift;
my $fds = shift;
my $errornodes=shift;
my @ready_fds = $fds->can_read(1);
my $rfh;
my $rc = @ready_fds;
@ -5586,6 +5652,10 @@ sub forward_data { #unserialize data from pipe, chunk at a time, use magic to de
print $rfh "ACK\n";
my $responses=thaw($data);
foreach (@$responses) {
#save the nodes that has errors for node status monitoring
if (exists($_->{node}->[0]->{errorcode})) {
if ($errornodes) { $errornodes->{$_->{node}->[0]->{name}->[0]}=1; }
}
$callback->($_);
}
} else {
@ -5617,6 +5687,7 @@ sub donode {
yield;
#my $msgtoparent=freeze(\@outhashes);
# print $outfd $msgtoparent;
return $rc;
}
sub sendoutput {

View File

@ -17,6 +17,8 @@ use xCAT::Utils;
use Getopt::Long;
use xCAT::GlobalDef;
use Sys::Hostname;
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
1;
@ -40,7 +42,8 @@ use Sys::Hostname;
sub handled_commands
{
return {
updatenode => "updatenode"};
updatenode => "updatenode",
updatenodestat => "updatenode"};
}
@ -60,7 +63,9 @@ sub preprocess_request
if ($command eq "updatenode")
{
return preprocess_updatenode($request, $callback);
}
} elsif ($command eq "updatenodestat") {
return [$request];
}
else {
my $rsp={};
$rsp->{data}->[0]= "unsupported command: $command.";
@ -87,11 +92,11 @@ sub process_request
my $command = $request->{command}->[0];
my $localhostname=hostname();
if ($command eq "updatenode")
{
return updatenode($request, $callback);
}
else {
if ($command eq "updatenode") {
return updatenode($request, $callback);
} elsif ($command eq "updatenodestat") {
return updatenodestat($request, $callback);
} else {
my $rsp={};
$rsp->{data}->[0]= "$localhostname: unsupported command: $command.";
$callback->($rsp);
@ -233,10 +238,11 @@ sub updatenode {
if ($nodestring) {
my $output;
if (xCAT::Utils->isLinux()) {
$output=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -e /install/postscripts/xcatdsklspost $postscripts 2>&1`;
$output=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -e /install/postscripts/xcatdsklspost 1 $postscripts 2>&1`;
}
else {
$output=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -e /install/postscripts/xcataixpost $postscripts 2>&1`;
$output="This function is not supported on AIX.";
#$output=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -e /install/postscripts/xcataixpost 1 $postscripts 2>&1`;
}
my $rsp={};
$rsp->{data}->[0]= "$output\n";
@ -248,6 +254,37 @@ sub updatenode {
}
sub updatenodestat {
my $request = shift;
my $callback = shift;
my @nodes=();
my @args=();
if (ref($request->{node})) {
@nodes = @{$request->{node}};
} else {
if ($request->{node}) { @nodes = ($request->{node}); }
}
if (ref($request->{arg})) {
@args=@{$request->{arg}};
} else {
@args=($request->{arg});
}
if ((@nodes>0) && (@args>0)) {
my %node_status=();
my $stat=$args[0];
$node_status{$stat}=[];
foreach my $node (@nodes) {
my $pa=$node_status{$stat};
push(@$pa, $node);
}
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%node_status, 1);
}
return 0;
}

View File

@ -3,7 +3,13 @@
package xCAT_plugin::xen;
my $libvirtsupport;
$libvirtsupport = eval { require Sys::Virt; };
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
#use Net::SNMP qw(:snmp INTEGER);
use xCAT::Table;
@ -436,6 +442,7 @@ sub preprocess_request {
}
return \@requests;
}
sub adopt {
#TODO: adopt orphans into suitable homes if possible
@ -529,8 +536,43 @@ sub process_request {
return;
}
#get new node status
my %nodestat=();
my $errornodes={};
my $check=0;
my $newstat;
if ($command eq 'rpower') {
my $subcommand=$exargs[0];
if (($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') {
#get the current nodeset stat
if (@allnodes>0) {
my $chaintab = xCAT::Table->new('chain');
my $tabdata=$chaintab->getNodesAttribs(\@allnodes,['node', 'currstate']);
foreach my $node (@allnodes) {
my $tmp1=$tabdata->{$node}->[0];
if ($tmp1) {
my $currstate=$tmp1->{currstate};
if ($currstate =~ /^install/) { $nodestat{$node}=$::STATUS_INSTALLING;}
elsif ($currstate =~ /^netboot/) { $nodestat{$node}=$::STATUS_NETBOOTING;}
}
}
}
}
}
}
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach $hyp (sort (keys %hyphash)) {
while ($children > $vmmaxp) { forward_data($callback,$sub_fds); }
while ($children > $vmmaxp) { forward_data($callback,$sub_fds,$errornodes); }
$children++;
my $cfd;
my $pfd;
@ -549,14 +591,37 @@ sub process_request {
$sub_fds->add($cfd);
}
while ($sub_fds->count > 0 or $children > 0) {
forward_data($callback,$sub_fds);
forward_data($callback,$sub_fds,$errornodes);
}
while (forward_data($callback,$sub_fds)) {}
while (forward_data($callback,$sub_fds,$errornodes)) {}
#update the node status to the nodelist.status table
if ($check) {
my %node_status=();
foreach (keys(%$errornodes)) { $nodestat{$_}="error"; }
foreach (keys %nodestat) { print "node=$_,status=" . $nodestat{$_} ."\n"; } #Ling:remove
foreach my $node (keys %nodestat) {
my $stat=$nodestat{$node};
if ($stat eq "error") { 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);
}
}
sub forward_data {
my $callback = shift;
my $fds = shift;
my $errornodes=shift;
my @ready_fds = $fds->can_read(1);
my $rfh;
my $rc = @ready_fds;
@ -569,6 +634,10 @@ sub forward_data {
print $rfh "ACK\n";
my $responses=thaw($data);
foreach (@$responses) {
#save the nodes that has errors for node status monitoring
if ((exists($_->{node}->[0]->{errorcode})) && ($_->{node}->[0]->{errorcode} != 0)) {
if ($errornodes) { $errornodes->{$_->{node}->[0]->{name}->[0]}=1; }
}
$callback->($_);
}
} else {

View File

@ -211,6 +211,19 @@ if ($inet6support) {
plugin_command(\%request,undef,\&build_response);
# exit(0);
#}
} elsif ($text =~ /netbooted/) {
my %request = (
command => [ 'updatenodestat' ],
node => [ $node ],
arg => [ 'booted' ],
);
close($conn);
#node should be blocked, race condition may occur otherwise
#my $pid=xCAT::Utils->xfork();
#unless ($pid) { #fork off the nodeset and potential slowness
plugin_command(\%request,undef,\&build_response);
# exit(0);
#}
} elsif ($text =~ /^unlocktftpdir/) { #TODO: only nodes in install state should be allowed
mkpath("$tftpdir/xcat/$node");
chmod 01777,"$tftpdir/xcat/$node";

View File

@ -2,9 +2,11 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN {
xcatdhost = ARGV[1]
xcatdhost = ARGV[1]
xcatdport = ARGV[2]
flag = ARGV[3]
if (!flag) flag = "next"
ns = "/inet/tcp/0/" ARGV[1] "/" xcatdport
@ -13,7 +15,7 @@ BEGIN {
print $0 | "logger -t xcat"
if($0 == "ready")
print "next" |& ns
print flag |& ns
if($0 == "done")
break
}

View File

@ -72,8 +72,8 @@ while [ -z "$MYCONT" ]; do
MYCONT=`cat /tmp/mypostscript`
# echo "MYCONT=$MYCONT"
done
if [ $# -gt 0 ]; then
POSTS=$1
if [ $# -gt 1 ]; then
POSTS=$2
#remove all the postscripts
TMP=`sed "/postscripts-start-here/,/postscripts-end-here/ d" /tmp/mypostscript`
echo "$TMP" > /tmp/mypostscript
@ -88,6 +88,12 @@ if [ -x /tmp/mypostscript ];then
/tmp/mypostscript
fi
rm -f /tmp/mypostscript
#notify the server that we are done with netbooting
if [ $# -eq 0 ]; then
updateflag.awk $MASTER 3002 netbooted
fi
killall stunnel
rm -rf /etc/stunnel