diff --git a/xCAT-rmc/plugin/rmcmon.pm b/xCAT-rmc/plugin/rmcmon.pm index a3fc6efc0..e8cfeb459 100644 --- a/xCAT-rmc/plugin/rmcmon.pm +++ b/xCAT-rmc/plugin/rmcmon.pm @@ -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; - } - - diff --git a/xCAT-rmc/resources/mn/IBM.Sensor/ErrorLogSensor.pm b/xCAT-rmc/resources/mn/IBM.Sensor/ErrorLogSensor.pm index 78fa9d1ab..295bef685 100644 --- a/xCAT-rmc/resources/mn/IBM.Sensor/ErrorLogSensor.pm +++ b/xCAT-rmc/resources/mn/IBM.Sensor/ErrorLogSensor.pm @@ -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), diff --git a/xCAT-rmc/resources/ms/IBM.Sensor/CFMRootModTime.pm b/xCAT-rmc/resources/ms/IBM.Sensor/CFMRootModTime.pm index 8aa141651..48dcb2d18 100644 --- a/xCAT-rmc/resources/ms/IBM.Sensor/CFMRootModTime.pm +++ b/xCAT-rmc/resources/ms/IBM.Sensor/CFMRootModTime.pm @@ -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), }; diff --git a/xCAT-rmc/scripts/perl/NodeUtils.pm b/xCAT-rmc/scripts/perl/NodeUtils.pm deleted file mode 100644 index 8b69b6a83..000000000 --- a/xCAT-rmc/scripts/perl/NodeUtils.pm +++ /dev/null @@ -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 = ; - 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; -} diff --git a/xCAT-rmc/scripts/perl/errmsgque b/xCAT-rmc/scripts/perl/errmsgque index e954544b7..adedc227f 100755 --- a/xCAT-rmc/scripts/perl/errmsgque +++ b/xCAT-rmc/scripts/perl/errmsgque @@ -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`; diff --git a/xCAT-rmc/scripts/perl/mkrmcresources b/xCAT-rmc/scripts/perl/mkrmcresources index 0cc0f1f35..8ff6a27ea 100755 --- a/xCAT-rmc/scripts/perl/mkrmcresources +++ b/xCAT-rmc/scripts/perl/mkrmcresources @@ -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"; } diff --git a/xCAT-rmc/scripts/perl/monerrorlog b/xCAT-rmc/scripts/perl/monerrorlog index aaea1dae0..ab29a2329 100755 --- a/xCAT-rmc/scripts/perl/monerrorlog +++ b/xCAT-rmc/scripts/perl/monerrorlog @@ -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; diff --git a/xCAT-rmc/xCAT-rmc.spec b/xCAT-rmc/xCAT-rmc.spec index 9f3c4549e..4fa8bc07e 100644 --- a/xCAT-rmc/xCAT-rmc.spec +++ b/xCAT-rmc/xCAT-rmc.spec @@ -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 diff --git a/xCAT-server-2.0/lib/xcat/monitoring/monitorctrl.pm b/xCAT-server-2.0/lib/xcat/monitoring/monitorctrl.pm index daf7376a4..b5d688008 100644 --- a/xCAT-server-2.0/lib/xcat/monitoring/monitorctrl.pm +++ b/xCAT-server-2.0/lib/xcat/monitoring/monitorctrl.pm @@ -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] ]; } } } diff --git a/xCAT-server-2.0/lib/xcat/monitoring/montbhandler.pm b/xCAT-server-2.0/lib/xcat/monitoring/montbhandler.pm new file mode 100644 index 000000000..ee72df016 --- /dev/null +++ b/xCAT-server-2.0/lib/xcat/monitoring/montbhandler.pm @@ -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); + +} + diff --git a/xCAT-server-2.0/lib/xcat/monitoring/samples/templatemon.pm b/xCAT-server-2.0/lib/xcat/monitoring/samples/templatemon.pm index b15d4f6eb..8aa914903 100644 --- a/xCAT-server-2.0/lib/xcat/monitoring/samples/templatemon.pm +++ b/xCAT-server-2.0/lib/xcat/monitoring/samples/templatemon.pm @@ -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"; } }