13fa2a4a32
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@1795 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
861 lines
27 KiB
Perl
861 lines
27 KiB
Perl
#!/usr/bin/env perl
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
package xCAT_monitoring::rmcmon;
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use xCAT::NodeRange;
|
|
use Sys::Hostname;
|
|
use Socket;
|
|
use xCAT::Utils;
|
|
use xCAT::GlobalDef;
|
|
use xCAT_monitoring::monitorctrl;
|
|
use xCAT_monitoring::xcatmon;
|
|
use xCAT::MsgUtils;
|
|
|
|
#print "xCAT_monitoring::rmcmon loaded\n";
|
|
1;
|
|
|
|
|
|
#TODO: script to define sensors on the nodes.
|
|
#TODO: how to push the sensor scripts to nodes?
|
|
#TODO: what to do when stop is called? stop all the associations or just the ones that were predefined? or leve them there?
|
|
#TODO: do we need to stop all the RMC daemons when stop is called?
|
|
#TODO: monitoring HMC with old RSCT and new RSCT
|
|
|
|
#-------------------------------------------------------------------------------
|
|
=head1 xCAT_monitoring:rmcmon
|
|
=head2 Package Description
|
|
xCAT monitoring plugin package to handle RMC monitoring.
|
|
=cut
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 start
|
|
This function gets called by the monitorctrl module
|
|
when xcatd starts. It starts the daemons and does
|
|
necessary startup process for the RMC monitoring.
|
|
It also queries the RMC for its currently monitored
|
|
nodes which will, in tern, compared with the nodes
|
|
in the input parameter. It asks RMC to add or delete
|
|
nodes according to the comparison so that the nodes
|
|
monitored by RMC are in sync with the nodes currently
|
|
in the xCAT cluster.
|
|
Arguments:
|
|
None.
|
|
Returns:
|
|
(return code, message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub start {
|
|
#print "rmcmon::start called\n";
|
|
|
|
my $noderef=xCAT_monitoring::monitorctrl->getMonHierarchy();
|
|
|
|
#assume the server is the current node.
|
|
#check if rsct is installed and running
|
|
if (! -e "/usr/bin/lsrsrc") {
|
|
return (1, "RSCT is not installed.\n");
|
|
}
|
|
|
|
chomp(my $pid= `/bin/ps -ef | /bin/grep rmcd | /bin/grep -v grep | /bin/awk '{print \$2}'`);
|
|
unless($pid){
|
|
#restart rmc daemon
|
|
$result=`startsrc -s ctrmc`;
|
|
if ($?) {
|
|
return (1, "RMC deamon cannot be started\n");
|
|
}
|
|
}
|
|
|
|
#enable remote client connection
|
|
`/usr/bin/rmcctrl -p`;
|
|
|
|
#get a list of managed nodes
|
|
$result=`/usr/bin/lsrsrc-api -s IBM.MngNode::::Name 2>&1`;
|
|
if ($?) {
|
|
if ($result !~ /2612-023/) {#2612-023 no resources found error
|
|
xCAT::MsgUtils->message('SI', "[mon]: $result\n");
|
|
return (1,$result);
|
|
}
|
|
$result='';
|
|
}
|
|
chomp($result);
|
|
my @rmc_nodes=split(/\n/, $result);
|
|
#print "RMC defined nodes=@rmc_nodes\n";
|
|
|
|
|
|
#the identification of this node
|
|
my @hostinfo=xCAT::Utils->determinehostname();
|
|
my $isSV=xCAT::Utils->isServiceNode();
|
|
%iphash=();
|
|
foreach(@hostinfo) {$iphash{$_}=1;}
|
|
if (!$isSV) { $iphash{'noservicenode'}=1;}
|
|
|
|
foreach my $key (keys (%$noderef)) {
|
|
my @key_a=split(',', $key);
|
|
if (! $iphash{$key_a[0]}) { next;}
|
|
my $mon_nodes=$noderef->{$key};
|
|
my $master=$key_a[1];
|
|
|
|
#check what has changed
|
|
my %summary;
|
|
foreach (@rmc_nodes) { $summary{$_}=-1;}
|
|
if ($mon_nodes) {
|
|
foreach(@$mon_nodes) {
|
|
my $node=$_->[0];
|
|
my $nodetype=$_->[1];
|
|
if ((!$nodetype) || ($nodetype =~ /$::NODETYPE_OSI/)) {
|
|
$summary{$node}++;
|
|
}
|
|
}
|
|
}
|
|
|
|
my @nodes_to_add=();
|
|
my @nodes_to_remove=();
|
|
foreach(keys(%summary)) {
|
|
if ($summary{$_}==1) {push(@nodes_to_add, $_);}
|
|
elsif ($summary{$_}==-1) {push(@nodes_to_remove, $_);}
|
|
}
|
|
|
|
#add new nodes to the RMC cluster
|
|
#print "all nodes to add: @nodes_to_add\nall nodes to remove: @nodes_to_remove\n";
|
|
if (@nodes_to_add>0) {
|
|
my %nodes_status=xCAT_monitoring::rmcmon->pingNodeStatus(@nodes_to_add);
|
|
my $active_nodes=$nodes_status{$::STATUS_ACTIVE};
|
|
my $inactive_nodes=$nodes_status{$::STATUS_INACTIVE};
|
|
#print "active nodes to add:@$active_nodes\ninactive nodes to add: @$inactive_nodes\n";
|
|
if (@$inactive_nodes>0) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: The following nodes cannot be added to the RMC cluster because they are inactive:\n @$inactive_nodes\n");
|
|
}
|
|
if (@$active_nodes>0) {
|
|
addNodes_noChecking($active_nodes, $master);
|
|
}
|
|
}
|
|
|
|
#remove unwanted nodes to the RMC cluster
|
|
if (@nodes_to_remove>0) {
|
|
#print "nodes to remove @nodes_to_remove\n";
|
|
removeNodes_noChecking(\@nodes_to_remove, $master);
|
|
}
|
|
|
|
#create conditions/responses/sensors on the service node or mn
|
|
my $result=`$::XCATROOT/sbin/rmcmon/mkrmcresources $::XCATROOT/lib/perl/xCAT_monitoring/rmc/resources/sn 2>&1`;
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: Error when creating predefined resources on $localhostname:\n$result\n");
|
|
}
|
|
if ($isSV) {
|
|
$result=`$::XCATROOT/sbin/rmcmon/mkrmcresources $::XCATROOT/lib/perl/xCAT_monitoring/rmc/resources/node 2>&1`;
|
|
} else {
|
|
$result=`$::XCATROOT/sbin/rmcmon/mkrmcresources $::XCATROOT/lib/perl/xCAT_monitoring/rmc/resources/mn 2>&1`;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: Error when creating predefined resources on $localhostname:\n$result\n");
|
|
}
|
|
}
|
|
|
|
return (0, "started");
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=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 ($class, @mon_nodes)=@_;
|
|
%status=();
|
|
my @active_nodes=();
|
|
my @inactive_nodes=();
|
|
if ((@mon_nodes)&& (@mon_nodes > 0)) {
|
|
#get all the active nodes
|
|
my $nodes= join(' ', @mon_nodes);
|
|
my $temp=`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;
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 stop
|
|
This function gets called by the monitorctrl module when
|
|
xcatd stops. It stops the monitoring on all nodes, stops
|
|
the daemons and does necessary cleanup process for the
|
|
RMC monitoring.
|
|
Arguments:
|
|
none
|
|
Returns:
|
|
(return code, message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub stop {
|
|
#print "rmcmon::stop called\n";
|
|
|
|
#TODO: stop condition-response associtations.
|
|
return (0, "stopped");
|
|
}
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 supportNodeStatusMon
|
|
This function is called by the monitorctrl module to check
|
|
if RMC can help monitoring and returning the node status.
|
|
|
|
Arguments:
|
|
none
|
|
Returns:
|
|
1
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub supportNodeStatusMon {
|
|
#print "rmcmon::supportNodeStatusMon called\n";
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 startNodeStatusMon
|
|
This function is called by the monitorctrl module to tell
|
|
RMC to start monitoring the node status and feed them back
|
|
to xCAT. RMC will start setting up the condition/response
|
|
to monitor the node status changes.
|
|
|
|
Arguments:
|
|
None.
|
|
Returns:
|
|
(return code, message)
|
|
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub startNodeStatusMon {
|
|
#print "rmcmon::startNodeStatusMon called\n";
|
|
my $retcode=0;
|
|
my $retmsg="started";
|
|
my $isSV=xCAT::Utils->isServiceNode();
|
|
if ($isSV) { return ($retcode, $retmsg); }
|
|
|
|
#get all the nodes status from IBM.MngNode class of local host and
|
|
#the identification of this node
|
|
my $noderef=xCAT_monitoring::monitorctrl->getMonHierarchy();
|
|
my @hostinfo=xCAT::Utils->determinehostname();
|
|
%iphash=();
|
|
foreach(@hostinfo) {$iphash{$_}=1;}
|
|
if (!$isSV) { $iphash{'noservicenode'}=1;}
|
|
|
|
my @servicenodes=();
|
|
my %status_hash=();
|
|
foreach my $key (keys (%$noderef)) {
|
|
my @key_a=split(',', $key);
|
|
if (! $iphash{$key_a[0]}) { push @servicenodes, $key_a[0]; }
|
|
my $mon_nodes=$noderef->{$key};
|
|
foreach(@$mon_nodes) {
|
|
my $node_info=$_;
|
|
$status_hash{$node_info->[0]}=$node_info->[2];
|
|
}
|
|
}
|
|
|
|
#get nodestatus from RMC and update the xCAT DB
|
|
($retcode, $retmsg) = saveRMCNodeStatusToxCAT(\%status_hash);
|
|
if ($retcode != 0) {
|
|
$retmsg="Error occurred while updating xCAT node status from RMC data.:$retmsg";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
foreach (@servicenodes) {
|
|
($retcode, $retmsg) = saveRMCNodeStatusToxCAT(\%status_hash, $_);
|
|
if ($retcode != 0) {
|
|
$retmsg="Error occurred while updating xCAT node status from RMC data from $_.:$retmsg";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
}
|
|
|
|
#start monitoring the status of mn's immediate children
|
|
my $result=`startcondresp NodeReachability UpdatexCATNodeStatus 2>&1`;
|
|
if ($?) {
|
|
$retcode=$?;
|
|
$retmsg="Error start node status monitoring: $result";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
|
|
#start monitoring the status of mn's grandchildren via their service nodes
|
|
$result=`startcondresp NodeReachability_H UpdatexCATNodeStatus 2>&1`;
|
|
if ($?) {
|
|
$retcode=$?;
|
|
$retmsg="Error start node status monitoring: $result";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
|
|
return ($retcode, $retmsg);
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 saveRMCNodeStatusToxCAT
|
|
This function gets RMC node status and save them to xCAT database
|
|
|
|
Arguments:
|
|
$oldstatus a pointer to a hash table that has the current node status
|
|
$node the name of the service node to run RMC command from. If null, get from local host.
|
|
Returns:
|
|
(return code, message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub saveRMCNodeStatusToxCAT {
|
|
#print "rmcmon::saveRMCNodeStatusToxCAT called\n";
|
|
my $retcode=0;
|
|
my $retmsg="started";
|
|
my $statusref=shift;
|
|
if ($statusref =~ /xCAT_monitoring::rmcmon/) {
|
|
$statusref=shift;
|
|
}
|
|
my $node=shift;
|
|
|
|
%status_hash=%$statusref;
|
|
|
|
#get all the node status from mn's children
|
|
my $result;
|
|
if ($node) {
|
|
$result=`CT_MANAGEMENT_SCOPE=4 /usr/bin/lsrsrc-api -o IBM.MngNode::::$node::Name::Status 2>&1`;
|
|
} else {
|
|
$result=`CT_MANAGEMENT_SCOPE=1 /usr/bin/lsrsrc-api -s IBM.MngNode::::Name::Status 2>&1`;
|
|
}
|
|
if ($?) {
|
|
$retcode=$?;
|
|
$retmsg=$result;
|
|
xCAT::MsgUtils->message('SI', "[mon]: Error getting node status from RMC: $result\n");
|
|
return ($retcode, $retmsg);
|
|
} else {
|
|
my @active_nodes=();
|
|
my @inactive_nodes=();
|
|
if ($result) {
|
|
my @lines=split('\n', $result);
|
|
#only save the ones that needs to change
|
|
foreach (@lines) {
|
|
@pairs=split('::', $_);
|
|
if ($pairs[1]==1) {
|
|
if ($status_hash{$pairs[0]} ne $::STATUS_ACTIVE) { push @active_nodes,$pairs[0];}
|
|
}
|
|
else {
|
|
if ($status_hash{$pairs[0]} ne $::STATUS_INACTIVE) { push @inactive_nodes, $pairs[0];}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my %new_node_status=();
|
|
if (@active_nodes>0) {
|
|
$new_node_status{$::STATUS_ACTIVE}=\@active_nodes;
|
|
}
|
|
if (@inactive_nodes>0) {
|
|
$new_node_status{$::STATUS_INACTIVE}=\@inactive_nodes;
|
|
}
|
|
#only set the node status for the changed ones
|
|
if (keys(%new_node_status) > 0) {
|
|
xCAT_monitoring::xcatmon::processNodeStatusChanges(\%new_node_status);
|
|
}
|
|
return ($retcode, $retmsg);
|
|
}
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 stopNodeStatusMon
|
|
This function is called by the monitorctrl module to tell
|
|
RMC to stop feeding the node status info back to xCAT. It will
|
|
stop the condition/response that is monitoring the node status.
|
|
|
|
Arguments:
|
|
none
|
|
Returns:
|
|
(return code, message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub stopNodeStatusMon {
|
|
#print "rmcmon::stopNodeStatusMon called\n";
|
|
my $retcode=0;
|
|
my $retmsg="stopped";
|
|
my $isSV=xCAT::Utils->isServiceNode();
|
|
if ($isSV) { return ($retcode, $retmsg); }
|
|
|
|
#stop monitoring the status of mn's immediate children
|
|
my $result=`stopcondresp NodeReachability UpdatexCATNodeStatus 2>&1`;
|
|
if ($?) {
|
|
$retcode=$?;
|
|
$retmsg="Error stop node status monitoring: $result";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
|
|
#stop monitoring the status of mn's grandchildren via their service nodes
|
|
$result=`stopcondresp NodeReachability_H UpdatexCATNodeStatus 2>&1`;
|
|
if ($?) {
|
|
$retcode=$?;
|
|
$retmsg="Error stop node status monitoring: $result";
|
|
xCAT::MsgUtils->message('SI', "[mon]: $retmsg\n");
|
|
}
|
|
return ($retcode, $retmsg);
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 getNodeID
|
|
This function gets the nodeif for the given node.
|
|
|
|
Arguments:
|
|
node
|
|
Returns:
|
|
node id for the given node
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub getNodeID {
|
|
my $node=shift;
|
|
if ($node =~ /xCAT_monitoring::rmcmon/) {
|
|
$node=shift;
|
|
}
|
|
my $tab=xCAT::Table->new("mac", -create =>0);
|
|
my $tmp=$tab->getNodeAttribs($node, ['mac']);
|
|
if (defined($tmp) && ($tmp)) {
|
|
my $mac=$tmp->{mac};
|
|
$mac =~ s/://g;
|
|
$mac .= "0000";
|
|
$tab->close();
|
|
return $mac;
|
|
}
|
|
$tab->close();
|
|
return undef;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 getLocalNodeID
|
|
This function goes to RMC and gets the nodeid for the local host.
|
|
|
|
Arguments:
|
|
node
|
|
Returns:
|
|
node id for the local host.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub getLocalNodeID {
|
|
my $node_id=`/usr/sbin/rsct/bin/lsnodeid`;
|
|
if ($?==0) {
|
|
chomp($node_id);
|
|
return $node_id;
|
|
} else {
|
|
return undef;
|
|
}
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 addNodes
|
|
This function adds the nodes into the RMC cluster.
|
|
Arguments:
|
|
nodes --nodes to be added. It is a pointer to an array. If the next argument is
|
|
1, each element is a ref to an array of [nodes, status]. For example:
|
|
[['node1', 'active'], ['node2', 'booting']..].
|
|
if the next argument is 0, each element is a node name to be added.
|
|
boolean -- 1, or 0.
|
|
Returns:
|
|
(error code, error message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub addNodes {
|
|
return (0, "ok"); #not handle it now, wait when nodelist.status work is done
|
|
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 addNodes_noChecking
|
|
This function gdds the nodes into the RMC cluster, it does not check the OSI type and
|
|
if the node has already defined.
|
|
Arguments:
|
|
nodes --an array of nodes to be added.
|
|
Returns:
|
|
(error code, error message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub addNodes_noChecking {
|
|
|
|
my $pmon_nodes=shift;
|
|
if ($pmon_nodes =~ /xCAT_monitoring::rmcmon/) {
|
|
$pmon_nodes=shift;
|
|
}
|
|
|
|
my @mon_nodes = @$pmon_nodes;
|
|
my $master=shift;
|
|
|
|
#print "rmcmon::addNodes_noChecking get called with @mon_nodes\n";
|
|
my @hostinfo=xCAT::Utils->determinehostname();
|
|
%iphash=();
|
|
foreach(@hostinfo) {$iphash{$_}=1;}
|
|
|
|
my $ms_host_name=hostname();
|
|
|
|
my $ms_node_id;
|
|
my $mn_node_id;
|
|
my $ms_name;
|
|
my $ms_aliases;
|
|
my $ms_addrtype;
|
|
my $ms_length;
|
|
my @ms_addrs;
|
|
my $ms_ipaddresses;
|
|
|
|
my $first_time=1;
|
|
foreach(@mon_nodes) {
|
|
|
|
my $node=$_;
|
|
|
|
if ($first_time) {
|
|
$first_time=0;
|
|
#get ms node id, hostname, ip etc
|
|
$ms_node_id=`/usr/sbin/rsct/bin/lsnodeid`;
|
|
chomp($ms_node_id);
|
|
($ms_name,$ms_aliases,$ms_addrtype,$ms_length,@ms_addrs) = gethostbyname($ms_host_name);
|
|
chomp($ms_name);
|
|
|
|
$ms_ipaddresses="{";
|
|
foreach (@ms_addrs) {
|
|
$ms_ipaddresses .= '"' .inet_ntoa($_) . '",';
|
|
}
|
|
chop($ms_ipaddresses);
|
|
$ms_ipaddresses .= "}";
|
|
}
|
|
|
|
#get info for the node
|
|
if($iphash{$node}) {
|
|
$mn_node_id=$ms_node_id;
|
|
} else {
|
|
if ($^O =~ /^linux/i) {
|
|
$mn_node_id=`$::XCATROOT/bin/psh --nonodecheck $node /usr/sbin/rsct/bin/lsnodeid 2>&1`;
|
|
} else {
|
|
$mn_node_id=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $node -t 30 /usr/sbin/rsct/bin/lsnodeid 2>&1`;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: Cannot get NodeID for $node. $mn_node_id\n");
|
|
next;
|
|
}
|
|
if ($mn_node_id =~ s/.*([0-9 a-g]{16}).*/$1/s) {;}
|
|
else { xCAT::MsgUtils->message('SI', "[mon]: No node id found for $node:\n$mn_node_id\n"); next;}
|
|
}
|
|
|
|
my ($mn_name,$mn_aliases,$mn_addrtype,$mn_length,@mn_addrs) = gethostbyname($node);
|
|
chomp($mn_name);
|
|
my $mn_ipaddresses="{";
|
|
foreach (@mn_addrs) {
|
|
$mn_ipaddresses .= '"'.inet_ntoa($_) . '",';
|
|
}
|
|
chop($mn_ipaddresses);
|
|
$mn_ipaddresses .= "}";
|
|
# print " mn_name=$mn_name, mn_aliases=$mn_aliases, mn_ipaddr=$mn_ipaddresses, mn_node_id=$mn_node_id\n";
|
|
|
|
# define resource in IBM.MngNode class on server
|
|
$result=`mkrsrc-api IBM.MngNode::Name::"$node"::KeyToken::"$node"::IPAddresses::"$mn_ipaddresses"::NodeID::0x$mn_node_id 2>&1`;
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: define resource in IBM.MngNode class result=$result\n");
|
|
next;
|
|
}
|
|
|
|
#copy the configuration script and run it locally
|
|
if($iphash{$node}) {
|
|
$result=`/usr/bin/mkrsrc-api IBM.MCP::MNName::"$node"::KeyToken::"$master"::IPAddresses::"$ms_ipaddresses"::NodeID::0x$ms_node_id`;
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: $result\n");
|
|
next;
|
|
}
|
|
} else {
|
|
if ($^O =~ /^linux/i) {
|
|
$result=`scp $::XCATROOT/sbin/rmcmon/configrmcnode $node:/tmp 2>&1`;
|
|
} else {
|
|
$result=`XCATBYPASS=Y $::XCATROOT/bin/xdcp $node $::XCATROOT/sbin/rmcmon/configrmcnode /tmp 2>&1`;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: rmcmon:addNodes: cannot copy the file configrmcnode to node $node\n");
|
|
next;
|
|
}
|
|
if ($^O =~ /^linux/i) {
|
|
$result=`$::XCATROOT/bin/psh --nonodecheck $node NODE=$node MONSERVER=$master MS_NODEID=$ms_node_id /tmp/configrmcnode 1 2>&1`;
|
|
} else {
|
|
$result=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $node NODE=$node MONSERVER=$master MS_NODEID=$ms_node_id /tmp/configrmcnode 1 2>&1`;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: $result\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return (0, "ok");
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 removeNodes
|
|
This function removes the nodes from the RMC cluster.
|
|
Arguments:
|
|
nodes --nodes to be added. It is a pointer to an array. If the next argument is
|
|
1, each element is a ref to an array of [nodes, nodetype, status]. For example:
|
|
[['node1', 'active'], ['node2', 'booting']..].
|
|
if the next argument is 0, each element is a node name to be added.
|
|
boolean -- 1, or 0.
|
|
Returns:
|
|
(error code, error message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub removeNodes {
|
|
return (0, "ok"); #not handle it now, wait when nodelist.status work is done
|
|
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 removeNodes_noChecking
|
|
This function removes the nodes from the RMC cluster.
|
|
Arguments:
|
|
nodes --a pointer to a array of node names to be removed.
|
|
|
|
Returns:
|
|
(error code, error message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub removeNodes_noChecking {
|
|
my $pmon_nodes=shift;
|
|
if ($pmon_nodes =~ /xCAT_monitoring::rmcmon/) {
|
|
$pmon_nodes=shift;
|
|
}
|
|
my @mon_nodes = @$pmon_nodes;
|
|
|
|
my $ms_host_name=hostname();
|
|
|
|
|
|
#print "rmcmon::removeNodes_noChecking get called with @mon_nodes\n";
|
|
|
|
foreach(@mon_nodes) {
|
|
my $node=$_;
|
|
|
|
#remove resource in IBM.MngNode class on server
|
|
my $result=`rmrsrc-api -s IBM.MngNode::"Name=\\\"\"$node\\\"\"" 2>&1`;
|
|
if ($?) {
|
|
if ($result =~ m/2612-023/) { #resource not found
|
|
next;
|
|
}
|
|
xCAT::MsgUtils->message('SI', "[mon]: Remove resource in IBM.MngNode class result=$result\n");
|
|
}
|
|
|
|
# TODO: check all the nodes together or use the 'status' value
|
|
#if the node is inactive, forget it
|
|
if ($ms_host_name ne $node) {
|
|
`fping -a $node 2> /dev/null`;
|
|
if ($?) {
|
|
next;
|
|
}
|
|
}
|
|
|
|
if ($ms_host_name eq $node) {
|
|
$result= `/usr/bin/rmrsrc-api -s IBM.MCP::"MNName=\\\"\"$node\\\"\"" 2>&1`;
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: $result\n");
|
|
}
|
|
} else {
|
|
#copy the configuration script and run it locally
|
|
if ($^O =~ /^linux/i) {
|
|
$result=`scp $::XCATROOT/sbin/rmcmon/configrmcnode $node:/tmp 2>&1 `;
|
|
} else {
|
|
$result=`XCATBYPASS=Y $::XCATROOT/bin/xdcp $node $::XCATROOT/sbin/rmcmon/configrmcnode /tmp 2>&1 `;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: rmcmon:removeNodes: cannot copy the file configrmcnode to node $node\n");
|
|
next;
|
|
}
|
|
|
|
if ($^O =~ /^linux/i) {
|
|
$result=`$::XCATROOT/bin/psh --nonodecheck $node NODE=$node /tmp/configrmcnode -1 2>&1`;
|
|
} else {
|
|
$result=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $node NODE=$node /tmp/configrmcnode -1 2>&1`;
|
|
}
|
|
if ($?) {
|
|
xCAT::MsgUtils->message('SI', "[mon]: $result\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return (0, "ok");
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 processSettingChanges
|
|
This function gets called when the setting for this monitoring plugin
|
|
has been changed in the monsetting table.
|
|
Arguments:
|
|
none.
|
|
Returns:
|
|
0 for successful.
|
|
non-0 for not successful.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub processSettingChanges {
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 getDiscription
|
|
This function returns the detailed description of the plugin inluding the
|
|
valid values for its settings in the monsetting tabel.
|
|
Arguments:
|
|
none
|
|
Returns:
|
|
The description.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub getDescription {
|
|
return
|
|
" Description:
|
|
rmcmon uses IBM's Resource Monitoring and Control (RMC) component
|
|
of Reliable Scalable Cluster Technology (RSCT) to monitor the
|
|
xCAT cluster. RMC has built-in resources such as CPU, memory,
|
|
process, network, file system etc for monitoring. RMC can also be
|
|
used to provide node liveness status monitoring for xCAT. RMC is
|
|
good for threadhold monitoring. xCAT automatically sets up the
|
|
monitoring domain for RMC during node deployment time. To start
|
|
RMC monitoring, use
|
|
monstart rmcmon
|
|
or
|
|
monstart rmcmon -n (to include node status monitoring).
|
|
Settings:
|
|
none.\n";
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 getNodeConfData
|
|
This function gets a list of configuration data that is needed by setting up
|
|
node monitoring. These data-value pairs will be used as environmental variables
|
|
on the given node.
|
|
Arguments:
|
|
node
|
|
pointer to a hash that will take the data.
|
|
Returns:
|
|
none
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub getNodeConfData {
|
|
#check if rsct is installed or not
|
|
if (! -e "/usr/bin/lsrsrc") {
|
|
return;
|
|
}
|
|
|
|
my $node=shift;
|
|
if ($node =~ /xCAT_monitoring::rmcmon/) {
|
|
$node=shift;
|
|
}
|
|
my $ref_ret=shift;
|
|
|
|
#get node ids for RMC monitoring
|
|
my $nodeid=xCAT_monitoring::rmcmon->getNodeID($node);
|
|
if (defined($nodeid)) {
|
|
$ref_ret->{NODEID}=$nodeid;
|
|
}
|
|
my $ms_nodeid=xCAT_monitoring::rmcmon->getLocalNodeID();
|
|
if (defined($ms_nodeid)) {
|
|
$ref_ret->{MS_NODEID}=$ms_nodeid;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 configMaster4Nodes
|
|
This function configures the current the localhost to accept the given nodes
|
|
into the monitoring domain.
|
|
Arguments:
|
|
noderef a pointer to an array of nodes.
|
|
Returns:
|
|
(code, message)
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub configMaster4Nodes {
|
|
my $noderef=shift;
|
|
if ($noderef =~ /xCAT_monitoring::rmcmon/) {
|
|
$noderef=shift;
|
|
}
|
|
if (!$noderef) { return (0, "");}
|
|
|
|
#check if rsct is installed or not
|
|
if (! -e "/usr/bin/lsrsrc") {
|
|
return (0, "");
|
|
}
|
|
|
|
#restart rmc daemon if it is not active
|
|
chomp(my $pid= `/bin/ps -ef | /bin/grep rmcd | /bin/grep -v grep | /bin/awk '{print \$2}'`);
|
|
unless($pid){
|
|
#restart rmc daemon
|
|
$result=`startsrc -s ctrmc`;
|
|
if ($?) {
|
|
return (1, "RMC deamon cannot be started\n");
|
|
}
|
|
}
|
|
|
|
my $message;
|
|
my $ret=0;
|
|
my $table3=xCAT::Table->new("nodetype", -create =>0);
|
|
foreach(@$noderef) {
|
|
my $node=$_;
|
|
|
|
#check if the node is OSI, akip if not
|
|
my $tmp3=$table3->getNodeAttribs($node, ['nodetype']);
|
|
my $nodetype=$::NODETYPE_OSI; #default
|
|
if (defined($tmp3) && ($tmp3)) {
|
|
if ($tmp3->{nodetype}) { $nodetype=$tmp3->{nodetype}; }
|
|
}
|
|
if ($nodetype !~ /$::NODETYPE_OSI/) { next; }
|
|
|
|
#check if the node is already defined, skip if it is
|
|
$result=`/usr/bin/lsrsrc-api -s IBM.MngNode::"Name==\'$node\'"::Name 2>&1`;
|
|
if ($?==0) { next;}
|
|
|
|
#get info for the node
|
|
my $mn_node_id=getNodeID($node);
|
|
my ($mn_name,$mn_aliases,$mn_addrtype,$mn_length,@mn_addrs) = gethostbyname($node);
|
|
chomp($mn_name);
|
|
my $mn_ipaddresses="{";
|
|
foreach (@mn_addrs) {
|
|
$mn_ipaddresses .= '"'.inet_ntoa($_) . '",';
|
|
}
|
|
chop($mn_ipaddresses);
|
|
$mn_ipaddresses .= "}";
|
|
# print " mn_name=$mn_name, mn_aliases=$mn_aliases, mn_ipaddr=$mn_ipaddresses, mn_node_id=$mn_node_id\n";
|
|
|
|
# define resource in IBM.MngNode class on server
|
|
$result=`mkrsrc-api IBM.MngNode::Name::"$node"::KeyToken::"$node"::IPAddresses::"$mn_ipaddresses"::NodeID::0x$mn_node_id 2>&1`;
|
|
if ($?) {
|
|
$ret=$?;
|
|
$message .= "define resource in IBM.MngNode class result=$result\n";
|
|
xCAT::MsgUtils->message('S', "[mon]: $message");
|
|
next;
|
|
}
|
|
}
|
|
if ( $table3) { $table3->close(); }
|
|
|
|
return ($ret, $message);
|
|
}
|