more monitoring code to support hierarchical management
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@493 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
d46c653a7e
commit
a227c6eb35
@ -7,11 +7,12 @@ BEGIN
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
use xCAT::NodeRange;
|
||||
use Sys::Hostname;
|
||||
use Socket;
|
||||
use xCAT::Utils;
|
||||
use xCAT::GlobalDef;
|
||||
|
||||
print "xCAT_monitoring::rmcmon loaded\n";
|
||||
#print "xCAT_monitoring::rmcmon loaded\n";
|
||||
|
||||
1;
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -34,9 +35,9 @@ print "xCAT_monitoring::rmcmon loaded\n";
|
||||
in the xCAT cluster.
|
||||
Arguments:
|
||||
monservers --A hash reference keyed by the monitoring server nodes
|
||||
and each value is a ref to an array of [nodes, nodetype] arrays
|
||||
and each value is a ref to an array of [nodes, nodetype, status] arrays
|
||||
monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
Returns:
|
||||
(return code, message)
|
||||
=cut
|
||||
@ -141,9 +142,9 @@ sub supportNodeStatusMon {
|
||||
|
||||
Arguments:
|
||||
monservers --A hash reference keyed by the monitoring server nodes
|
||||
and each value is a ref to an array of [nodes, nodetype] arrays
|
||||
and each value is a ref to an array of [nodes, nodetype, status] arrays
|
||||
monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
Returns:
|
||||
(return code, message)
|
||||
|
||||
@ -178,9 +179,9 @@ sub stopNodeStatusMon {
|
||||
This function gdds the nodes into the RMC cluster.
|
||||
Arguments:
|
||||
nodes --nodes to be added. It is a hash reference keyed by the monitoring server
|
||||
nodes and each value is a ref to an array of [nodes, nodetype] arrays monitored
|
||||
nodes and each value is a ref to an array of [nodes, nodetype, status] arrays monitored
|
||||
by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
verbose -- verbose mode. 1 for yes, 0 for no.
|
||||
Returns:
|
||||
none
|
||||
@ -193,16 +194,23 @@ sub addNodes {
|
||||
}
|
||||
my $VERBOSE=shift;
|
||||
|
||||
if ($VERBOSE) { print "rmcmon::addNodes called $noderef=$noderef\n"};
|
||||
#if ($VERBOSE) { print "rmcmon::addNodes called $noderef=$noderef\n"};
|
||||
|
||||
my $ms_host_name=hostname();
|
||||
chomp($ms_host_name);
|
||||
|
||||
foreach (keys(%$noderef)) {
|
||||
my $server=$_;
|
||||
if ($VERBOSE) { print " monitoring server: $server\n";}
|
||||
#if ($VERBOSE) { print " monitoring server: $server\n";}
|
||||
|
||||
if ($server ne $ms_host_name) {
|
||||
next; #only handle the nodes which has this node as the monitor server
|
||||
}
|
||||
|
||||
#check if rsct is installed and running
|
||||
if (! -e "/usr/bin/lsrsrc") {
|
||||
print "RSCT is not is not installed.\n";
|
||||
next;
|
||||
print "RSCT is not installed.\n";
|
||||
return 1;
|
||||
}
|
||||
my $result=`/usr/bin/lssrc -s ctrmc`;
|
||||
if ($result !~ /active/) {
|
||||
@ -210,48 +218,63 @@ sub addNodes {
|
||||
$result=`startsrc -s ctrmc`;
|
||||
if ($?) {
|
||||
print "rmc deamon cannot be started\n";
|
||||
next;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#enable remote client connection
|
||||
`/usr/bin/rmcctrl -p`;
|
||||
|
||||
#get ms node id, hostname, ip etc
|
||||
#TODO: currently one server which is where xcatd is. later changes to use server for hierachy
|
||||
my $ms_node_id=`head -n 1 /var/ct/cfg/ct_node_id`;
|
||||
chomp($ms_node_id);
|
||||
my $ms_host_name=`hostname`;
|
||||
chomp($ms_host_name);
|
||||
my ($ms_name,$ms_aliases,$ms_addrtype,$ms_length,@ms_addrs) = gethostbyname($ms_host_name);
|
||||
chomp($ms_name);
|
||||
|
||||
my $ms_ipaddresses="{";
|
||||
foreach (@ms_addrs) {
|
||||
$ms_ipaddresses .= '"' .inet_ntoa($_) . '",';
|
||||
}
|
||||
chop($ms_ipaddresses);
|
||||
$ms_ipaddresses .= "}";
|
||||
#ms node id, hostname, ip defs
|
||||
my $ms_node_id;
|
||||
my $ms_name,$ms_aliases,$ms_addrtype,$ms_length,@ms_addrs;
|
||||
my $ms_ipaddresses;
|
||||
|
||||
#if ($VERBOSE) {
|
||||
# print " ms_host_name=$ms_host_name, ms_nam=$ms_name, ms_aliases=$ms_aliases, ms_ip_addr=$ms_ipaddresses, ms_node_id=$ms_node_id\n";
|
||||
#}
|
||||
|
||||
my $mon_nodes=$noderef->{$_};
|
||||
my $first_time=1;
|
||||
foreach(@$mon_nodes) {
|
||||
my $node_pair=$_;
|
||||
my $node=$node_pair->[0];
|
||||
my $nodetype=$node_pair->[1];
|
||||
if ((!$nodetype) || ($nodetype =~ /$::NODETYPE_OSI/)) {
|
||||
#RMC deals only with osi type. empty type is treated as osi type
|
||||
#check if the node has already defined
|
||||
$result=`lsrsrc-api -s IBM.MngNode::"Name=\\\"\"$node\\\"\"" 2>&1`;
|
||||
if ($? == 0) { #resource has already defined
|
||||
next;
|
||||
}
|
||||
|
||||
#TODO: check if the node is installed and ready for configuring monitor
|
||||
#TODO: check all nodes at the same time or use the 'status' value in the node
|
||||
`fping -a $node 2> /dev/null`;
|
||||
if ($?) {
|
||||
print "Cannot add the node $node into the RMC domian. The node is inactive.\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($first_time) {
|
||||
$first_time=0;
|
||||
|
||||
#enable remote client connection
|
||||
`/usr/bin/rmcctrl -p`;
|
||||
|
||||
#get ms node id, hostname, ip etc
|
||||
$ms_node_id=`head -n 1 /var/ct/cfg/ct_node_id`;
|
||||
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
|
||||
$mn_node_id=`psh $node "head -n 1 /var/ct/cfg/ct_node_id" 2>&1`;
|
||||
$mn_node_id =~ s/.*([0-9 a-g]{16}).*/$1/s;
|
||||
@ -269,18 +292,22 @@ sub addNodes {
|
||||
#}
|
||||
|
||||
# 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`;
|
||||
print "define resource in IBM.MngNode class result=$result\n";
|
||||
$result=`mkrsrc-api IBM.MngNode::Name::"$node"::KeyToken::"$node"::IPAddresses::"$mn_ipaddresses"::NodeID::0x$mn_node_id 2>&1`;
|
||||
if ($?) {
|
||||
print "define resource in IBM.MngNode class result=$result\n";
|
||||
}
|
||||
|
||||
#copy the configuration script and run it locally
|
||||
$result=`scp $::XCATROOT/lib/perl/xCAT_monitoring/rmc/configrmcnode $node:/tmp`;
|
||||
if ($resul>0) {
|
||||
$result=`scp $::XCATROOT/sbin/rmcmon/configrmcnode $node:/tmp 2>&1`;
|
||||
if ($?) {
|
||||
print "rmcmon:addNodes: cannot copy the file configrmcnode to node $node\n";
|
||||
next;
|
||||
}
|
||||
|
||||
$result=`psh $node /tmp/configrmcnode -a $node $ms_host_name $ms_ipaddresses 0x$ms_node_id`;
|
||||
print "$result\n";
|
||||
$result=`psh $node /tmp/configrmcnode -a $node $ms_host_name $ms_ipaddresses 0x$ms_node_id 2>&1`;
|
||||
if ($?) {
|
||||
print "$result\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,9 +321,9 @@ sub addNodes {
|
||||
This function removes the nodes from the RMC cluster.
|
||||
Arguments:
|
||||
nodes --nodes to be removed. It is a hash reference keyed by the monitoring server
|
||||
nodes and each value is a ref to an array of [nodes, nodetype] arrays monitored
|
||||
nodes and each value is a ref to an array of [nodes, nodetype, status] arrays monitored
|
||||
by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
verbose -- verbose mode. 1 for yes, 0 for no.
|
||||
Returns:
|
||||
none
|
||||
@ -309,48 +336,53 @@ sub removeNodes {
|
||||
}
|
||||
my $VERBOSE=shift;
|
||||
|
||||
#if ($VERBOSE) { print "rmcmon::removeNodes called $noderef=$noderef\n"};
|
||||
#if ($VERBOSE) { print "rmcmon::removeNodes called\n"};
|
||||
|
||||
my $local_host_name=hostname();
|
||||
chomp($local_host_name);
|
||||
foreach (keys(%$noderef)) {
|
||||
$server=$_;
|
||||
#print " monitoring server: $server\n";
|
||||
#print " monitoring server: $server local_host_name=$local_host_name\n";
|
||||
#only handle the nodes which has this node as the monitor server
|
||||
if ($server ne $local_host_name) {next; }
|
||||
|
||||
my $mon_nodes=$noderef->{$_};
|
||||
foreach(@$mon_nodes) {
|
||||
my $node_pair=$_;
|
||||
my $node=$node_pair->[0];
|
||||
my $nodetype=$node_pair->[1];
|
||||
#if ($VERBOSE) { print " node=$node, nodetype=$nodetype\n"; }
|
||||
if ((!$nodetype) || ($nodetype =~ /$::NODETYPE_OSI/)) {
|
||||
#RMC deals only with osi type. empty type is treated as osi type
|
||||
|
||||
#TODO: check if the node is installed and ready for configuring monitor
|
||||
`fping -a $node 2> /dev/null`;
|
||||
if ($?) {
|
||||
print "Cannot remove node $node from the RMC domian. The node is inactive.\n";
|
||||
|
||||
#remove resource in IBM.MngNode class on server
|
||||
my $result=`rmrsrc-api -s IBM.MngNode::"Name=\\\"\"$node\\\"\"" 2>&1`;
|
||||
if ($?) { print "remove resource in IBM.MngNode class result=$result\n"; }
|
||||
if ($result =~ m/2612-023/) { #resource not found
|
||||
next;
|
||||
}
|
||||
|
||||
#remove resource in IBM.MngNode class on server
|
||||
my $result=`rmrsrc-api -s IBM.MngNode::"Name=\\\"\"$node\\\"\""`;
|
||||
if ($VERBOSE) { print "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
|
||||
`fping -a $node 2> /dev/null`;
|
||||
if ($?) {
|
||||
next;
|
||||
}
|
||||
|
||||
#copy the configuration script and run it locally
|
||||
$result=`scp $::XCATROOT/lib/perl/xCAT_monitoring/rmc/configrmcnode $node:/tmp`;
|
||||
if ($resul>0) {
|
||||
$result=`scp $::XCATROOT/sbin/rmcmon/configrmcnode $node:/tmp 2>&1 `;
|
||||
if ($?) {
|
||||
print "rmcmon:removeNodes: cannot copy the file configrmcnode to node $node\n";
|
||||
next;
|
||||
}
|
||||
|
||||
$result=`psh --nonodecheck $node /tmp/configrmcnode -d $node`;
|
||||
print "$result\n";
|
||||
$result=`psh --nonodecheck $node /tmp/configrmcnode -d $node 2>&1`;
|
||||
if ($?) {
|
||||
print "$result\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ BEGIN
|
||||
|
||||
$RES::Sensor{'ErrorLogSensor'} = {
|
||||
Name => q(ErrorLogSensor),
|
||||
Command => "$::XCATROOT/lib/perl/xCAT_monitoring/rmc/monerrorlog",
|
||||
Command => "$::XCATROOT/sbin/rmcmon/monerrorlog",
|
||||
UserName => q(root),
|
||||
RefreshInterval => q(60),
|
||||
ControlFlags => q(4),
|
||||
|
@ -6,7 +6,7 @@ BEGIN
|
||||
|
||||
$RES::Sensor{'CFMRootModTime'} = {
|
||||
Name => q(CFMRootModTime),
|
||||
Command => "$::XCATROOT/lib/perl/xCAT_monitoring/rmc/mtime /cfmroot",
|
||||
Command => "$::XCATROOT/sbin/rmcmon/mtime /cfmroot",
|
||||
UserName => q(root),
|
||||
RefreshInterval => q(60),
|
||||
};
|
||||
|
@ -1,341 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package NodeUtils;
|
||||
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 NodeUtils module
|
||||
=head2 NodeUtils module is used to store common functions for RMC monitoring on
|
||||
xCAT clusters.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
sub isHMC
|
||||
{
|
||||
my $hmcfile = "/opt/hsc/data/hmcType.properties";
|
||||
if (-e $hmcfile) { return 1; }
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
if this function is used in a scalar context, the output is joined into a single string
|
||||
with the newlines separating the lines.
|
||||
Arguments:
|
||||
command, exitcode and reference to output
|
||||
Returns:
|
||||
see below
|
||||
Error:
|
||||
Normally, if there is an error running the cmd, it will display the error msg
|
||||
and exit with the cmds exit code, unless exitcode is given one of the
|
||||
following values:
|
||||
0: display error msg, DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-1: DO NOT display error msg and DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-2: DO the default behavior (display error msg and exit with cmds
|
||||
exit code.
|
||||
number > 0: Display error msg and exit with the given code
|
||||
Example:
|
||||
my $outref = NodeUtils->runcmd($cmd, -2, 1);
|
||||
Comments:
|
||||
If refoutput is true, then the output will be returned as a reference to
|
||||
an array for efficiency.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runcmd
|
||||
{
|
||||
my ($class, $cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
{
|
||||
$::RUNCMD_RC = $? >> 8;
|
||||
my $displayerror = 1;
|
||||
my $rc;
|
||||
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
|
||||
{
|
||||
if ($exitcode > 0)
|
||||
{
|
||||
$rc = $exitcode;
|
||||
} # if not zero, exit with specified code
|
||||
elsif ($exitcode <= 0)
|
||||
{
|
||||
$rc = ''; # if zero or negative, do not exit
|
||||
if ($exitcode < 0) { $displayerror = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rc = $::RUNCMD_RC;
|
||||
} # if exitcode not specified, use cmd exit code
|
||||
if ($displayerror)
|
||||
{
|
||||
my $errmsg = '';
|
||||
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
|
||||
{
|
||||
$errmsg = "Segmentation fault $errmsg";
|
||||
}
|
||||
else
|
||||
{
|
||||
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
|
||||
NodeUtils->filterRmcApiOutput($cmd, $outref);
|
||||
$errmsg = join('', @$outref);
|
||||
chomp $errmsg;
|
||||
}
|
||||
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
|
||||
}
|
||||
}
|
||||
if ($refoutput)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return $outref;
|
||||
}
|
||||
elsif (wantarray)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $line = join('', @$outref);
|
||||
chomp $line;
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runrmccmd
|
||||
Runs an RMC commmand
|
||||
Arguments:
|
||||
$rmccmd, $resclass, $options, $select, $exitcode, $nodelist_ref
|
||||
Returns:
|
||||
the output from runcmd($cmd, -2, 1)
|
||||
as a ref to the output array.
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $outref =NodeUtils->runrmccmd('lsrsrc-api', "-i -D ':|:'", $where);
|
||||
Comments:
|
||||
When $nodelist_ref is not null, break it up into smaller slices
|
||||
and run RMC commands seperately for each slice.
|
||||
Otherwise just run RMC commands with the arguments passed in.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runrmccmd
|
||||
{
|
||||
my ($class, $rmccmd, $options, $select, $exitcode, $nodelist_ref) = @_;
|
||||
|
||||
my @nodelist;
|
||||
my $return_ref = [];
|
||||
|
||||
if (!defined($exitcode))
|
||||
{
|
||||
$exitcode = -2;
|
||||
}
|
||||
|
||||
if(! grep /usr\/bin/, $rmccmd)
|
||||
{
|
||||
# add absolute path
|
||||
$rmccmd = "/usr/bin/$rmccmd";
|
||||
}
|
||||
|
||||
if ($nodelist_ref)
|
||||
{
|
||||
# check whether to break up nodelist for better scalability.
|
||||
@nodelist = @$nodelist_ref;
|
||||
my $divide = 500; # max number of nodes for each division
|
||||
my @sublist;
|
||||
my @newarray;
|
||||
my ($start_index, $end_index, $nodestring);
|
||||
|
||||
my $count = 0;
|
||||
my $times = int(scalar(@nodelist) / $divide);
|
||||
while ($count <= $times)
|
||||
{
|
||||
$start_index = $count * $divide;
|
||||
$end_index =
|
||||
((scalar(@nodelist) - 1) < (($count + 1) * $divide - 1))
|
||||
? (scalar(@nodelist) - 1)
|
||||
: (($count + 1) * $divide - 1);
|
||||
@sublist = @nodelist[$start_index .. $end_index];
|
||||
@newarray = ();
|
||||
foreach my $node (@sublist)
|
||||
{
|
||||
my @vals = split ',|\s', $node;
|
||||
push @newarray, @vals;
|
||||
}
|
||||
$nodestring = join("','", @newarray);
|
||||
|
||||
# replace the pattern in select string with the broken up node string
|
||||
my $select_new = $select;
|
||||
$select_new =~ s/XXX/$nodestring/;
|
||||
my $cmd = "$rmccmd $options $select_new";
|
||||
my $outref = NodeUtils->runcmd($cmd, $exitcode, 1);
|
||||
push @$return_ref, @$outref;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my $cmd = "$rmccmd $options $select";
|
||||
$return_ref = NodeUtils->runcmd($cmd, $exitcode, 1);
|
||||
}
|
||||
|
||||
# returns a reference to the output array
|
||||
return $return_ref;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 quote
|
||||
Quote a string, taking into account embedded quotes. This function is most
|
||||
useful when passing string through the shell to another cmd. It handles one
|
||||
level of embedded double quotes, single quotes, and dollar signs.
|
||||
Arguments:
|
||||
string to quote
|
||||
Returns:
|
||||
quoted string
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub quote
|
||||
{
|
||||
my ($class, $str) = @_;
|
||||
|
||||
# if the value has imbedded double quotes, use single quotes. If it also has
|
||||
# single quotes, escape the double quotes.
|
||||
if (!($str =~ /\"/)) # no embedded double quotes
|
||||
{
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
elsif (!($str =~ /\'/))
|
||||
{
|
||||
$str = qq('$str');
|
||||
} # no embedded single quotes
|
||||
else # has both embedded double and single quotes
|
||||
{
|
||||
# Escape the double quotes. (Escaping single quotes does not seem to work
|
||||
# in the shells.)
|
||||
$str =~ s/\"/\\\"/sg; #" this comment helps formating
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 filterRmcApiOutput
|
||||
filter RMC Api Output
|
||||
Arguments:
|
||||
RMC command
|
||||
Output reference
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
NodeUtils->filterRmcApiOutput($cmd, $outref);
|
||||
Comments:
|
||||
The error msgs from the RPM -api cmds are pretty messy.
|
||||
This routine cleans them up a little bit.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($class, $cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
# Figure out the output delimiter
|
||||
my ($d) = $cmd =~ / -D\s+(\S+)/;
|
||||
if (length($d)) {
|
||||
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
|
||||
# escape any chars perl pattern matching would intepret as special chars
|
||||
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d = '::';
|
||||
} # this is the default output delimiter for the -api cmds
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 readFile
|
||||
Read a file and return its content.
|
||||
Arguments:
|
||||
filename
|
||||
Returns:
|
||||
file contents or undef
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
undef
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub readFile
|
||||
{
|
||||
my ($class, $filename) = @_;
|
||||
open(FILE, "<$filename") or return undef;
|
||||
my @contents;
|
||||
@contents = <FILE>;
|
||||
close(FILE);
|
||||
if (wantarray) { return @contents; }
|
||||
else { return join('', @contents); }
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 touchFile
|
||||
Arguments: $filename, $donotExit
|
||||
Returns: non zero return code indicates error
|
||||
Example: NodeUtils->touchFile("/var/opt/csm/touch");
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub touchFile
|
||||
{
|
||||
my ($class, $filename, $donotExit) = @_;
|
||||
my $fh;
|
||||
my $rc = 0;
|
||||
if (!-e $filename) {
|
||||
#if the file doesn't exist we need to open and close it
|
||||
open($fh, ">>$filename") or $rc++;
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
close($fh) or $rc++;
|
||||
}
|
||||
else {
|
||||
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
|
||||
my $now = time;
|
||||
utime($now, $now, $filename);
|
||||
}
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,19 +1,144 @@
|
||||
#!/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/xCAT_monitoring/rmc";
|
||||
|
||||
use strict;
|
||||
use locale;
|
||||
|
||||
use Getopt::Std;
|
||||
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
|
||||
use IPC::Msg;
|
||||
use NodeUtils;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
if this function is used in a scalar context, the output is joined into a single string
|
||||
with the newlines separating the lines.
|
||||
Arguments:
|
||||
command, exitcode and reference to output
|
||||
Returns:
|
||||
see below
|
||||
Error:
|
||||
Normally, if there is an error running the cmd, it will display the error msg
|
||||
and exit with the cmds exit code, unless exitcode is given one of the
|
||||
following values:
|
||||
0: display error msg, DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-1: DO NOT display error msg and DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-2: DO the default behavior (display error msg and exit with cmds
|
||||
exit code.
|
||||
number > 0: Display error msg and exit with the given code
|
||||
Example:
|
||||
my $outref = runcmd($cmd, -2, 1);
|
||||
Comments:
|
||||
If refoutput is true, then the output will be returned as a reference to
|
||||
an array for efficiency.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
{
|
||||
$::RUNCMD_RC = $? >> 8;
|
||||
my $displayerror = 1;
|
||||
my $rc;
|
||||
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
|
||||
{
|
||||
if ($exitcode > 0)
|
||||
{
|
||||
$rc = $exitcode;
|
||||
} # if not zero, exit with specified code
|
||||
elsif ($exitcode <= 0)
|
||||
{
|
||||
$rc = ''; # if zero or negative, do not exit
|
||||
if ($exitcode < 0) { $displayerror = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rc = $::RUNCMD_RC;
|
||||
} # if exitcode not specified, use cmd exit code
|
||||
if ($displayerror)
|
||||
{
|
||||
my $errmsg = '';
|
||||
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
|
||||
{
|
||||
$errmsg = "Segmentation fault $errmsg";
|
||||
}
|
||||
else
|
||||
{
|
||||
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
$errmsg = join('', @$outref);
|
||||
chomp $errmsg;
|
||||
}
|
||||
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
|
||||
}
|
||||
}
|
||||
if ($refoutput)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return $outref;
|
||||
}
|
||||
elsif (wantarray)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $line = join('', @$outref);
|
||||
chomp $line;
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 filterRmcApiOutput
|
||||
filter RMC Api Output
|
||||
Arguments:
|
||||
RMC command
|
||||
Output reference
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
Comments:
|
||||
The error msgs from the RPM -api cmds are pretty messy.
|
||||
This routine cleans them up a little bit.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
# Figure out the output delimiter
|
||||
my ($d) = $cmd =~ / -D\s+(\S+)/;
|
||||
if (length($d)) {
|
||||
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
|
||||
# escape any chars perl pattern matching would intepret as special chars
|
||||
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d = '::';
|
||||
} # this is the default output delimiter for the -api cmds
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
my $m = ord('xcat_rmc');
|
||||
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
|
||||
@ -25,7 +150,7 @@ my $qcurrentlen = $$stat[5];
|
||||
if ($qcurrentlen >= 10000) {
|
||||
if (!-d "/var/opt/xcat_rmc_err_mon/") {
|
||||
my $cmd = "mkdir -p \"/var/opt/xcat_rmc_err_mon\"";
|
||||
NodeUtils->runcmd($cmd, -1);
|
||||
runcmd($cmd, -1);
|
||||
}
|
||||
open(FILE, ">>/var/opt/xcat_rmc_err_mon/errmsgqueerr.log");
|
||||
my $sdate = `/bin/date`;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 mkrmcresources
|
||||
=head2 mkrmcresources is used to predefine RMC conditions, responses, associations,
|
||||
@ -15,19 +16,280 @@
|
||||
of packaging files, script run after install or from the command line.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl/xCAT_monitoring/rmc";
|
||||
|
||||
use Getopt::Long;
|
||||
use NodeUtils;
|
||||
|
||||
|
||||
$Getopt::Long::ignorecase = 0; #Checks case in GetOptions
|
||||
Getopt::Long::Configure("bundling"); #allows short command line options to be grouped (e.g. -av)
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 quote
|
||||
Quote a string, taking into account embedded quotes. This function is most
|
||||
useful when passing string through the shell to another cmd. It handles one
|
||||
level of embedded double quotes, single quotes, and dollar signs.
|
||||
Arguments:
|
||||
string to quote
|
||||
Returns:
|
||||
quoted string
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub quote
|
||||
{
|
||||
my ($str) = @_;
|
||||
|
||||
# if the value has imbedded double quotes, use single quotes. If it also has
|
||||
# single quotes, escape the double quotes.
|
||||
if (!($str =~ /\"/)) # no embedded double quotes
|
||||
{
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
elsif (!($str =~ /\'/))
|
||||
{
|
||||
$str = qq('$str');
|
||||
} # no embedded single quotes
|
||||
else # has both embedded double and single quotes
|
||||
{
|
||||
# Escape the double quotes. (Escaping single quotes does not seem to work
|
||||
# in the shells.)
|
||||
$str =~ s/\"/\\\"/sg; #" this comment helps formating
|
||||
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
||||
$str =~ s/\`/\\\`/sg;
|
||||
$str = qq("$str");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 filterRmcApiOutput
|
||||
filter RMC Api Output
|
||||
Arguments:
|
||||
RMC command
|
||||
Output reference
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
Comments:
|
||||
The error msgs from the RPM -api cmds are pretty messy.
|
||||
This routine cleans them up a little bit.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
# Figure out the output delimiter
|
||||
my ($d) = $cmd =~ / -D\s+(\S+)/;
|
||||
if (length($d)) {
|
||||
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
|
||||
# escape any chars perl pattern matching would intepret as special chars
|
||||
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d = '::';
|
||||
} # this is the default output delimiter for the -api cmds
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
sub isHMC
|
||||
{
|
||||
my $hmcfile = "/opt/hsc/data/hmcType.properties";
|
||||
if (-e $hmcfile) { return 1; }
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
if this function is used in a scalar context, the output is joined into a single string
|
||||
with the newlines separating the lines.
|
||||
Arguments:
|
||||
command, exitcode and reference to output
|
||||
Returns:
|
||||
see below
|
||||
Error:
|
||||
Normally, if there is an error running the cmd, it will display the error msg
|
||||
and exit with the cmds exit code, unless exitcode is given one of the
|
||||
following values:
|
||||
0: display error msg, DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-1: DO NOT display error msg and DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-2: DO the default behavior (display error msg and exit with cmds
|
||||
exit code.
|
||||
number > 0: Display error msg and exit with the given code
|
||||
Example:
|
||||
my $outref = runcmd($cmd, -2, 1);
|
||||
Comments:
|
||||
If refoutput is true, then the output will be returned as a reference to
|
||||
an array for efficiency.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
{
|
||||
$::RUNCMD_RC = $? >> 8;
|
||||
my $displayerror = 1;
|
||||
my $rc;
|
||||
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
|
||||
{
|
||||
if ($exitcode > 0)
|
||||
{
|
||||
$rc = $exitcode;
|
||||
} # if not zero, exit with specified code
|
||||
elsif ($exitcode <= 0)
|
||||
{
|
||||
$rc = ''; # if zero or negative, do not exit
|
||||
if ($exitcode < 0) { $displayerror = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rc = $::RUNCMD_RC;
|
||||
} # if exitcode not specified, use cmd exit code
|
||||
if ($displayerror)
|
||||
{
|
||||
my $errmsg = '';
|
||||
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
|
||||
{
|
||||
$errmsg = "Segmentation fault $errmsg";
|
||||
}
|
||||
else
|
||||
{
|
||||
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
$errmsg = join('', @$outref);
|
||||
chomp $errmsg;
|
||||
}
|
||||
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
|
||||
}
|
||||
}
|
||||
if ($refoutput)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return $outref;
|
||||
}
|
||||
elsif (wantarray)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $line = join('', @$outref);
|
||||
chomp $line;
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runrmccmd
|
||||
Runs an RMC commmand
|
||||
Arguments:
|
||||
$rmccmd, $resclass, $options, $select, $exitcode, $nodelist_ref
|
||||
Returns:
|
||||
the output from runcmd($cmd, -2, 1)
|
||||
as a ref to the output array.
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $outref =runrmccmd('lsrsrc-api', "-i -D ':|:'", $where);
|
||||
Comments:
|
||||
When $nodelist_ref is not null, break it up into smaller slices
|
||||
and run RMC commands seperately for each slice.
|
||||
Otherwise just run RMC commands with the arguments passed in.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runrmccmd
|
||||
{
|
||||
my ($rmccmd, $options, $select, $exitcode, $nodelist_ref) = @_;
|
||||
|
||||
my @nodelist;
|
||||
my $return_ref = [];
|
||||
|
||||
if (!defined($exitcode))
|
||||
{
|
||||
$exitcode = -2;
|
||||
}
|
||||
|
||||
if(! grep /usr\/bin/, $rmccmd)
|
||||
{
|
||||
# add absolute path
|
||||
$rmccmd = "/usr/bin/$rmccmd";
|
||||
}
|
||||
|
||||
if ($nodelist_ref)
|
||||
{
|
||||
# check whether to break up nodelist for better scalability.
|
||||
@nodelist = @$nodelist_ref;
|
||||
my $divide = 500; # max number of nodes for each division
|
||||
my @sublist;
|
||||
my @newarray;
|
||||
my ($start_index, $end_index, $nodestring);
|
||||
|
||||
my $count = 0;
|
||||
my $times = int(scalar(@nodelist) / $divide);
|
||||
while ($count <= $times)
|
||||
{
|
||||
$start_index = $count * $divide;
|
||||
$end_index =
|
||||
((scalar(@nodelist) - 1) < (($count + 1) * $divide - 1))
|
||||
? (scalar(@nodelist) - 1)
|
||||
: (($count + 1) * $divide - 1);
|
||||
@sublist = @nodelist[$start_index .. $end_index];
|
||||
@newarray = ();
|
||||
foreach my $node (@sublist)
|
||||
{
|
||||
my @vals = split ',|\s', $node;
|
||||
push @newarray, @vals;
|
||||
}
|
||||
$nodestring = join("','", @newarray);
|
||||
|
||||
# replace the pattern in select string with the broken up node string
|
||||
my $select_new = $select;
|
||||
$select_new =~ s/XXX/$nodestring/;
|
||||
my $cmd = "$rmccmd $options $select_new";
|
||||
my $outref = runcmd($cmd, $exitcode, 1);
|
||||
push @$return_ref, @$outref;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my $cmd = "$rmccmd $options $select";
|
||||
$return_ref = runcmd($cmd, $exitcode, 1);
|
||||
}
|
||||
|
||||
# returns a reference to the output array
|
||||
return $return_ref;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 queryResources
|
||||
Queries all resources of a given class or classes. Places
|
||||
@ -47,7 +309,7 @@ sub queryResources
|
||||
{
|
||||
#special case: run lscondresp because Associations do not have names
|
||||
#cant run lsrsrc because Assoctation also does not store names of resources (just handles)
|
||||
my @condresp = NodeUtils->runcmd("LANG=C /usr/bin/lscondresp");
|
||||
my @condresp = runcmd("LANG=C /usr/bin/lscondresp");
|
||||
my $class = $res;
|
||||
$class =~ s/^IBM\.//;
|
||||
splice @condresp, 0,
|
||||
@ -76,7 +338,7 @@ sub queryResources
|
||||
}
|
||||
}
|
||||
|
||||
my $output = NodeUtils->runrmccmd("lsrsrc-api", "-i -m -n -D ':|:'", $where);
|
||||
my $output = runrmccmd("lsrsrc-api", "-i -m -n -D ':|:'", $where);
|
||||
foreach my $line (@$output)
|
||||
{
|
||||
my @array = split(/:\|:/, $line);
|
||||
@ -260,7 +522,7 @@ sub createResources
|
||||
foreach my $attr (keys %{$cre{$resource}})
|
||||
{
|
||||
my $value = $cre{$resource}{$attr};
|
||||
$string .= "${attr}::" . NodeUtils->quote($value) . "::";
|
||||
$string .= "${attr}::" . quote($value) . "::";
|
||||
}
|
||||
if (($sensorflg == 1) && ($::INSTALL))
|
||||
{
|
||||
@ -279,7 +541,7 @@ sub createResources
|
||||
#my $cmd = "/usr/bin/mkrsrc-api $string";
|
||||
#print "running $cmd\n";
|
||||
#system($cmd);
|
||||
NodeUtils->runrmccmd("mkrsrc-api", "", $string);
|
||||
runrmccmd("mkrsrc-api", "", $string);
|
||||
$string = "";
|
||||
$counter = 0;
|
||||
}
|
||||
@ -292,12 +554,12 @@ sub createResources
|
||||
#my $cmd = "/usr/bin/mkrsrc-api $string";
|
||||
#print "running $cmd\n";
|
||||
#system($cmd);
|
||||
NodeUtils->runrmccmd("mkrsrc-api", "", $string);
|
||||
runrmccmd("mkrsrc-api", "", $string);
|
||||
}
|
||||
foreach my $cmd (@assoc_cmds)
|
||||
{
|
||||
#need to make associations after conds and resps have been made
|
||||
NodeUtils->runcmd("$cmd");
|
||||
runcmd("$cmd");
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,15 +586,15 @@ sub changeResources
|
||||
my ($cond, $resp) = split ":_:", $resource;
|
||||
if ($cre{$resource}{'ActiveFlag'} == 1)
|
||||
{
|
||||
NodeUtils->runcmd("/usr/bin/startcondresp $cond $resp");
|
||||
runcmd("/usr/bin/startcondresp $cond $resp");
|
||||
if ($cre{$resource}{'Locked'} == 1)
|
||||
{
|
||||
NodeUtils->runcmd( "/usr/bin/startcondresp -L $cond $resp");
|
||||
runcmd( "/usr/bin/startcondresp -L $cond $resp");
|
||||
}
|
||||
}
|
||||
else
|
||||
{ #not active
|
||||
NodeUtils->runcmd("/usr/bin/mkcondresp $cond $resp");
|
||||
runcmd("/usr/bin/mkcondresp $cond $resp");
|
||||
#no need to lock stopped associations
|
||||
}
|
||||
}
|
||||
@ -345,7 +607,7 @@ sub changeResources
|
||||
foreach my $attr (keys %{$cha{$resource}})
|
||||
{
|
||||
my $value = $cha{$resource}{$attr};
|
||||
$string .= "${attr}::" . NodeUtils->quote($value) . "::";
|
||||
$string .= "${attr}::" . quote($value) . "::";
|
||||
}
|
||||
}
|
||||
if (@unlock)
|
||||
@ -362,10 +624,10 @@ sub changeResources
|
||||
# here
|
||||
|
||||
if ($ustring =~ m/\w+/) {
|
||||
NodeUtils->runrmccmd("chrsrc-api", "", $ustring, undef, \@unlock);
|
||||
runrmccmd("chrsrc-api", "", $ustring, undef, \@unlock);
|
||||
}
|
||||
if ($string =~ m/\w+/) {
|
||||
NodeUtils->runrmccmd("chrsrc-api", "", $string, undef, \@unlock);
|
||||
runrmccmd("chrsrc-api", "", $string, undef, \@unlock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,7 +645,7 @@ sub writeAllFiles
|
||||
print "classes=@classes, basedir=$basedir";
|
||||
foreach my $class (@classes)
|
||||
{
|
||||
my $output = NodeUtils->runrmccmd("lsrsrc-api", "-i", "-s ${class}::::Name");
|
||||
my $output = runrmccmd("lsrsrc-api", "-i", "-s ${class}::::Name");
|
||||
foreach my $line (@$output)
|
||||
{
|
||||
&writeFile("${class}::$line", $basedir);
|
||||
@ -418,13 +680,13 @@ sub writeFile
|
||||
my $file = "$basedir/$class/$resourcefilename.pm";
|
||||
my $where = qq/"Name IN ('XXX')"/;
|
||||
my $string = " -s ${class}::${where}::*p0x0002";
|
||||
my $output = NodeUtils->runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
||||
my $output = runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
||||
$string, undef, $resource);
|
||||
$string = " -s ${class}::${where}::*p0x0008";
|
||||
my $optional = NodeUtils->runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
||||
my $optional = runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
||||
$string, undef, $resource);
|
||||
|
||||
#my @output = NodeUtils->runcmd("/usr/bin/lsrsrc -s $where $class");
|
||||
#my @output = runcmd("/usr/bin/lsrsrc -s $where $class");
|
||||
#uses lsrsrc instead of lsrsrc-api because format is almost right (just needs a few mods)
|
||||
|
||||
my $fh;
|
||||
@ -530,7 +792,7 @@ if (
|
||||
}
|
||||
|
||||
if ($::HELP) { &usage; exit; }
|
||||
if (NodeUtils->isHMC() && ($ENV{'DC_ENVIRONMENT'} ne 1))
|
||||
if (isHMC() && ($ENV{'DC_ENVIRONMENT'} ne 1))
|
||||
{
|
||||
print "mkresources is not supported on HMC.\n";
|
||||
}
|
||||
|
@ -9,11 +9,11 @@
|
||||
checks for errors.
|
||||
=cut
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl/xCAT_monitoring/rmc";
|
||||
|
||||
use strict;
|
||||
use locale;
|
||||
@ -21,7 +21,174 @@ use locale;
|
||||
use Getopt::Std;
|
||||
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
|
||||
use IPC::Msg;
|
||||
use NodeUtils;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
if this function is used in a scalar context, the output is joined into a single string
|
||||
with the newlines separating the lines.
|
||||
Arguments:
|
||||
command, exitcode and reference to output
|
||||
Returns:
|
||||
see below
|
||||
Error:
|
||||
Normally, if there is an error running the cmd, it will display the error msg
|
||||
and exit with the cmds exit code, unless exitcode is given one of the
|
||||
following values:
|
||||
0: display error msg, DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-1: DO NOT display error msg and DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-2: DO the default behavior (display error msg and exit with cmds
|
||||
exit code.
|
||||
number > 0: Display error msg and exit with the given code
|
||||
Example:
|
||||
my $outref = runcmd($cmd, -2, 1);
|
||||
Comments:
|
||||
If refoutput is true, then the output will be returned as a reference to
|
||||
an array for efficiency.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
{
|
||||
$::RUNCMD_RC = $? >> 8;
|
||||
my $displayerror = 1;
|
||||
my $rc;
|
||||
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
|
||||
{
|
||||
if ($exitcode > 0)
|
||||
{
|
||||
$rc = $exitcode;
|
||||
} # if not zero, exit with specified code
|
||||
elsif ($exitcode <= 0)
|
||||
{
|
||||
$rc = ''; # if zero or negative, do not exit
|
||||
if ($exitcode < 0) { $displayerror = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rc = $::RUNCMD_RC;
|
||||
} # if exitcode not specified, use cmd exit code
|
||||
if ($displayerror)
|
||||
{
|
||||
my $errmsg = '';
|
||||
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
|
||||
{
|
||||
$errmsg = "Segmentation fault $errmsg";
|
||||
}
|
||||
else
|
||||
{
|
||||
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
$errmsg = join('', @$outref);
|
||||
chomp $errmsg;
|
||||
}
|
||||
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
|
||||
}
|
||||
}
|
||||
if ($refoutput)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return $outref;
|
||||
}
|
||||
elsif (wantarray)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $line = join('', @$outref);
|
||||
chomp $line;
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 filterRmcApiOutput
|
||||
filter RMC Api Output
|
||||
Arguments:
|
||||
RMC command
|
||||
Output reference
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
Comments:
|
||||
The error msgs from the RPM -api cmds are pretty messy.
|
||||
This routine cleans them up a little bit.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
# Figure out the output delimiter
|
||||
my ($d) = $cmd =~ / -D\s+(\S+)/;
|
||||
if (length($d)) {
|
||||
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
|
||||
# escape any chars perl pattern matching would intepret as special chars
|
||||
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d = '::';
|
||||
} # this is the default output delimiter for the -api cmds
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 touchFile
|
||||
Arguments: $filename, $donotExit
|
||||
Returns: non zero return code indicates error
|
||||
Example: touchFile("/var/opt/xcat/touch");
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub touchFile
|
||||
{
|
||||
my ($filename, $donotExit) = @_;
|
||||
my $fh;
|
||||
my $rc = 0;
|
||||
if (!-e $filename) {
|
||||
#if the file doesn't exist we need to open and close it
|
||||
open($fh, ">>$filename") or $rc++;
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
close($fh) or $rc++;
|
||||
}
|
||||
else {
|
||||
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
|
||||
my $now = time;
|
||||
utime($now, $now, $filename);
|
||||
}
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#do nothing on Linux when stopping.
|
||||
if (($ENV{'SENSOR_MonitorStatus'} eq '2') && ($^O =~ /^linux/i)) {
|
||||
@ -48,7 +215,7 @@ if (!-d $vardir) { mkdir($vardir); }
|
||||
|
||||
sub isRMrunning{
|
||||
my $resMan = $_[0];
|
||||
my @output = NodeUtils->runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
|
||||
my @output = runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
|
||||
if ($::RUNCMD_RC) { return 0; } # maybe we should try to catch real errors here
|
||||
my ($subsys, $group, $pid, $status) = split(' ', $output[1]);
|
||||
if (defined($status) && $status eq 'active') {
|
||||
@ -61,16 +228,16 @@ sub isRMrunning{
|
||||
if (!-e $runfile){
|
||||
#first time
|
||||
if ($^O =~ /^linux/i) {
|
||||
NodeUtils->runcmd("grep $dirname $syslogconf", -1);
|
||||
runcmd("grep $dirname $syslogconf", -1);
|
||||
if ($::RUNCMD_RC == 1) { #grep did not find dirname
|
||||
#update syslog.conf
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
NodeUtils->runcmd("/usr/bin/mkfifo $fifo");
|
||||
NodeUtils->runcmd("echo \"$embedinfo\" >> $syslogconf");
|
||||
runcmd("/usr/bin/mkfifo $fifo");
|
||||
runcmd("echo \"$embedinfo\" >> $syslogconf");
|
||||
my $cmd = service("syslog", "restart");
|
||||
NodeUtils->runcmd($cmd);
|
||||
runcmd($cmd);
|
||||
}
|
||||
NodeUtils->touchFile($runfile);
|
||||
touchFile($runfile);
|
||||
}
|
||||
elsif ($^O =~ /^aix/i) {
|
||||
open(ODM, ">$odmstanza") or die $!;
|
||||
@ -79,11 +246,11 @@ errnotify:
|
||||
en_pid = 0
|
||||
en_name = "xcat_rmc_errlog_sensor"
|
||||
en_persistenceflg = 1
|
||||
en_method = "' . "$::XCATROOT/lib/perl/xCAT_monitoring/rmc/errmsgque" . ' sequence = $1 error_id = $2 class = $3 type = $4 alert_flags = $5 res_name = $6 res_type = $7 res_class = $8 label = $9"
|
||||
en_method = "' . "$::XCATROOT/sbin/rmcmon/errmsgque" . ' sequence = $1 error_id = $2 class = $3 type = $4 alert_flags = $5 res_name = $6 res_type = $7 res_class = $8 label = $9"
|
||||
';
|
||||
close ODM or die $!;
|
||||
NodeUtils->runcmd("/usr/bin/odmadd $odmstanza");
|
||||
NodeUtils->touchFile($runfile);
|
||||
runcmd("/usr/bin/odmadd $odmstanza");
|
||||
touchFile($runfile);
|
||||
}
|
||||
else {
|
||||
print "unknown platform\n";
|
||||
@ -117,7 +284,7 @@ if ($^O =~ /^linux/i) {
|
||||
chomp($line);
|
||||
|
||||
#print "String=\"$line\"\n";
|
||||
NodeUtils->runcmd(
|
||||
runcmd(
|
||||
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$line\' 1>/dev/null 2>/dev/null\" | at now",0);
|
||||
}
|
||||
close PIPE;
|
||||
@ -129,7 +296,7 @@ elsif ($^O =~ /^aix/i) {
|
||||
# set $ENV{'SENSOR_MonitorStatus'} to 2
|
||||
# should not do clean up when IBM.SensorRM is stopped
|
||||
if (&isRMrunning("IBM.SensorRM")) {
|
||||
NodeUtils->runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_rmc_errlog_sens\"", -1);
|
||||
runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_rmc_errlog_sens\"", -1);
|
||||
if (-e $runfile) {
|
||||
unlink($runfile);
|
||||
}
|
||||
@ -149,7 +316,7 @@ elsif ($^O =~ /^aix/i) {
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
NodeUtils->runcmd(
|
||||
runcmd(
|
||||
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$buf\' 1>/dev/null 2>/dev/null\" | at now", 0);
|
||||
}
|
||||
|
||||
@ -172,10 +339,10 @@ sub verify_atd
|
||||
{
|
||||
my $cmd;
|
||||
$cmd = service("atd", "status");
|
||||
NodeUtils->runcmd($cmd, -1);
|
||||
runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC) {
|
||||
$cmd = service("atd", "start");
|
||||
NodeUtils->runcmd($cmd, -1);
|
||||
runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC) {
|
||||
print "Warning: atd has failed to start!\n";
|
||||
}
|
||||
@ -209,7 +376,7 @@ sub service
|
||||
my $SVCDIR = "/etc/init.d";
|
||||
|
||||
# On SLES, nfs server script is "nfsserver".
|
||||
if (((-e "/etc/SuSE-release") || NodeUtils->isHMC()) && $service eq "nfs") {
|
||||
if (((-e "/etc/SuSE-release") || isHMC()) && $service eq "nfs") {
|
||||
$service = "nfsserver";
|
||||
}
|
||||
if (-f $SVCCLI) {
|
||||
@ -221,6 +388,13 @@ sub service
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
sub isHMC
|
||||
{
|
||||
my $hmcfile = "/opt/hsc/data/hmcType.properties";
|
||||
if (-e $hmcfile) { return 1; }
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
@ -14,6 +14,9 @@ BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
|
||||
BuildArch: noarch
|
||||
%endif
|
||||
|
||||
Requires: perl-xCAT = %{version}
|
||||
Requires: xCAT-server = %{version}
|
||||
|
||||
Provides: xCAT-rmc = %{version}
|
||||
|
||||
%description
|
||||
|
@ -14,6 +14,7 @@ use xCAT::MsgUtils;
|
||||
use xCAT::Utils;
|
||||
use xCAT::Client;
|
||||
use xCAT_plugin::notification;
|
||||
use xCAT_monitoring::montbhandler;
|
||||
|
||||
#the list store 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.
|
||||
@ -72,6 +73,9 @@ sub start {
|
||||
#setup signal
|
||||
$SIG{USR2}=\&handleMonSignal;
|
||||
|
||||
xCAT_monitoring::montbhandler->regMonitoringNotif();
|
||||
|
||||
|
||||
#start monitoring for all the registered plug-ins in the monitoring table.
|
||||
#better span a process so that it will not block the xcatd.
|
||||
my $pid;
|
||||
@ -92,20 +96,12 @@ sub start {
|
||||
print "$_: @$retstat\n";
|
||||
}
|
||||
}
|
||||
|
||||
#register for nodelist table changes if not already registered
|
||||
my $tab = xCAT::Table->new('notification');
|
||||
my $regged=0;
|
||||
if ($tab) {
|
||||
(my $ref) = $tab->getAttribs({filename => qw(monitorctrl.pm)}, tables);
|
||||
if ($ref and $ref->{tables}) {
|
||||
$regged=1;
|
||||
}
|
||||
$tab->close();
|
||||
|
||||
if (keys(%PRODUCT_LIST) > 0) {
|
||||
regNodelistNotif();
|
||||
}
|
||||
|
||||
if (!$regged) {
|
||||
xCAT_plugin::notification::regNotification([qw(monitorctrl.pm nodelist,monitoring -o a,u,d)]);
|
||||
else {
|
||||
unregNodelistNotif();
|
||||
}
|
||||
|
||||
#print "child done\n";
|
||||
@ -113,6 +109,62 @@ sub start {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 regNodelistNotif
|
||||
It registers this module in the notification table to watch for changes in
|
||||
the nodelist table.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
0 for successful.
|
||||
non-0 for not successful.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub regNodelistNotif {
|
||||
|
||||
#register for nodelist table changes if not already registered
|
||||
my $tab = xCAT::Table->new('notification');
|
||||
my $regged=0;
|
||||
if ($tab) {
|
||||
(my $ref) = $tab->getAttribs({filename => qw(monitorctrl.pm)}, tables);
|
||||
if ($ref and $ref->{tables}) {
|
||||
$regged=1;
|
||||
}
|
||||
$tab->close();
|
||||
}
|
||||
|
||||
if (!$regged) {
|
||||
xCAT_plugin::notification::regNotification([qw(monitorctrl.pm nodelist -o a,d)]);
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 unregNodelistNotif
|
||||
It un-registers this module in the notification table.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
0 for successful.
|
||||
non-0 for not successful.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub unregNodelistNotif {
|
||||
my $tab = xCAT::Table->new('notification');
|
||||
my $regged=0;
|
||||
if ($tab) {
|
||||
(my $ref) = $tab->getAttribs({filename => qw(monitorctrl.pm)}, tables);
|
||||
if ($ref and $ref->{tables}) {
|
||||
$regged=1;
|
||||
}
|
||||
$tab->close();
|
||||
}
|
||||
|
||||
if ($regged) {
|
||||
xCAT_plugin::notification::unregNotification([qw(monitorctrl.pm)]);
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 handleSignal
|
||||
@ -172,6 +224,16 @@ sub handleMonSignal {
|
||||
}
|
||||
}
|
||||
|
||||
#registers or unregusters this module in the notification table for changes in
|
||||
# the nodelist and monitoring tables.
|
||||
if (keys(%PRODUCT_LIST) > 0) {
|
||||
regNodelistNotif();
|
||||
}
|
||||
else {
|
||||
unregNodelistNotif();
|
||||
}
|
||||
|
||||
|
||||
#setup the signal again
|
||||
$SIG{USR2}=\&handleMonSignal;
|
||||
|
||||
@ -230,7 +292,8 @@ sub stop {
|
||||
$ret{"Stop node status monitoring with $NODESTAT_MON_NAME"}=\@ret2;
|
||||
}
|
||||
|
||||
xCAT_plugin::notification::unregNotification([qw(monitorctrl.pm)]);
|
||||
xCAT_monitoring::montbhandler->unregMonitoringNotif();
|
||||
unregNodelistNotif();
|
||||
|
||||
if (%ret) {
|
||||
foreach(keys(%ret)) {
|
||||
@ -309,7 +372,7 @@ sub startMonitoring {
|
||||
#--------------------------------------------------------------------------------
|
||||
sub startNodeStatusMonitoring {
|
||||
my $pname=shift;
|
||||
if ($pname =~ /xCAT_plugin::monitorctrl/) {
|
||||
if ($pname =~ /xCAT_monitoring::monitorctrl/) {
|
||||
$pname=shift;
|
||||
}
|
||||
|
||||
@ -413,7 +476,7 @@ sub stopMonitoring {
|
||||
#--------------------------------------------------------------------------------
|
||||
sub stopNodeStatusMonitoring {
|
||||
my $pname=shift;
|
||||
if ($pname =~ /xCAT_plugin::monitorctrl/) {
|
||||
if ($pname =~ /xCAT_monitoring::monitorctrl/) {
|
||||
$pname=shift;
|
||||
}
|
||||
|
||||
@ -472,18 +535,15 @@ sub stopNodeStatusMonitoring {
|
||||
#--------------------------------------------------------------------------------
|
||||
sub processTableChanges {
|
||||
my $action=shift;
|
||||
if ($action =~ /xCAT_plugin::monitorctrl/) {
|
||||
if ($action =~ /xCAT_monitoring::monitorctrl/) {
|
||||
$action=shift;
|
||||
}
|
||||
my $tablename=shift;
|
||||
my $old_data=shift;
|
||||
my $new_data=shift;
|
||||
|
||||
if ($tablename eq "nodelist") {
|
||||
processNodelistTableChanges($action, $tablename, $old_data, $new_data);
|
||||
} else {
|
||||
processMonitoringTableChanges($action, $tablename, $old_data, $new_data);
|
||||
}
|
||||
processNodelistTableChanges($action, $tablename, $old_data, $new_data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -501,7 +561,7 @@ sub processTableChanges {
|
||||
#--------------------------------------------------------------------------------
|
||||
sub processNodelistTableChanges {
|
||||
my $action=shift;
|
||||
if ($action =~ /xCAT_plugin::monitorctrl/) {
|
||||
if ($action =~ /xCAT_monitoring::monitorctrl/) {
|
||||
$action=shift;
|
||||
}
|
||||
#print "monitorctrl::processNodelistTableChanges action=$action\n";
|
||||
@ -530,10 +590,10 @@ sub processNodelistTableChanges {
|
||||
if ($action eq "a") {
|
||||
if ($new_data) {
|
||||
my $nodetype='';
|
||||
my $groups='';
|
||||
my $status='';
|
||||
if (exists($new_data->{nodetype})) {$nodetype=$new_data->{nodetype};}
|
||||
if (exists($new_data->{groups})) {$groups=$new_data->{groups};}
|
||||
push(@nodenames, [$new_data->{node}, $nodetype, $groups]);
|
||||
if (exists($new_data->{status})) {$status=$new_data->{status};}
|
||||
push(@nodenames, [$new_data->{node}, $nodetype, $status]);
|
||||
my $hierarchy=getMonServerWithInfo(\@nodenames);
|
||||
|
||||
#call each plug-in to add the nodes into the monitoring domain
|
||||
@ -551,19 +611,19 @@ sub processNodelistTableChanges {
|
||||
$colnames=$old_data->[0];
|
||||
my $node_i=-1;
|
||||
my $nodetype_i=-1;
|
||||
my $groups_i=-1;
|
||||
my $status_i=-1;
|
||||
for ($i=0; $i<@$colnames; ++$i) {
|
||||
if ($colnames->[$i] eq "node") {
|
||||
$node_i=$i;
|
||||
} elsif ($colnames->[$i] eq "nodetype") {
|
||||
$nodetype_i=$i;
|
||||
} elsif ($colnames->[$i] eq "groups") {
|
||||
$groups_i=$i;
|
||||
} elsif ($colnames->[$i] eq "status") {
|
||||
$status_i=$i;
|
||||
}
|
||||
}
|
||||
|
||||
for (my $j=1; $j<@$old_data; ++$j) {
|
||||
push(@nodenames, [$old_data->[$j]->[$node_i], $old_data->[$j]->[$nodetype_i], $old_data->[$j]->[$groups_i]]);
|
||||
push(@nodenames, [$old_data->[$j]->[$node_i], $old_data->[$j]->[$nodetype_i], $old_data->[$j]->[$status_i]]);
|
||||
}
|
||||
|
||||
if (@nodenames > 0) {
|
||||
@ -608,9 +668,8 @@ sub processMonitoringTableChanges {
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 processNodeStatusChanges
|
||||
This is the callback routine passed as a parameter to the startNodeStatusMon()
|
||||
function of the monitoring plug-ins. This routine will be called by a
|
||||
selected monitoring plug-in module to feed the node status back to xcat.
|
||||
This routine will be called by
|
||||
monitoring plug-in modules to feed the node status back to xcat.
|
||||
(callback mode). This function will update the status column of the
|
||||
nodelist table with the new node status.
|
||||
Arguments:
|
||||
@ -625,7 +684,7 @@ sub processMonitoringTableChanges {
|
||||
sub processNodeStatusChanges {
|
||||
#print "monitorctrl::processNodeStatusChanges called\n";
|
||||
my $temp=shift;
|
||||
if ($temp =~ /xCAT_plugin::monitorctrl/) {
|
||||
if ($temp =~ /xCAT_monitoring::monitorctrl/) {
|
||||
$temp=shift;
|
||||
}
|
||||
|
||||
@ -753,13 +812,13 @@ sub refreshProductList {
|
||||
=head3 getMonHierarchy
|
||||
It gets the monnitoring server node for all the nodes within nodelist table.
|
||||
The "monserver" attribute is used from the noderes table. If "monserver" is not defined
|
||||
for a node, "xcatmaster" is used. If none is defined, use the local host.
|
||||
for a node, "servicenode" is used. If none is defined, use the local host.
|
||||
Arguments:
|
||||
None.
|
||||
Returns:
|
||||
A hash reference keyed by the monitoring server nodes and each value is a ref to
|
||||
an array of [nodes, nodetype] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
an array of [nodes, nodetype, status] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getMonHierarchy {
|
||||
@ -767,53 +826,33 @@ sub getMonHierarchy {
|
||||
|
||||
#get all from nodelist table and noderes table
|
||||
my $table=xCAT::Table->new("nodelist", -create =>0);
|
||||
my @tmp1=$table->getAllAttribs(('node','nodetype', 'groups'));
|
||||
my @tmp1=$table->getAllAttribs(('node','nodetype', 'status'));
|
||||
|
||||
my $table2=xCAT::Table->new("noderes", -create =>0);
|
||||
my @tmp2=$table2->getAllAttribs(('node','monserver', 'xcatmaster'));
|
||||
|
||||
#get monserver for each node. use "monserver" attribute from noderes table, if not
|
||||
#defined, use "xcatmaster". otherwise, use loca lhost.
|
||||
#defined, use "servicenode". otherwise, use loca lhost.
|
||||
my $host=hostname();
|
||||
if (defined(@tmp1) && (@tmp1 > 0)) {
|
||||
if (defined(@tmp2) && (@tmp2 > 0)) {
|
||||
foreach(@tmp1) {
|
||||
my $node=$_->{node};
|
||||
my $groups=$_->{groups};
|
||||
my $nodetype=$_->{nodetype};
|
||||
my @group_array=();
|
||||
if ($groups) {
|
||||
@group_array=split(/,/, $groups);
|
||||
}
|
||||
my $monserver=$host;
|
||||
foreach(@tmp2) {
|
||||
my $node2=$_->{node};
|
||||
if (($node2 eq $node) || (grep {$_ eq $node2} @group_array)) {
|
||||
if ($_->{monserver}) {
|
||||
$monserver=$_->{monserver};
|
||||
}
|
||||
elsif ($_->{xcatmaster}) {
|
||||
$monserver=$_->{xcatmaster};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exists($ret->{$monserver})) {
|
||||
my $pa=$ret->{$monserver};
|
||||
push(@$pa, [$node, $nodetype]);
|
||||
}
|
||||
else {
|
||||
$ret->{$monserver}=[[$node, $nodetype]];
|
||||
}
|
||||
foreach(@tmp1) {
|
||||
my $node=$_->{node};
|
||||
my $status=$_->{status};
|
||||
my $nodetype=$_->{nodetype};
|
||||
my $monserver=$host;
|
||||
my $tmp2=$table2->getNodeAttribs($node, ['monserver', 'servicenode']);
|
||||
if (defined($tmp2) && ($tmp2)) {
|
||||
if ($tmp2->{monserver}) { $monserver=$tmp2->{monserver}; }
|
||||
elsif ($tmp2->{servicenode}) { $monserver=$tmp2->{servicenode}; }
|
||||
}
|
||||
|
||||
if (exists($ret->{$monserver})) {
|
||||
my $pa=$ret->{$monserver};
|
||||
push(@$pa, [$node, $nodetype, $status]);
|
||||
}
|
||||
else {
|
||||
$ret->{$monserver}=[[$node, $nodetype, $status]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
#no entried in noderes table, use local host as the monserver for all the nodes
|
||||
my $nodes=[];
|
||||
foreach(@tmp1) {
|
||||
push(@$nodes, [$_->{node}, $nodetype]);
|
||||
}
|
||||
$ret->{$host}=$nodes;
|
||||
}
|
||||
}
|
||||
$table->close();
|
||||
$table2->close();
|
||||
@ -824,17 +863,17 @@ sub getMonHierarchy {
|
||||
=head3 getMonServerWithInfo
|
||||
It gets the monnitoring server node for each of the nodes from the input.
|
||||
The "monserver" attribute is used from the noderes table. If "monserver" is not defined
|
||||
for a node, "xcatmaster" is used. If none is defined, use the local host as the
|
||||
for a node, "servicenode" is used. If none is defined, use the local host as the
|
||||
the monitoring server. The difference of this function from the getMonServer function
|
||||
is that the input of the nodes have 'node', 'nodetype' and 'groups' info.
|
||||
is that the input of the nodes have 'node', 'nodetype' and 'status' info.
|
||||
The other one just has 'node'. The
|
||||
names.
|
||||
Arguments:
|
||||
nodes: An array ref. Each element is of the format: [node, nodetype, groups]
|
||||
nodes: An array ref. Each element is of the format: [node, nodetype, status]
|
||||
Returns:
|
||||
A hash reference keyed by the monitoring server nodes and each value is a ref to
|
||||
an array of [nodes, nodetype] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
an array of [nodes, nodetype, status] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getMonServerWithInfo {
|
||||
@ -846,32 +885,21 @@ sub getMonServerWithInfo {
|
||||
#print "getMonServerWithInfo called with @in_nodes\n";
|
||||
#get all from the noderes table
|
||||
my $table2=xCAT::Table->new("noderes", -create =>0);
|
||||
my @tmp2=$table2->getAllAttribs(('node','monserver', 'xcatmaster'));
|
||||
my $host=hostname();
|
||||
|
||||
foreach (@in_nodes) {
|
||||
my $node=$_->[0];
|
||||
my $nodetype=$_->[1];
|
||||
my $groups=$_->[2];
|
||||
my @group_array=();
|
||||
if ($groups) {
|
||||
@group_array=split(/,/, $groups);
|
||||
}
|
||||
my $status=$_->[2];
|
||||
|
||||
my $monserver=$host;
|
||||
if (defined(@tmp2) && (@tmp2 > 0)) {
|
||||
foreach(@tmp2) {
|
||||
my $node2=$_->{node};
|
||||
if (($node2 eq $node) || (grep {$_ eq $node2} @group_array)) {
|
||||
if ($_->{monserver}) {
|
||||
$monserver=$_->{monserver};
|
||||
}
|
||||
elsif ($_->{xcatmaster}) {
|
||||
$monserver=$_->{xcatmaster};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my $tmp2=$table2->getNodeAttribs($node, ['monserver', 'servicenode']);
|
||||
if (defined($tmp2) && ($tmp2)) {
|
||||
if ($tmp2->{monserver}) { $monserver=$tmp2->{monserver}; }
|
||||
elsif ($tmp2->{servicenode}) { $monserver=$tmp2->{servicenode}; }
|
||||
}
|
||||
|
||||
|
||||
if (exists($ret->{$monserver})) {
|
||||
my $pa=$ret->{$monserver};
|
||||
push(@$pa, [$node, $nodetype]);
|
||||
@ -890,14 +918,14 @@ sub getMonServerWithInfo {
|
||||
=head3 getMonServer
|
||||
It gets the monnitoring server node for each of the nodes from the input.
|
||||
The "monserver" attribute is used from the noderes table. If "monserver" is not defined
|
||||
for a node, "xcatmaster" is used. If none is defined, use the local host as the
|
||||
for a node, "servicenode" is used. If none is defined, use the local host as the
|
||||
the monitoring server.
|
||||
Arguments:
|
||||
nodes: An array ref of nodes.
|
||||
Returns:
|
||||
A hash reference keyed by the monitoring server nodes and each value is a ref to
|
||||
an array of [nodes, nodetype] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
an array of [nodes, nodetype, status] arrays monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi', active'], ['node2', 'switch', booting']...], ...}
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getMonServer {
|
||||
@ -908,42 +936,29 @@ sub getMonServer {
|
||||
#get all from nodelist table and noderes table
|
||||
my $table=xCAT::Table->new("nodelist", -create =>0);
|
||||
my $table2=xCAT::Table->new("noderes", -create =>0);
|
||||
my @tmp2=$table2->getAllAttribs(('node','monserver', 'xcatmaster'));
|
||||
my $host=hostname();
|
||||
|
||||
foreach (@in_nodes) {
|
||||
my @tmp1=$table->getAttribs({'node'=>$_}, ('node', 'nodetype', 'groups'));
|
||||
my @tmp1=$table->getAttribs({'node'=>$_}, ('node', 'nodetype', 'status'));
|
||||
|
||||
if (defined(@tmp1) && (@tmp1 > 0)) {
|
||||
my $node=$_;
|
||||
my $groups=$tmp1[0]->{groups};
|
||||
my $status=$tmp1[0]->{status};
|
||||
my $nodetype=$tmp1[0]->{nodetype};
|
||||
my @group_array=();
|
||||
if ($groups) {
|
||||
@group_array=split(/,/, $groups);
|
||||
}
|
||||
|
||||
my $monserver=$host;
|
||||
if (defined(@tmp2) && (@tmp2 > 0)) {
|
||||
foreach(@tmp2) {
|
||||
my $node2=$_->{node};
|
||||
if (($node2 eq $node) || (grep {$_ eq $node2} @group_array)) {
|
||||
if ($_->{monserver}) {
|
||||
$monserver=$_->{monserver};
|
||||
}
|
||||
elsif ($_->{xcatmaster}) {
|
||||
$monserver=$_->{xcatmaster};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my $tmp2=$table2->getNodeAttribs($node, ['monserver', 'servicenode']);
|
||||
if (defined($tmp2) && ($tmp2)) {
|
||||
if ($tmp2->{monserver}) { $monserver=$tmp2->{monserver}; }
|
||||
elsif ($tmp2->{servicenode}) { $monserver=$tmp2->{servicenode}; }
|
||||
}
|
||||
|
||||
if (exists($ret->{$monserver})) {
|
||||
my $pa=$ret->{$monserver};
|
||||
push(@$pa, [$node, $nodetype]);
|
||||
push(@$pa, [$node, $nodetype, $status]);
|
||||
}
|
||||
else {
|
||||
$ret->{$monserver}=[ [$node,$nodetype] ];
|
||||
$ret->{$monserver}=[ [$node,$nodetype, $status] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
124
xCAT-server-2.0/lib/xcat/monitoring/montbhandler.pm
Normal file
124
xCAT-server-2.0/lib/xcat/monitoring/montbhandler.pm
Normal file
@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_monitoring::montbhandler;
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
|
||||
use xCAT::Table;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::Utils;
|
||||
use xCAT_plugin::notification;
|
||||
use xCAT_monitoring::monitorctrl;
|
||||
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head1 xCAT_monitoring:montbhandler
|
||||
=head2 Package Description
|
||||
xCAT monitoring table handler module. This is a helper module for monitorctrl module
|
||||
becuase the notification infrastructure does not allow a module to register more
|
||||
than one callbacks. This module registers and unregisters notification to watch for
|
||||
the changes in the monitoring tables. When changes occurrs, it forward the info
|
||||
back to monitorctrl module for handling.
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 regMonitoringNotif
|
||||
It registers this module in the notification table to watch for changes in
|
||||
the monitoring table.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
0 for successful.
|
||||
non-0 for not successful.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub regMonitoringNotif {
|
||||
|
||||
#register for nodelist table changes if not already registered
|
||||
my $tab = xCAT::Table->new('notification');
|
||||
my $regged=0;
|
||||
if ($tab) {
|
||||
(my $ref) = $tab->getAttribs({filename => qw(montbhandler.pm)}, tables);
|
||||
if ($ref and $ref->{tables}) {
|
||||
$regged=1;
|
||||
}
|
||||
$tab->close();
|
||||
}
|
||||
|
||||
if (!$regged) {
|
||||
xCAT_plugin::notification::regNotification([qw(montbhandler.pm monitoring -o a,u,d)]);
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 unregMonitoringNotif
|
||||
It un-registers this module in the notification table.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
0 for successful.
|
||||
non-0 for not successful.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub unregMonitoringNotif {
|
||||
my $tab = xCAT::Table->new('notification');
|
||||
my $regged=0;
|
||||
if ($tab) {
|
||||
(my $ref) = $tab->getAttribs({filename => qw(montbhandler.pm)}, tables);
|
||||
if ($ref and $ref->{tables}) {
|
||||
$regged=1;
|
||||
}
|
||||
$tab->close();
|
||||
}
|
||||
|
||||
if ($regged) {
|
||||
xCAT_plugin::notification::unregNotification([qw(montbhandler.pm)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 processTableChanges
|
||||
It is called by the NotifHander module
|
||||
when the monitoring tables get changed. If a plug-in
|
||||
is added or removed from the monitoring table. this function will start
|
||||
or stop the plug-in for monitoing the xCAT cluster.
|
||||
Arguments:
|
||||
action - table action. It can be d for rows deleted, a for rows added
|
||||
or u for rows updated.
|
||||
tablename - string. The name of the DB table whose data has been changed.
|
||||
old_data - an array reference of the old row data that has been changed.
|
||||
The first element is an array reference that contains the column names.
|
||||
The rest of the elelments are also array references each contains
|
||||
attribute values of a row.
|
||||
It is set when the action is u or d.
|
||||
new_data - a hash refernce of new row data; only changed values are present
|
||||
in the hash. It is keyed by column names.
|
||||
It is set when the action is u or a.
|
||||
Returns:
|
||||
0 for successful.
|
||||
non-0 for not successful.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub processTableChanges {
|
||||
my $action=shift;
|
||||
if ($action =~ /xCAT_plugin::montbhandler/) {
|
||||
$action=shift;
|
||||
}
|
||||
my $tablename=shift;
|
||||
my $old_data=shift;
|
||||
my $new_data=shift;
|
||||
|
||||
|
||||
xCAT_monitoring::monitorctrl->processMonitoringTableChanges($action, $tablename, $old_data, $new_data);
|
||||
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ package xCAT_monitoring::templatemon;
|
||||
in the xCAT cluster.
|
||||
Arguments:
|
||||
monservers --A hash reference keyed by the monitoring server nodes
|
||||
and each value is a ref to an array of [nodes, nodetype] arrays
|
||||
and each value is a ref to an array of [nodes, nodetype, status] arrays
|
||||
monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
Returns:
|
||||
(return code, message)
|
||||
=cut
|
||||
@ -52,8 +52,8 @@ sub start {
|
||||
print " monitoring server: $_\n";
|
||||
my $mon_nodes=$monservers->{$_};
|
||||
foreach(@$mon_nodes) {
|
||||
$node_pair=$_;
|
||||
print " node=$node_pair->[0], nodetype=$node_pair->[1]\n";
|
||||
my $node_info=$_;
|
||||
print " node=$node_info->[0], nodetype=$node_info->[1], status=$node_info->[2]\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,9 +111,9 @@ sub supportNodeStatusMon {
|
||||
to xCAT.
|
||||
Arguments:
|
||||
monservers --A hash reference keyed by the monitoring server nodes
|
||||
and each value is a ref to an array of [nodes, nodetype] arrays
|
||||
and each value is a ref to an array of [nodes, nodetype, status] arrays
|
||||
monitored by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
Returns:
|
||||
(return code, message)
|
||||
|
||||
@ -131,8 +131,8 @@ sub startNodeStatusMon {
|
||||
print " monitoring server: $_\n";
|
||||
my $mon_nodes=$monservers->{$_};
|
||||
foreach(@$mon_nodes) {
|
||||
$node_pair=$_;
|
||||
print " node=$node_pair->[0], nodetype=$node_pair->[1]\n";
|
||||
my $node_info=$_;
|
||||
print " node=$node_info->[0], nodetype=$node_info->[1], status=$node_info->[2]\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,9 +164,9 @@ sub stopNodeStatusMon {
|
||||
to the xCAT cluster. It should add the nodes into the product for monitoring.
|
||||
Arguments:
|
||||
nodes --nodes to be added. It is a hash reference keyed by the monitoring server
|
||||
nodes and each value is a ref to an array of [nodes, nodetype] arrays monitored
|
||||
nodes and each value is a ref to an array of [nodes, nodetype, status] arrays monitored
|
||||
by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'bboting']...], ...}
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
@ -182,8 +182,8 @@ sub addNodes {
|
||||
print " monitoring server: $_\n";
|
||||
my $mon_nodes=$noderef->{$_};
|
||||
foreach(@$mon_nodes) {
|
||||
$node_pair=$_;
|
||||
print " node=$node_pair->[0], nodetype=$node_pair->[1]\n";
|
||||
my $node_info=$_;
|
||||
print " node=$node_info->[0], nodetype=$node_info->[1], status=$node_info->[2]\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,9 +197,9 @@ sub addNodes {
|
||||
from the xCAT cluster. It should remove the nodes from the product for monitoring.
|
||||
Arguments:
|
||||
nodes --nodes to be removed. It is a hash reference keyed by the monitoring server
|
||||
nodes and each value is a ref to an array of [nodes, nodetype] arrays monitored
|
||||
nodes and each value is a ref to an array of [nodes, nodetype, status] arrays monitored
|
||||
by the server. So the format is:
|
||||
{monserver1=>[['node1', 'osi'], ['node2', 'switch']...], ...}
|
||||
{monserver1=>[['node1', 'osi', 'active'], ['node2', 'switch', 'booting']...], ...}
|
||||
Returns:
|
||||
none
|
||||
=cut
|
||||
@ -215,8 +215,8 @@ sub removeNodes {
|
||||
print " monitoring server: $_\n";
|
||||
my $mon_nodes=$noderef->{$_};
|
||||
foreach(@$mon_nodes) {
|
||||
$node_pair=$_;
|
||||
print " node=$node_pair->[0], nodetype=$node_pair->[1]\n";
|
||||
my $node_info=$_;
|
||||
print " node=$node_info->[0], nodetype=$node_info->[1], status=$node_info->[2]\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user