mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-04 05:12:30 +00:00 
			
		
		
		
	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:
		@@ -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";
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user