#!/usr/bin/env perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; } use lib "$::XCATROOT/lib/perl"; use xCAT::GlobalDef; use xCAT::Table; use xCAT_monitoring::monitorctrl; ################################################################# # This script is used as a cron job by the xCAT monitoring plug-in # to monitor the node status. To activate it, simply do # chtab pname=xCAT monitoring.nodestatmon=Y ################################################################## ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); printf "%2d-%02d-%04d %02d:%02d:%02d: xcatnodemon started.\n", $mon+1,$mday,$year+1900,$hour,$min,$sec; #get saved node status from the nodelist table my %nodes_status_old=xCAT_monitoring::monitorctrl::getNodeStatus(); #get a list of nodes my $tmp_node_active=$nodes_status_old{$::STATUS_ACTIVE}; my $tmp_node_inactive=$nodes_status_old{$::STATUS_INACTIVE}; my $tmp_node_unknown=$nodes_status_old{unknown}; #print "active nodes: @$tmp_node_active\n"; #print "inactive nodes: @$tmp_node_inactive\n"; #print "unknown nodes: @$tmp_node_unknown\n"; #get current node status my %nodes_status_new1=(); if ($tmp_node_active) { %nodes_status_new1=pingNodeStatus(@$tmp_node_active);} my %nodes_status_new2=(); if ($tmp_node_inactive) {%nodes_status_new2=pingNodeStatus(@$tmp_node_inactive);} my %nodes_status_new3=(); if ($tmp_node_unknown) { %nodes_status_new3=pingNodeStatus(@$tmp_node_unknown);} my $changed1=$nodes_status_new1{$::STATUS_INACTIVE}; my $changed2=$nodes_status_new2{$::STATUS_ACTIVE}; my $changed3=$nodes_status_new3{$::STATUS_INACTIVE}; my $changed4=$nodes_status_new3{$::STATUS_ACTIVE}; my @changed_active=(@$changed2, @$changed4); my @changed_inactive=(@$changed1, @$changed3); print " switch to active: @changed_active\n"; print " switch to inactive: @changed_inactive\n"; my %node_status=(); if (@changed_active>0) { $node_status{$::STATUS_ACTIVE}=\@changed_active; } if (@changed_inactive>0) { $node_status{$::STATUS_INACTIVE}=\@changed_inactive; } #only set the node status for the changed ones if (keys(%node_status) > 0) { xCAT_monitoring::monitorctrl::processNodeStatusChanges(\%node_status); } ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); printf "%2d-%02d-%04d %02d:%02d:%02d: xcatnodemon finished.\n\n", $mon+1,$mday,$year+1900,$hour,$min,$sec; #-------------------------------------------------------------------------------- =head3 pingNodeStatus This function takes an array of nodes and returns their status using fping. Arguments: nodes-- an array of nodes. Returns: a hash that has the node status. The format is: {active=>[node1, node3,...], unreachable=>[node4, node2...]} =cut #-------------------------------------------------------------------------------- sub pingNodeStatus { my @mon_nodes=@_; %status=(); my @active_nodes=(); my @inactive_nodes=(); if ((@mon_nodes)&& (@mon_nodes > 0)) { #get all the active nodes #TODO how to decide the path of fping. how about AIX, does it support fping? my $nodes= join(' ', @mon_nodes); my $temp=`/usr/sbin/fping -a $nodes 2> /dev/null`; chomp($temp); @active_nodes=split(/\n/, $temp); #get all the inactive nodes by substracting the active nodes from all. my %temp2; if ((@active_nodes) && ( @active_nodes > 0)) { foreach(@active_nodes) { $temp2{$_}=1}; foreach(@mon_nodes) { if (!$temp2{$_}) { push(@inactive_nodes, $_);} } } else {@inactive_nodes=@mon_nodes;} } $status{$::STATUS_ACTIVE}=\@active_nodes; $status{$::STATUS_INACTIVE}=\@inactive_nodes; return %status; }