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