From 1f661e7f084352e3043de390e66815a94fc231b6 Mon Sep 17 00:00:00 2001 From: linggao Date: Thu, 25 Sep 2008 03:04:56 +0000 Subject: [PATCH] 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 --- perl-xCAT/xCAT/GlobalDef.pm | 15 ++++ perl-xCAT/xCAT/PPC.pm | 72 +++++++++++++++- perl-xCAT/xCAT/Schema.pm | 2 +- .../lib/xcat/monitoring/monitorctrl.pm | 28 +++++- xCAT-server/lib/xcat/monitoring/xcatmon.pm | 16 +++- xCAT-server/lib/xcat/plugins/blade.pm | 67 +++++++++++++++ xCAT-server/lib/xcat/plugins/destiny.pm | 21 +++++ xCAT-server/lib/xcat/plugins/ipmi.pm | 85 +++++++++++++++++-- xCAT-server/lib/xcat/plugins/updatenode.pm | 55 ++++++++++-- xCAT-server/lib/xcat/plugins/xen.pm | 77 ++++++++++++++++- xCAT-server/sbin/xcatd | 13 +++ xCAT/postscripts/updateflag.awk | 8 +- xCAT/postscripts/xcatdsklspost | 10 ++- 13 files changed, 437 insertions(+), 32 deletions(-) diff --git a/perl-xCAT/xCAT/GlobalDef.pm b/perl-xCAT/xCAT/GlobalDef.pm index 5c86ff4c7..b642ddce4 100644 --- a/perl-xCAT/xCAT/GlobalDef.pm +++ b/perl-xCAT/xCAT/GlobalDef.pm @@ -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; diff --git a/perl-xCAT/xCAT/PPC.pm b/perl-xCAT/xCAT/PPC.pm index 052e248c1..24535a95c 100644 --- a/perl-xCAT/xCAT/PPC.pm +++ b/perl-xCAT/xCAT/PPC.pm @@ -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; diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 3a2d41077..ba0c45402 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -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.", }, diff --git a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm index 22a06c88c..cfd8ea724 100644 --- a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm +++ b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm @@ -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) { diff --git a/xCAT-server/lib/xcat/monitoring/xcatmon.pm b/xCAT-server/lib/xcat/monitoring/xcatmon.pm index 125b2a278..a59b8f92c 100644 --- a/xCAT-server/lib/xcat/monitoring/xcatmon.pm +++ b/xCAT-server/lib/xcat/monitoring/xcatmon.pm @@ -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); } #-------------------------------------------------------------------------------- diff --git a/xCAT-server/lib/xcat/plugins/blade.pm b/xCAT-server/lib/xcat/plugins/blade.pm index a2f39d2b5..cb9ef3ad4 100644 --- a/xCAT-server/lib/xcat/plugins/blade.pm +++ b/xCAT-server/lib/xcat/plugins/blade.pm @@ -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"; } diff --git a/xCAT-server/lib/xcat/plugins/destiny.pm b/xCAT-server/lib/xcat/plugins/destiny.pm index d3246e889..7a66f5e5a 100644 --- a/xCAT-server/lib/xcat/plugins/destiny.pm +++ b/xCAT-server/lib/xcat/plugins/destiny.pm @@ -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']}); } + } diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm index cae1ba8c2..b790fa76d 100644 --- a/xCAT-server/lib/xcat/plugins/ipmi.pm +++ b/xCAT-server/lib/xcat/plugins/ipmi.pm @@ -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 { diff --git a/xCAT-server/lib/xcat/plugins/updatenode.pm b/xCAT-server/lib/xcat/plugins/updatenode.pm index f2894ca77..2968d1bba 100644 --- a/xCAT-server/lib/xcat/plugins/updatenode.pm +++ b/xCAT-server/lib/xcat/plugins/updatenode.pm @@ -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; +} + + diff --git a/xCAT-server/lib/xcat/plugins/xen.pm b/xCAT-server/lib/xcat/plugins/xen.pm index 0b28c347a..5c2a85c8b 100644 --- a/xCAT-server/lib/xcat/plugins/xen.pm +++ b/xCAT-server/lib/xcat/plugins/xen.pm @@ -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 { diff --git a/xCAT-server/sbin/xcatd b/xCAT-server/sbin/xcatd index b86470939..9197bfd95 100755 --- a/xCAT-server/sbin/xcatd +++ b/xCAT-server/sbin/xcatd @@ -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"; diff --git a/xCAT/postscripts/updateflag.awk b/xCAT/postscripts/updateflag.awk index 610c6bf92..91599dee2 100755 --- a/xCAT/postscripts/updateflag.awk +++ b/xCAT/postscripts/updateflag.awk @@ -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 } diff --git a/xCAT/postscripts/xcatdsklspost b/xCAT/postscripts/xcatdsklspost index 2afef953d..3c73586cc 100755 --- a/xCAT/postscripts/xcatdsklspost +++ b/xCAT/postscripts/xcatdsklspost @@ -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