From 9621c2854c7000d152b3a772acca797b973ee152 Mon Sep 17 00:00:00 2001 From: linggao Date: Fri, 1 Aug 2008 17:35:58 +0000 Subject: [PATCH] changes in monitoring plug-in infrastructure to better fit the xCAT env git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@1978 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- .../lib/xcat/monitoring/monitorctrl.pm | 937 ++++----- .../lib/xcat/monitoring/montbhandler.pm | 4 +- xCAT-server/lib/xcat/monitoring/snmpmon.pm | 726 ++++--- xCAT-server/lib/xcat/monitoring/xcatmon.pm | 176 +- xCAT-server/lib/xcat/plugins/aixinstall.pm | 34 +- xCAT-server/lib/xcat/plugins/monctrlcmds.pm | 1782 +++++++++++------ xCAT-server/lib/xcat/plugins/pxe.pm | 9 - xCAT-server/lib/xcat/plugins/yaboot.pm | 8 - xCAT-server/sbin/xcatnodemon | 2 +- 9 files changed, 2216 insertions(+), 1462 deletions(-) diff --git a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm index d7543744b..e51906e9b 100644 --- a/xCAT-server/lib/xcat/monitoring/monitorctrl.pm +++ b/xCAT-server/lib/xcat/monitoring/monitorctrl.pm @@ -6,25 +6,25 @@ BEGIN $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; } use lib "$::XCATROOT/lib/perl"; - +use strict; use xCAT::NodeRange; use xCAT::Table; use xCAT::MsgUtils; use xCAT::Utils; -use xCAT::Client; use xCAT_plugin::notification; use xCAT_monitoring::montbhandler; - +use Sys::Hostname; #the list stores 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. #the format is: (name=>[filename, modulename], ...) -%PRODUCT_LIST; +my %PRODUCT_LIST; #stores the module name and the method that is used for the node status monitoring #for xCAT. -$NODESTAT_MON_NAME; -$masterpid; +my $NODESTAT_MON_NAME; +my $masterpid; + 1; @@ -69,12 +69,18 @@ sub start { #print "masterpid=$masterpid\n"; # get the plug-in list from the monitoring table - refreshProductList(); + #refreshProductList(); #setup signal - $SIG{USR2}=\&handleMonSignal; + #$SIG{USR2}=\&handleMonSignal; - xCAT_monitoring::montbhandler->regMonitoringNotif(); + undef $SIG{CHLD}; + my $isMN=xCAT::Utils->isMN(); + my $isMonServer=isMonServer(); + + if ($isMN) { + xCAT_monitoring::montbhandler->regMonitoringNotif(); + } #start monitoring for all the registered plug-ins in the monitoring table. @@ -85,25 +91,34 @@ sub start { return 0; } elsif (defined($pid)) { #child process - my %ret = startMonitoring(()); - if ($NODESTAT_MON_NAME) { - my @ret2 = startNodeStatusMonitoring($NODESTAT_MON_NAME); - $ret{"Node status monitoring with $NODESTAT_MON_NAME"}=\@ret2; - } - if (%ret) { - foreach(keys(%ret)) { - my $retstat=$ret{$_}; - xCAT::MsgUtils->message('S', "[mon]: $_: @$retstat\n"); - #print "$_: @$retstat\n"; - } - } + my $localhostname=hostname(); - if (! xCAT::Utils->isServiceNode()) { - if (keys(%PRODUCT_LIST) > 0) { - regNodelistNotif(); + if ($isMonServer) { #only start monitoring on monservers. + #on the service node, need to configure the local host in case it is in a process + #of diskless rebooting + if (xCAT::Utils->isServiceNode()) { + my %ret3=config([], [], 0); + if (%ret3) { + foreach(keys(%ret3)) { + my $retstat3=$ret3{$_}; + xCAT::MsgUtils->message('S', "[mon]: $_: @$retstat3 on $localhostname\n"); + #print "$_: @$retstat\n"; + } + } } - else { - unregNodelistNotif(); + + #mn and sn + my %ret = startMonitoring([], [], 0); + if ($NODESTAT_MON_NAME) { + my @ret2 = startNodeStatusMonitoring($NODESTAT_MON_NAME, [], 0); + $ret{"Node status monitoring with $NODESTAT_MON_NAME"}=\@ret2; + } + if (%ret) { + foreach(keys(%ret)) { + my $retstat=$ret{$_}; + xCAT::MsgUtils->message('S', "[mon]: $_: @$retstat on $localhostname\n"); + #print "$_: @$retstat\n"; + } } } @@ -113,58 +128,27 @@ sub start { } + #-------------------------------------------------------------------------------- -=head3 regNodelistNotif - It registers this module in the notification table to watch for changes in - the nodelist table. +=head3 stop + It is called by the xcatd when xcatd stops. It + in tern calls the stop() function of each monitoring + plug-in modules, stops all the timers for pulling the + node status and unregisters for the nodelist + tables changes. Arguments: - none + configLocal -- 1 means that only the local node get configured. Returns: 0 for successful. non-0 for not successful. =cut #-------------------------------------------------------------------------------- -sub regNodelistNotif { +sub stop { - #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)]); + if (xCAT::Utils->isMN()) { + xCAT_monitoring::montbhandler->unregMonitoringNotif(); } + return 0; } #------------------------------------------------------------------------------- @@ -180,71 +164,11 @@ sub unregNodelistNotif { =cut #------------------------------------------------------------------------------- sub handleMonSignal { - #print "monitorctrl handleMonSignal called masterpid=$masterpid\n"; - #save the old cache values - my @old_products=keys(%PRODUCT_LIST); - my $old_nodestatmon=$NODESTAT_MON_NAME; - - #print "old_products=@old_products.\n"; - #print "old_nodestatmon=$old_nodestatmon.\n"; - #get new cache values, it also loads the newly added modules + print "handleMonSignal: go there\n"; refreshProductList(); - #my @new_products=keys(%PRODUCT_LIST); - #my $new_nodestatmon=$NODESTAT_MON_NAME; - #print "new_products=@new_products.\n"; - #print "new_nodestatmon=$new_nodestatmon.\n"; - - - #check what have changed - my %summary; - foreach (@old_products) { $summary{$_}=-1;} - foreach (keys %PRODUCT_LIST) { $summary{$_}++;} - - #start/stop plug-ins accordingly - my %ret=(); - foreach (keys %summary) { - if ($summary{$_}==-1) { #plug-in deleted - #print "got here stop $_.\n"; - %ret=stopMonitoring(($_)); - } elsif ($summary{$_}==1) { #plug-in added - #print "got here start $_.\n"; - my %ret1=startMonitoring(($_)); - %ret=(%ret, %ret1); - } - } - - #handle node status monitoring changes - if ($old_nodestatmon ne $NODESTAT_MON_NAME) { - if ($old_nodestatmon) { - my @ret3=stopNodeStatusMonitoring($old_nodestatmon); - $ret{"Stop node status monitoring with $old_nodestatmon"}=\@ret3; - } - if ($NODESTAT_MON_NAME) { - my @ret4=startNodeStatusMonitoring($NODESTAT_MON_NAME); - $ret{"Start node status monitoring with $NODESTAT_MON_NAME"}=\@ret4; - } - } - - #registers or unregusters this module in the notification table for changes in - # the nodelist and monitoring tables. - if (! xCAT::Utils->isServiceNode()) { - if (keys(%PRODUCT_LIST) > 0) { - regNodelistNotif(); - } - else { - unregNodelistNotif(); - } - } - #setup the signal again $SIG{USR2}=\&handleMonSignal; - - #log status - foreach(keys(%ret)) { - my $retstat=$ret{$_}; - xCAT::MsgUtils->message('S', "[mon]: $_: @$retstat\n"); - } } @@ -262,62 +186,23 @@ sub sendMonSignal { #print "monitorctrl sendMonSignal masterpid=$masterpid\n"; if ($masterpid) { kill('USR2', $masterpid); - } else { - sub handle_response {return;} - my $cmdref; - $cmdref->{command}->[0]="updatemon"; - xCAT::Client::submit_request($cmdref,\&handle_response); } } - -#-------------------------------------------------------------------------------- -=head3 stop - It is called by the xcatd when xcatd stops. It - in tern calls the stop() function of each monitoring - plug-in modules, stops all the timers for pulling the - node status and unregisters for the nodelist - tables changes. - Arguments: - none - Returns: - 0 for successful. - non-0 for not successful. -=cut -#-------------------------------------------------------------------------------- -sub stop { - #print "\nmonitorctrl::stop called\n"; - - %ret=stopMonitoring(()); - if ($NODESTAT_MON_NAME) { - my @ret2 = stopNodeStatusMonitoring($NODESTAT_MON_NAME); - $ret{"Stop node status monitoring with $NODESTAT_MON_NAME"}=\@ret2; - } - - xCAT_monitoring::montbhandler->unregMonitoringNotif(); - if (! xCAT::Utils->isServiceNode()) { - unregNodelistNotif(); - } - - if (%ret) { - foreach(keys(%ret)) { - $retstat=$ret{$_}; - xCAT::MsgUtils->message('S',"[mon]: $_: @$retstat\n"); - # print "$_: @$retstat\n"; - } - } - - return 0; -} - #-------------------------------------------------------------------------------- =head3 startMonitoring It takes a list of monitoring plug-in names as an input and start the monitoring process for them. Arguments: - names -- an array of monitoring plug-in module names to be started. If non is specified, - all the plug-in modules registered in the monitoring table will be used. + names -- a pointer to an array of monitoring plug-in module names to be started. + If non is specified, all the plug-in modules registered in the monitoring + table will be used. + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: A hash table keyed by the plug-in names. The value is an array pointer pointer to a return code and message pair. For example: @@ -326,7 +211,17 @@ sub stop { =cut #-------------------------------------------------------------------------------- sub startMonitoring { - @product_names=@_; + my $nameref=shift; + if ($nameref =~ /xCAT_monitoring::monitorctrl/) { + $nameref=shift; + } + my $noderef=shift, + my $scope=shift; + my $callback=shift; + + refreshProductList(); + + my @product_names=@$nameref; #print "\nmonitorctrl::startMonitoring called with @product_names\n"; if (@product_names == 0) { @@ -335,6 +230,7 @@ sub startMonitoring { #print "product_names=@product_names\n"; my %ret=(); + print "-------startMonitoring: product_names=@product_names\n"; foreach(@product_names) { my $aRef=$PRODUCT_LIST{$_}; if ($aRef) { @@ -342,10 +238,11 @@ sub startMonitoring { undef $SIG{CHLD}; #initialize and start monitoring - my @ret1 = ${$module_name."::"}{start}->(); + no strict "refs"; + my @ret1 = ${$module_name."::"}{start}->($noderef, $scope, $callback); $ret{$_}=\@ret1; } else { - $ret{$_}=[1, "Monitoring plug-in module $_ is not registered."]; + $ret{$_}=[1, "Monitoring plug-in module $_ is not registered or enabled."]; } } @@ -362,6 +259,11 @@ sub startMonitoring { name -- name of the mornitoring plug-in module to be started for node status monitoring. If none is specified, use the one in the monitoring table that has the "nodestatmon" column set to be "1", or "Yes". + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: (return_code, error_message) @@ -372,19 +274,28 @@ sub startNodeStatusMonitoring { if ($pname =~ /xCAT_monitoring::monitorctrl/) { $pname=shift; } + my $noderef=shift, + my $scope=shift; + my $callback=shift; + + refreshProductList(); if (!$pname) {$pname=$NODESTAT_MON_NAME;} + print "----startNodeStatusMonitoring: pname=$pname\n"; if ($pname) { my $aRef=$PRODUCT_LIST{$pname}; if ($aRef) { my $module_name=$aRef->[1]; undef $SIG{CHLD}; + no strict "refs"; my $method = ${$module_name."::"}{supportNodeStatusMon}->(); + print "method=$method\n"; # return value 0 means not support. 1 means yes. if ($method > 0) { #start nodes tatus monitoring - my @ret2 = ${$module_name."::"}{startNodeStatusMon}->(); + no strict "refs"; + my @ret2 = ${$module_name."::"}{startNodeStatusMon}->($noderef, $scope, $callback); return @ret2; } else { @@ -407,8 +318,13 @@ sub startNodeStatusMonitoring { It takes a list of monitoring plug-in names as an input and stop the monitoring process for them. Arguments: - names -- an array of monitoring plug-in names to be stopped. If non is specified, + names -- a pointer to an array of monitoring plug-in names to be stopped. If non is specified, all the plug-ins registered in the monitoring table will be stopped. + p_nodes -- a pointer to an arrays of nodes to be stopped for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: A hash table keyed by the plug-in names. The value is ann array pointer pointer to a return code and message pair. For example: @@ -417,20 +333,33 @@ sub startNodeStatusMonitoring { =cut #-------------------------------------------------------------------------------- sub stopMonitoring { - @product_names=@_; + my $nameref=shift; + if ($nameref =~ /xCAT_monitoring::monitorctrl/) { + $nameref=shift; + } + my $noderef=shift, + my $scope=shift; + my $callback=shift; + + #refreshProductList(); + + my @product_names=@$nameref; + #print "\nmonitorctrl::stopMonitoring called with @product_names\n"; if (@product_names == 0) { @product_names=keys(%PRODUCT_LIST); } + print "-------stopMonitoring: product_names=@product_names\n"; my %ret=(); #stop each plug-in from monitoring the xcat cluster my $count=0; foreach(@product_names) { + my $aRef=$PRODUCT_LIST{$_}; - + my $module_name; if ($aRef) { $module_name=$aRef->[1]; } @@ -451,7 +380,8 @@ sub stopMonitoring { } #stop monitoring undef $SIG{CHLD}; - my @ret2 = ${$module_name."::"}{stop}->(); + no strict "refs"; + my @ret2 = ${$module_name."::"}{stop}->($noderef, $scope, $callback); $ret{$_}=\@ret2; } @@ -468,6 +398,11 @@ sub stopMonitoring { name -- name of the monitoring plu-in module to be stoped for node status monitoring. If none is specified, use the one in the monitoring table that has the "nodestatmon" column set to be "1", or "Yes". + p_nodes -- a pointer to an arrays of nodes to be stoped for monitoring. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: (return_code, error_message) @@ -478,8 +413,13 @@ sub stopNodeStatusMonitoring { if ($pname =~ /xCAT_monitoring::monitorctrl/) { $pname=shift; } + my $noderef=shift, + my $scope=shift; + my $callback=shift; + #refreshProductList(); if (!$pname) {$pname=$NODESTAT_MON_NAME;} + print "----stopNodeSatusMonitoring: pname=$pname\n"; if ($pname) { my $module_name; @@ -499,140 +439,13 @@ sub stopNodeStatusMonitoring { # $PRODUCT_LIST{$pname}=\@a; #} } - - my @ret2 = ${$module_name."::"}{stopNodeStatusMon}->(); + no strict "refs"; + my @ret2 = ${$module_name."::"}{stopNodeStatusMon}->($noderef, $scope, $callback); return @ret2; } } - -#-------------------------------------------------------------------------------- -=head3 processTableChanges - It is called by the NotifHander module - when the nodelist or the monitoring tables get changed. If a - node is added or removed from the nodelist table, this - function will inform all the monitoring plug-in modules. 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_monitoring::monitorctrl/) { - $action=shift; - } - my $tablename=shift; - my $old_data=shift; - my $new_data=shift; - - processNodelistTableChanges($action, $tablename, $old_data, $new_data); - -} - - -#-------------------------------------------------------------------------------- -=head3 processNodelistTableChanges - It is called when the nodelist table gets changed. - When node is added or removed from the nodelist table, this - function will inform all the monitoring plug-in modules. - Arguments: - See processTableChanges. - Returns: - 0 for successful. - non-0 for not successful. -=cut -#-------------------------------------------------------------------------------- -sub processNodelistTableChanges { - #does not handle this function on a service node - if (xCAT::Utils->isServiceNode()) { return 0;} - - my $action=shift; - if ($action =~ /xCAT_monitoring::monitorctrl/) { - $action=shift; - } - #print "monitorctrl::processNodelistTableChanges action=$action\n"; - - if ($action eq "u") { - return 0; - } - - if (!$masterpid) { refreshProductList();} - if (keys(%PRODUCT_LIST) ==0) { return 0; } - - my $tablename=shift; - my $old_data=shift; - my $new_data=shift; - - #foreach (keys %$new_data) { - # print "new_data{$_}=$new_data->{$_}\n"; - #} - - #for (my $j=0; $j<@$old_data; ++$j) { - # my $tmp=$old_data->[$j]; - # print "old_data[". $j . "]= @$tmp \n"; - #} - - my @nodenames=(); - if ($action eq "a") { - if ($new_data) { - my $status=''; - if (exists($new_data->{status})) {$status=$new_data->{status};} - push(@nodenames, [$new_data->{node}, $status]); - } - } - elsif ($action eq "d") { - #find out the index of "node" column - if ($old_data->[0]) { - $colnames=$old_data->[0]; - my $node_i=-1; - my $status_i=-1; - for ($i=0; $i<@$colnames; ++$i) { - if ($colnames->[$i] eq "node") { - $node_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]->[$status_i]]); - } - } - } - else { return 0; } - - if (@nodenames ==0) { return 0;} - - #call each plug-in to add the nodes into the monitoring domain - foreach(keys(%PRODUCT_LIST)) { - my $aRef=$PRODUCT_LIST{$_}; - my $module_name=$aRef->[1]; - #print "moduel_name=$module_name\n"; - if ($action eq "a") { ${$module_name."::"}{addNodes}->(\@nodenames, 1);} - else { ${$module_name."::"}{removeNodes}->(\@nodenames, 1);} - } - - - return 0; -} - - #-------------------------------------------------------------------------------- =head3 processMonitoringTableChanges It is called when the monitoring table gets changed. @@ -654,7 +467,8 @@ sub processMonitoringTableChanges { } my $tablename=shift; - if ($tablename eq "monitoring") { sendMonSignal(); return 0; } + #if ($tablename eq "monitoring") { sendMonSignal(); return 0; + #} # if nothing is being monitored, do not care. if (!$masterpid) { refreshProductList();} @@ -681,9 +495,9 @@ sub processMonitoringTableChanges { elsif (($action eq "d") || (($action eq "u"))) { #find out the index of "node" column if ($old_data->[0]) { - $colnames=$old_data->[0]; + my $colnames=$old_data->[0]; my $name_i=-1; - for ($i=0; $i<@$colnames; ++$i) { + for (my $i=0; $i<@$colnames; ++$i) { if ($colnames->[$i] eq "name") { $name_i=$i; last; @@ -697,11 +511,16 @@ sub processMonitoringTableChanges { } #print "plugin module setting changed:" . keys(%namelist) . "\n"; + + #TODO: need to let monservers handle it too. foreach(keys %namelist) { if (exists($PRODUCT_LIST{$_})) { my $aRef=$PRODUCT_LIST{$_}; my $module_name=$aRef->[1]; - ${$module_name."::"}{processSettingChanges}->(); + no strict "refs"; + if (defined(${$module_name."::"}{processSettingChanges})) { + ${$module_name."::"}{processSettingChanges}->(); + } } } @@ -709,8 +528,11 @@ sub processMonitoringTableChanges { } + + + #-------------------------------------------------------------------------------- -=head3 processNodeStatusChanges +=head3 setNodeStatusAttributes 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 @@ -724,8 +546,8 @@ sub processMonitoringTableChanges { non-0 for not successful. =cut #-------------------------------------------------------------------------------- -sub processNodeStatusChanges { - #print "monitorctrl::processNodeStatusChanges called\n"; +sub setNodeStatusAttributes { + #print "monitorctrl::setNodeStatusAttributes called\n"; my $temp=shift; if ($temp =~ /xCAT_monitoring::monitorctrl/) { $temp=shift; @@ -764,14 +586,14 @@ sub processNodeStatusChanges { =cut #-------------------------------------------------------------------------------- sub getNodeStatus { - %status=(); + my %status=(); my @inactive_nodes=(); my @active_nodes=(); my @unknown_nodes=(); my $table=xCAT::Table->new("nodelist", -create =>0); if ($table) { my @tmp1=$table->getAllAttribs(('node','status')); - if (defined(@tmp1) && (@tmp1 > 0)) { + if (@tmp1 > 0) { foreach(@tmp1) { my $node=$_->{node}; my $status=$_->{status}; @@ -846,7 +668,7 @@ sub refreshProductList { #print " $_:@$aRef\n"; } #print "NODESTAT_MON_NAME=$NODESTAT_MON_NAME\n"; - return 0; + return 0; } @@ -868,13 +690,13 @@ sub getPluginSettings { $name=shift; } - %settings=(); + my %settings=(); #get the monitoring plug-in list from the monitoring table my $table=xCAT::Table->new("monsetting", -create =>1); if ($table) { my @tmp1=$table->getAllAttribsWhere("name in (\'$name\')", 'key','value'); - if (defined(@tmp1) && (@tmp1 > 0)) { + if (@tmp1 > 0) { foreach(@tmp1) { if ($_->{key}) { $settings{$_->{key}}=$_->{value}; @@ -885,48 +707,109 @@ sub getPluginSettings { return %settings; } +#-------------------------------------------------------------------------------- +=head3 isMonServer + Determines if the local host is a monitoring server. + Arguments: + none. + Returns: + 1 if the local host is a moniterring server. + 0 if the local host is not a monitotering server. +=cut +#-------------------------------------------------------------------------------- +sub isMonServer { + my $pHash=getNodeMonServerPair([], 1); + my @hostinfo=xCAT::Utils->determinehostname(); + my $isSV=xCAT::Utils->isServiceNode(); + my %iphash=(); + foreach(@hostinfo) {$iphash{$_}=1;} + if (!$isSV) { $iphash{'noservicenode'}=1;} + + foreach my $pair (keys(%$pHash)) { + my @a=split(',', $pair); + if ($iphash{$a[0]} || $iphash{$a[1]}) { return 1;} + } + + return 0; +} #-------------------------------------------------------------------------------- =head3 getNodeMonServerPair - It gets the monserver and monmaster for a given node. + It gets the monserver and monmaster for the given nodes. Arguments: - node. - Returns: - "monserver,monmaser" First one is the monitoring service node ip/hostname - that faces the mn and the second one is the monitoring service node ip/hostname - that faces the cn. + $nodes a pointer to an array of nodes. If the array is empty, all nodes in the + nodelist table will be used. + retfromat 0-- A pointer to a hash table with node as the key and a the monserver pairs + string as the value. + For example: { node1=>"sv1,ma1", node2=>"sv1,ma1", node3=>"sv2,ma2"...} + 1-- A pointer to a hash table with monserver pairs as the key and an array + pointer of nodes as the value. + For example: { "sv1,ma1"=>[node1,node2], "sv2,ma2"=>node3...} + + The pair is in the format of "monserver,monmaser". First one is the monitoring service + node ip/hostname that faces the mn and the second one is the monitoring service + node ip/hostname that faces the cn. The value of the first one can be "noservicenode" meaning that there is no service node for that node. In this case the second one is the site master. + Returns: + An pointer to a hash. =cut #-------------------------------------------------------------------------------- sub getNodeMonServerPair { - my $node=shift; - if ($node =~ /xCAT_monitoring::monitorctrl/) { $node=shift; } + my $pnodes=shift; + if ($pnodes =~ /xCAT_monitoring::monitorctrl/) { $pnodes=shift; } + my $retformat=shift; - my $monserver; - my $monmaster; - my $table2=xCAT::Table->new("noderes", -create =>0); - my $pairs; - my $tmp2=$table2->getNodeAttribs($node, ['monserver', 'servicenode', 'xcatmaster']); - if ($tmp2) { - if ($tmp2->{monserver}) { - $pairs=$tmp2->{monserver}; - #when there is only one hostname specified in noderes.monserver, - #both monserver and monmaster take the same hostname. - if ($pairs !~ /,/) { $pairs=$tmp2->{monserver}.','.$tmp2->{monserver}; } - } - } + my @nodes=@$pnodes; + my $ret={}; - if (!$pairs) { - if ($tmp2->{servicenode}) { $monserver=$tmp2->{servicenode}; } - if ($tmp2->{xcatmaster}) { $monmaster=$tmp2->{xcatmaster}; } - if (!$monserver) { $monserver="noservicenode"; } - if (!$monmaster) { $monmaster=xCAT::Utils->get_site_attribute('master'); } - $pairs="$monserver,$monmaster"; + #get all nodes from the nodelist table if the input has 0 nodes. + if (@nodes==0) { + my $table1=xCAT::Table->new("nodelist", -create =>0); + my @tmp1=$table1->getAllAttribs(('node')); + foreach(@tmp1) { + push @nodes, $_->{node}; + } + $table1->close(); + } + if (@nodes==0) { return $ret; } + + my $table2=xCAT::Table->new("noderes", -create =>0); + my $tabdata = $table2->getNodesAttribs(\@nodes,['monserver', 'servicenode', 'xcatmaster']); + foreach my $node (@nodes) { + my $monserver; + my $monmaster; + my $pairs; + my $tmp2 = $tabdata->{$node}->[0]; + if ($tmp2 && $tmp2->{monserver}) { + $pairs=$tmp2->{monserver}; + #when there is only one hostname specified in noderes.monserver, + #both monserver and monmaster take the same hostname. + if ($pairs !~ /,/) { $pairs=$tmp2->{monserver}.','.$tmp2->{monserver}; } + } + + if (!$pairs) { + if ($tmp2->{servicenode}) { $monserver=$tmp2->{servicenode}; } + if ($tmp2->{xcatmaster}) { $monmaster=$tmp2->{xcatmaster}; } + if (!$monserver) { $monserver="noservicenode"; } + if (!$monmaster) { $monmaster=xCAT::Utils->get_site_attribute('master'); } + $pairs="$monserver,$monmaster"; + } + #print "node=$node, pairs=$pairs\n"; + + if ($retformat) { + if (exists($ret->{$pairs})) { + my $pa=$ret->{$pairs}; + push(@$pa, $node); + } + else { + $ret->{$pairs}=[$node]; + } + } + else { $ret->{$node}=$pairs; } } - #print "node=$node, pairs=$pairs\n"; $table2->close(); - return $pairs; + return $ret; } #-------------------------------------------------------------------------------- @@ -968,13 +851,13 @@ sub getMonHierarchy { } my $sitemaster=xCAT::Utils->get_site_attribute('master'); - if (defined(@tmp1) && (@tmp1 > 0)) { + if (@tmp1 > 0) { foreach(@tmp1) { my $node=$_->{node}; my $status=$_->{status}; my $row3=$temp_hash3{$node}; - my $nodetype="osi"; #default + my $nodetype=""; #default if (defined($row3) && ($row3)) { if ($row3->{nodetype}) { $nodetype=$row3->{nodetype}; } } @@ -1049,19 +932,25 @@ sub getMonServerWithInfo { #print "getMonServerWithInfo called with @in_nodes\n"; #get all from the noderes table + my @allnodes=(); + foreach (@in_nodes) { + push(@allnodes, $_->[0]); + } my $table3=xCAT::Table->new("nodetype", -create =>0); - + my $tabdata=$table3->getNodesAttribs(\@allnodes,['nodetype']); + my $pPairHash=getNodeMonServerPair(\@allnodes, 0); + foreach (@in_nodes) { my $node=$_->[0]; my $status=$_->[2]; + my $tmp3= $tabdata->{$node}->[0]; - my $tmp3=$table3->getNodeAttribs($node, ['nodetype']); - my $nodetype="osi"; #default + my $nodetype=""; #default if (defined($tmp3) && ($tmp3)) { if ($tmp3->{nodetype}) { $nodetype=$tmp3->{nodetype}; } } - my $pairs=getNodeMonServerPair($node); + my $pairs=$pPairHash->{$node}; if (exists($ret->{$pairs})) { my $pa=$ret->{$pairs}; @@ -1105,23 +994,29 @@ sub getMonServer { my $ret={}; #get all from nodelist table and noderes table - my $table=xCAT::Table->new("nodelist", -create =>0); - my $table3=xCAT::Table->new("nodetype", -create =>0); - + my @allnodes=(); foreach (@in_nodes) { - my @tmp1=$table->getAttribs({'node'=>$_}, ('node', 'status')); + push(@allnodes, $_->[0]); + } + my $table=xCAT::Table->new("nodelist", -create =>0); + my $tabdata=$table->getNodesAttribs(\@allnodes,['node', 'status']); + my $table3=xCAT::Table->new("nodetype", -create =>0); + my $tabdata3=$table3->getNodesAttribs(\@allnodes,['nodetype']); - if (defined(@tmp1) && (@tmp1 > 0)) { - my $node=$_; - my $status=$tmp1[0]->{status}; + my $pPairHash=getNodeMonServerPair(\@allnodes, 0); + + foreach my $node (@allnodes) { + my $tmp1=$tabdata->{$node}->[0]; + if ($tmp1) { + my $status=$tmp1->{status}; - my $tmp3=$table3->getNodeAttribs($node, ['nodetype']); - my $nodetype="osi"; #default + my $tmp3=$tabdata3->{$node}->[0]; + my $nodetype=""; #default if (defined($tmp3) && ($tmp3)) { if ($tmp3->{nodetype}) { $nodetype=$tmp3->{nodetype}; } } - my $pairs=getNodeMonServerPair($node); + my $pairs=$pPairHash->{$node}; if (exists($ret->{$pairs})) { @@ -1155,75 +1050,165 @@ sub nodeStatMonName { return $NODESTAT_MON_NAME; } + #-------------------------------------------------------------------------------- -=head3 addNodes - This function informs all the local active monitoring plug-ins to add the given - nodes to their monitoring domain. - Arguments: - noderange a pointer to an array of node names +=head3 getAllRegs + This function gets all the registered monitoring plug-ins. + Arguments: + none Returns: - ret a hash with plug-in name as the keys and the an arry of - [return code, error message] as the values. + a hash with the plug-in name as the key and a integer as value. + 0-- not monitored. + 1-- monitored + 2 -- monitored with node status monitored. =cut #-------------------------------------------------------------------------------- -sub addNodes { - my $noderef=shift; - if ($noderef =~ /xCAT_monitoring::monitorctrl/) { - $noderef=shift; - } - +sub getAllRegs +{ my %ret=(); - if (!$masterpid) { refreshProductList();} - if (keys(%PRODUCT_LIST) ==0) { return %ret; } - - #let all actvie modules to process it - foreach(keys(%PRODUCT_LIST)) { - my $aRef=$PRODUCT_LIST{$_}; - my $module_name=$aRef->[1]; - my @ret1=${$module_name."::"}{addNodes}->($noderef, 0); - $ret{$_}=\@ret1; - - #for service node, the error may not be get shown, log it - if ($ret1[0] >0) { - xCAT::MsgUtils->message('S', "[mon]: $svname: $ret1[1]\n"); + #get all the module names from monitoring table + my %names=(); + my $table=xCAT::Table->new("monitoring", -create =>1); + if ($table) { + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + my $monnode=0; + my $disable=1; + if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $monnode=1; } + if ($_->{disable} =~ /0|NO|No|no|N|n/) { $disable=0; } + if ($disable) { $ret{$_->{name}}=0; } + else { + if ($monnode) { $ret{$_->{name}}=2; } + else { $ret{$_->{name}}=1;} + } + } } - } + $table->close(); + } return %ret; } + #-------------------------------------------------------------------------------- -=head3 removeNodes - This function informs all the local active monitoring plug-ins to remove the given - nodes to their monitoring domain. +=head3 config + This function configures the cluster for the given nodes. Arguments: - noderange a pointer to an array of node names + names -- a pointer to an array of monitoring plug-in names. If non is specified, + all the plug-ins registered in the monitoring table will be notified. + p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: ret a hash with plug-in name as the keys and the an arry of [return code, error message] as the values. =cut #-------------------------------------------------------------------------------- -sub removeNodes { - my $noderef=shift; - if ($noderef =~ /xCAT_monitoring::monitorctrl/) { - $noderef=shift; +sub config { + my $nameref=shift; + if ($nameref =~ /xCAT_monitoring::monitorctrl/) { + $nameref=shift; } + my $noderef=shift, + my $scope=shift; + my $callback=shift; my %ret=(); - if (!$masterpid) { refreshProductList();} - if (keys(%PRODUCT_LIST) ==0) { return %ret; } + my @product_names=@$nameref; - #let all actvie modules to process it - foreach(keys(%PRODUCT_LIST)) { - my $aRef=$PRODUCT_LIST{$_}; - my $module_name=$aRef->[1]; - my @ret1=${$module_name."::"}{removeNodes}->($noderef, 0); - $ret{$_}=\@ret1; - - if (($ret1[0] >0)) { - xCAT::MsgUtils->message('S', "[mon]: $_: $ret1[1]\n"); - } + my %all=getAllRegs(); + if (@product_names == 0) { + @product_names=keys(%all); } + print "------config: product_names=@product_names\n"; + + foreach(@product_names) { + if (exists($all{$_})) { + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$_.pm"; + my $module_name="xCAT_monitoring::$_"; + #load the module in memory + eval {require($file_name)}; + if ($@) { + my @ret3=(1, "The file $file_name cannot be located or has compiling errors.\n"); + $ret{$_}=\@ret3; + next; + } + undef $SIG{CHLD}; + #initialize and start monitoring + no strict "refs"; + if (defined(${$module_name."::"}{config})) { + my @ret1 = ${$module_name."::"}{config}->($noderef, $scope, $callback); + $ret{$_}=\@ret1; + } + } else { + $ret{$_}=[1, "Monitoring plug-in module $_ is not registered."]; + } + } + return %ret; +} + +#-------------------------------------------------------------------------------- +=head3 deconfig + This function de-configures the cluster for the given nodes. + It function informs all the local active monitoring plug-ins to + remove the given nodes to their monitoring domain. + Arguments: + names -- a pointer to an array of monitoring plug-in names. If non is specified, + all the plug-ins registered in the monitoring table will be notified. + p_nodes -- a pointer to an arrays of nodes to be removed for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both loca lhost and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + ret a hash with plug-in name as the keys and the an arry of + [return code, error message] as the values. +=cut +#-------------------------------------------------------------------------------- +sub deconfig { + my $nameref=shift; + if ($nameref =~ /xCAT_monitoring::monitorctrl/) { + $nameref=shift; + } + my $noderef=shift, + my $scope=shift; + my $callback=shift; + + my @product_names=@$nameref; + + my %ret=(); + my %all=getAllRegs(); + if (@product_names == 0) { + @product_names=keys(%all); + } + print "------deconfig: product_names=@product_names\n"; + + + foreach(@product_names) { + if (exists($all{$_})) { + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$_.pm"; + my $module_name="xCAT_monitoring::$_"; + #load the module in memory + eval {require($file_name)}; + if ($@) { + my @ret3=(1, "The file $file_name cannot be located or has compiling errors.\n"); + $ret{$_}=\@ret3; + next; + } + undef $SIG{CHLD}; + #initialize and start monitoring + no strict "refs"; + if (defined(${$module_name."::"}{deconfig})) { + my @ret1 = ${$module_name."::"}{deconfig}->($noderef, $scope, $callback); + $ret{$_}=\@ret1; + } + } else { + $ret{$_}=[1, "Monitoring plug-in module $_ is not registered."]; + } + } return %ret; } @@ -1246,23 +1231,28 @@ sub getNodeConfData { $node=shift; } - %ret=(); + my %ret=(); #get monitoring server - my $pair=xCAT_monitoring::monitorctrl->getNodeMonServerPair($node); - my @pair_array=split(',', $pair); - my $monserver=$pair_array[1]; + my $pHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair([$node], 0); + my @pair_array=split(',', $pHash->{$node}); + my $monserver=$pair_array[0]; + if ($monserver eq 'noservicenode') { $monserver=hostname(); } $ret{MONSERVER}=$monserver; + $ret{MONMASTER}=$pair_array[1]; - #get all the module names from /opt/xcat/lib/perl/XCAT_monitoring directory + #get all the module names from monitoring table my %names=(); - my @plugins=glob("$::XCATROOT/lib/perl/xCAT_monitoring/*.pm"); - foreach (@plugins) { - /.*\/([^\/]*).pm$/; - $names{$1}=1; + my $table=xCAT::Table->new("monitoring", -create =>1); + if ($table) { + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { $names{$_->{name}}=1; } + } + } else { + xCAT::MsgUtils->message('S', "[mon]: getPostScripts for node $node: cannot open monitoring table.\n"); + return %ret; } - # remove 2 files that are not plug-ins - delete($names{monitorctrl}); - delete($names{montbhandler}); + #get node conf data from each plug-in module foreach my $pname (keys(%names)) { @@ -1271,6 +1261,7 @@ sub getNodeConfData { #load the module in memory eval {require($file_name)}; if (!$@) { + no strict "refs"; if (defined(${$module_name."::"}{getNodeConfData})) { ${$module_name."::"}{getNodeConfData}->($node, \%ret); } @@ -1282,92 +1273,6 @@ sub getNodeConfData { -#-------------------------------------------------------------------------------- -=head3 configMaster4Nodes - This function goes to every monitoring plug-in module and configures the current - the localhost to accept the given nodes into the monitoring domain. - Arguments: - noderef a pointer to an array of nodes. - Returns: - (code, message) -=cut -#-------------------------------------------------------------------------------- -sub configMaster4Nodes { - my $noderef=shift; - if ($noderef =~ /xCAT_monitoring::monitorctrl/) { - $noderef=shift; - } - - #get all the module names from /opt/xcat/lib/perl/XCAT_monitoring directory - my %names=(); - my @plugins=glob("$::XCATROOT/lib/perl/xCAT_monitoring/*.pm"); - foreach (@plugins) { - /.*\/([^\/]*).pm$/; - $names{$1}=1; - } - # remove 2 files that are not plug-ins - delete($names{monitorctrl}); - delete($names{montbhandler}); - - #get node conf data from each plug-in module - my $message; - my $retcode=0; - foreach my $pname (keys(%names)) { - my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; - my $module_name="xCAT_monitoring::$pname"; - #load the module in memory - eval {require($file_name)}; - if (!$@) { - if (defined(${$module_name."::"}{configMaster4Nodes})) { - my ($c, $m)=${$module_name."::"}{configMaster4Nodes}->($noderef); - if ($c) {$retcode=$c; $message .= "$pname: $m\n";} - } - } - } - - return ($retcode, $message); -} - -#-------------------------------------------------------------------------------- -=head3 shouldConfigMaster - This function goes to every monitoring plug-in module to check if - anyone implements the configMaster4Nodes function. - Arguments: - none - Returns: - 1, if any monitoring plug-in module implements the configMaster4Nodes fucntion. - 0. if none. -=cut -#-------------------------------------------------------------------------------- -sub shouldConfigMaster { - - #get all the module names from /opt/xcat/lib/perl/XCAT_monitoring directory - my %names=(); - my @plugins=glob("$::XCATROOT/lib/perl/xCAT_monitoring/*.pm"); - foreach (@plugins) { - /.*\/([^\/]*).pm$/; - $names{$1}=1; - } - # remove 2 files that are not plug-ins - delete($names{monitorctrl}); - delete($names{montbhandler}); - - #get node conf data from each plug-in module - foreach my $pname (keys(%names)) { - my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; - my $module_name="xCAT_monitoring::$pname"; - #load the module in memory - eval {require($file_name)}; - if (!$@) { - if (defined(${$module_name."::"}{configMaster4Nodes})) { - return 1; - } - } - } - - return 0; -} - diff --git a/xCAT-server/lib/xcat/monitoring/montbhandler.pm b/xCAT-server/lib/xcat/monitoring/montbhandler.pm index d96ea2f95..696fdfeba 100644 --- a/xCAT-server/lib/xcat/monitoring/montbhandler.pm +++ b/xCAT-server/lib/xcat/monitoring/montbhandler.pm @@ -46,7 +46,7 @@ sub regMonitoringNotif { my $tab = xCAT::Table->new('notification'); my $regged=0; if ($tab) { - (my $ref) = $tab->getAttribs({filename => qw(montbhandler.pm)}, tables); + (my $ref) = $tab->getAttribs({filename => qw(montbhandler.pm)}, 'tables'); if ($ref and $ref->{tables}) { $regged=1; } @@ -54,7 +54,7 @@ sub regMonitoringNotif { } if (!$regged) { - xCAT_plugin::notification::regNotification([qw(montbhandler.pm monitoring,monsetting -o a,u,d)]); + xCAT_plugin::notification::regNotification([qw(montbhandler.pm monsetting -o a,u,d)]); } } diff --git a/xCAT-server/lib/xcat/monitoring/snmpmon.pm b/xCAT-server/lib/xcat/monitoring/snmpmon.pm index 842739bce..52812db54 100644 --- a/xCAT-server/lib/xcat/monitoring/snmpmon.pm +++ b/xCAT-server/lib/xcat/monitoring/snmpmon.pm @@ -6,11 +6,12 @@ BEGIN $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; } use lib "$::XCATROOT/lib/perl"; +use strict; use IO::File; use xCAT::Utils; use xCAT::MsgUtils; use xCAT_monitoring::monitorctrl; - +use Sys::Hostname; #print "xCAT_monitoring::snmpmon loaded\n"; 1; @@ -27,61 +28,334 @@ use xCAT_monitoring::monitorctrl; #-------------------------------------------------------------------------------- =head3 start - This function gets called by the monitorctrl module - when xcatd starts. + This function gets called by the monitorctrl module when monstart command + gets called and when xcatd starts. Arguments: - None. + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both localhost and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: - (return code, message) + (return code, message) + if the callback is set, use callback to display the status and error. =cut #-------------------------------------------------------------------------------- sub start { - #print "snmpmon::start called\n"; + print "snmpmon:start called\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::snmpmon/) { + $noderef=shift; + } + my $scope=shift; + my $callback=shift; - # do not turn it on on the service node - #if (xCAT::Utils->isServiceNode()) { return (0, "");} + my $localhostname=hostname(); - # unless we are running on linux, exit. - #unless($^O eq "linux"){ - # exit; - # } + # get the PID of the currently running snmptrapd if it is running. + # then stop it and restart it again so that it reads our new + # snmptrapd.conf configuration file. Then the process + my $pid; + chomp($pid= `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`); + if($pid){ + `/bin/kill -9 $pid`; + } + # start it up again! + system("/usr/sbin/snmptrapd -m ALL"); + + # get the PID of the currently running snmpd if it is running. + # if it's running then we just leave. Otherwise, if we don't get A PID, then we + # assume that it isn't running, and start it up again! + chomp($pid= `/bin/ps -ef | /bin/grep snmpd | /bin/grep -v grep | /bin/awk '{print \$2}'`); + unless($pid){ + # start it up! + system("/usr/sbin/snmpd"); + } + + if ($scope) { + #enable alerts on the nodes + #enable bmcs if any + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: enabling SNMP alert on BMCs and MMs..."; + $callback->($rsp); + } + configBMC(1, $noderef, $callback); + + #enable MMAs if any + configMPA(1, $noderef, $callback); + } + + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: started."; + $callback->($rsp); + } + + return (0, "started") +} + + + +#-------------------------------------------------------------------------------- +=head3 stop + This function gets called by the monitorctrl module when monstop command gets called. + Arguments: + p_nodes -- a pointer to an arrays of nodes to be stoped for monitoring. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + (return code, message) + if the callback is set, use callback to display the status and error. +=cut +#-------------------------------------------------------------------------------- +sub stop { + print "snmpmon:stop called\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::snmpmon/) { + $noderef=shift; + } + my $scope=shift; + my $callback=shift; + + my $localhostname=hostname(); + + if ($scope) { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: disabling SNMP alert on BMCs and MMs..."; + $callback->($rsp); + } + #disable MMAs if any + configMPA(0, $noderef, $callback); + + #disable BMC so that it stop senging alerts (PETs) to this node + configBMC(0, $noderef, $callback); + } + + + # now check to see if the daemon is running. If it is then we need to resart or stop? + # it with the new snmptrapd.conf file that will not forward events to RMC. + chomp(my $pid= `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`); + if($pid){ + `/bin/kill -9 $pid`; + # start it up again! + #system("/usr/sbin/snmptrapd"); + } + + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: stopped."; + $callback->($rsp); + } + + return (0, "stopped"); +} + + +#-------------------------------------------------------------------------------- +=head3 supportNodeStatusMon + This function is called by the monitorctrl module to check + if SNMP can help monitoring and returning the node status. + SNMP does not support this function. + + Arguments: + none + Returns: + 0 +=cut +#-------------------------------------------------------------------------------- +sub supportNodeStatusMon { + return 0; +} + + + +#-------------------------------------------------------------------------------- +=head3 startNodeStatusMon + This function is called by the monitorctrl module when monstart gets called and + when xcatd starts. It starts monitoring the node status and feed them back + to xCAT. + Arguments: + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means loca lhost only. + 2 means both localhost and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + note: p_nodes and scope are ignored by this plugin. + Returns: + (return code, message) + if the callback is set, use callback to display the status and error. + This function is called by the monitorctrl module to tell +=cut +#-------------------------------------------------------------------------------- +sub startNodeStatusMon { + return (1, "This function is not supported."); +} + + +#-------------------------------------------------------------------------------- +=head3 stopNodeStatusMon + This function is called by the monitorctrl module when monstop command is issued. + It stops feeding the node status info back to xCAT. + Arguments: + p_nodes -- a pointer to an arrays of nodes to stoped for monitoring. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + note: p_nodes and scope are ignored by this plugin. + Returns: + (return code, message) + if the callback is set, use callback to display the status and error. +=cut +#-------------------------------------------------------------------------------- +sub stopNodeStatusMon { + return (1, "This function is not supported."); +} + + + +#-------------------------------------------------------------------------------- +=head3 config + This function configures the cluster for the given nodes. + This function is called when monconfig command is issued or when xcatd starts + on the service node. It will configure the cluster to include the given nodes within + the monitoring doamin. + Arguments: + p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means localhost and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + (error code, error message) +=cut +#-------------------------------------------------------------------------------- +sub config { + print "snmpmon:config called\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::snmpmon/) { + $noderef=shift; + } + my $scope=shift; + my $callback=shift; + + my $localhostname=hostname(); # check supported snmp package my $cmd; my @snmpPkg = `/bin/rpm -qa | grep snmp`; my $pkginstalled = grep(/net-snmp/, @snmpPkg); - if ($pkginstalled) { + if (!$pkginstalled) { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: net-snmp is not installed."; + $callback->($rsp); + } + return (1, "net-snmp is not installed") + } else { my ($ret, $err)=configSNMP(); if ($ret != 0) { return ($ret, $err);} - } else { - return (1, "net-snmp is not installed") } - #enable bmcs if any - configBMC(1); - - #enable MMAs if any - configMPA(1); - #configure mail to enabling receiving mails from trap handler configMail(); - return (0, "started") + if ($scope) { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: setting up SNMP alert destination for BMCs and MMs ...."; + $callback->($rsp); + } + #enable bmcs if any + configBMC(2, $noderef, $callback); + + #enable MMAs if any + configMPA(2, $noderef, $callback); + } + + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: done."; + $callback->($rsp); + } + + return (0, "") } +#-------------------------------------------------------------------------------- +=head3 deconfig + This function de-configures the cluster for the given nodes. + This function is called by the monitorctrl module when nodes are removed + from the xCAT cluster. It should remove the nodes from the product for monitoring. + Arguments: + p_nodes -- a pointer to an arrays of nodes to be removed for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means local host only. + 2 means both local host and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + (error code, error message) +=cut +#-------------------------------------------------------------------------------- +sub deconfig { + print "snmpmon:deconfig called\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::snmpmon/) { + $noderef=shift; + } + my $scope=shift; + my $callback=shift; + my $localhostname=hostname(); + + if (-f "/usr/share/snmp/snmptrapd.conf.orig"){ + # copy back the old one + `mv -f /usr/share/snmp/snmptrapd.conf.orig /usr/share/snmp/snmptrapd.conf`; + } else { + if (-f "/usr/share/snmp/snmptrapd.conf"){ + + # if the file exists, delete all entries that have xcat_traphandler + my $cmd = "grep -v xcat_traphandler /usr/share/snmp/snmptrapd.conf "; + $cmd .= "> /usr/share/snmp/snmptrapd.conf.unconfig "; + `$cmd`; + + # move it back to the snmptrapd.conf file. + `mv -f /usr/share/snmp/snmptrapd.conf.unconfig /usr/share/snmp/snmptrapd.conf`; + } + } + + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: done."; + $callback->($rsp); + } + + return (0, ""); +} + + + #-------------------------------------------------------------------------------- =head3 configBMC This function configures BMC to setup the snmp destination, enable/disable PEF policy table entry number 1. Arguments: - actioon -- 1 enable PEF policy table. 0 disable PEF policy table. + actioon -- 0 disable alert. 1 enable alert. 2 setup snmp destination + + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + callback -- the callback pointer for error and status displaying. It can be null. Returns: (return code, message) =cut #-------------------------------------------------------------------------------- sub configBMC { my $action=shift; + my $noderef=shift; + my $callback=shift; my $ret_text=""; my $ret_val=0; @@ -89,22 +363,24 @@ sub configBMC { #the identification of this node my @hostinfo=xCAT::Utils->determinehostname(); my $isSV=xCAT::Utils->isServiceNode(); - %iphash=(); + my %iphash=(); foreach(@hostinfo) {$iphash{$_}=1;} if (!$isSV) { $iphash{'noservicenode'}=1;} - - + + my $pPairHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair($noderef, 0); + my %masterhash=(); my @node_a=(); my $table=xCAT::Table->new("ipmi"); if ($table) { my @tmp1=$table->getAllNodeAttribs(['node','bmc']); - if (defined(@tmp1) && (@tmp1 > 0)) { + if (@tmp1 > 0) { foreach(@tmp1) { my $node=$_->{node}; my $bmc=$_->{bmc}; + if (! exists($pPairHash->{$node})) {next;} - my $pairs=xCAT_monitoring::monitorctrl->getNodeMonServerPair($node); + my $pairs=$pPairHash->{$node}; my @a_temp=split(',',$pairs); my $monserver=$a_temp[0]; my $master=$a_temp[1]; @@ -132,17 +408,22 @@ sub configBMC { #now doing the real thing: enable PEF alert policy table my $noderange=join(',',@node_a ); - my $actionstring="en"; - if ($action==0) {$actionstring="dis";} - #print "XCATBYPASS=Y rspconfig $noderange alert=$actionstring\n"; - my $result = `XCATBYPASS=Y rspconfig $noderange alert=$actionstring 2>&1`; - if ($?) { - xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"); - $ret_tex .= "Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"; - } - - #setup the snmp destination - if ($action==1) { + if ($action==0) { + print "XCATBYPASS=Y rspconfig $noderange alert=dis\n"; + my $result = `XCATBYPASS=Y rspconfig $noderange alert=dis 2>&1`; + if ($?) { + xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"); + $ret_text .= "Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"; + } + } elsif ($action==1) { + print "XCATBYPASS=Y rspconfig $noderange alert=en\n"; + my $result = `XCATBYPASS=Y rspconfig $noderange alert=en 2>&1`; + if ($?) { + xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"); + $ret_text .= "Changeing SNMP PEF policy for IPMI nodes $noderange:\n $result\n"; + } + } else { + #setup the snmp destination foreach (keys(%masterhash)) { my $ref2=$masterhash{$_}; if (@$ref2==0) { next;} @@ -154,16 +435,24 @@ sub configBMC { $ret_val=1; $ret_text .= "Converting to IP: $ptmp->[1]\n"; } else { - #print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1]\n"; + print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1]\n"; my $result2 = `XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1] 2>&1`; if ($?) { xCAT::MsgUtils->message('S', "[mon]: Changing SNMP destination for IPMI nodes $nr2:\n $result2\n"); - $ret_tex .= "Changing SNMP destination for IPMI nodes $nr2:\n $result2\n"; + $ret_text .= "Changing SNMP destination for IPMI nodes $nr2:\n $result2\n"; } } } } + if ($callback) { + my $rsp={}; + if ($ret_val) { + $rsp->{data}->[0]="$ret_text"; + } + $callback->($rsp); + } + return ($ret_val, $ret_text); } @@ -174,13 +463,18 @@ sub configBMC { This function configures Blade Center Management Module to setup the snmp destination, enable/disable remote alert notification. Arguments: - actioon -- 1 enable remote alert notification. 0 disable remote alert notification. + actioon -- 1 enable remote alert notification. 0 disable remote alert notification. + 2 setting up snmp destination. + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + callback -- the callback pointer for error and status displaying. It can be null. Returns: (return code, message) =cut #-------------------------------------------------------------------------------- sub configMPA { my $action=shift; + my $noderef=shift; + my $callback=shift; my $ret_val=0; my $ret_text=""; @@ -188,25 +482,35 @@ sub configMPA { #the identification of this node my @hostinfo=xCAT::Utils->determinehostname(); my $isSV=xCAT::Utils->isServiceNode(); - %iphash=(); + my %iphash=(); foreach(@hostinfo) {$iphash{$_}=1;} if (!$isSV) { $iphash{'noservicenode'}=1;} + my $all=0; + my %nodehash=(); + if ((!$noderef) || (@$noderef==0)) {$all=1;} + else { + foreach(@$noderef) { $nodehash{$_}=1;} + } + my %mpa_hash=(); my %masterhash=(); my @node_a=(); my $table=xCAT::Table->new("mp"); if ($table) { - my @tmp1=$table->getAllNodeAttribs(['mpa']); - if (defined(@tmp1) && (@tmp1 > 0)) { + my @tmp1=$table->getAllNodeAttribs(['node','mpa']); + if (@tmp1 > 0) { foreach(@tmp1) { + my $node=$_->{node}; my $mpa=$_->{mpa}; + if ((!$all) && (!exists($nodehash{$node})) && (!exists($nodehash{$mpa}))) {next;} if ($mpa_hash{$mpa}) { next;} #already handled $mpa_hash{$mpa}=1; - my $pairs=xCAT_monitoring::monitorctrl->getNodeMonServerPair($mpa); + my $pHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0); + my $pairs=$pHash->{$mpa}; my @a_temp=split(',',$pairs); my $monserver=$a_temp[0]; my $master=$a_temp[1]; @@ -235,19 +539,22 @@ sub configMPA { #now doing the real thing: enable PEF alert policy table my $noderange=join(',',@node_a ); - #print "noderange=@noderange\n"; - my $actionstring="en"; - if ($action==0) {$actionstring="dis";} - - #print "XCATBYPASS=Y rspconfig $noderange alert=$actionstring\n"; - my $result = `XCATBYPASS=Y rspconfig $noderange alert=$actionstring 2>&1`; - if ($?) { - xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"); - $ret_text .= "Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"; - } - - #setup the snmp destination - if ($action==1) { + if ($action==0) { + print "XCATBYPASS=Y rspconfig $noderange alert=dis\n"; + my $result = `XCATBYPASS=Y rspconfig $noderange alert=dis 2>&1`; + if ($?) { + xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"); + $ret_text .= "Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"; + } + } elsif ($action==1) { + print "XCATBYPASS=Y rspconfig $noderange alert=en\n"; + my $result = `XCATBYPASS=Y rspconfig $noderange alert=en 2>&1`; + if ($?) { + xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"); + $ret_text .= "Changeing SNMP remote alert profile for Blade Center MM $noderange:\n $result\n"; + } + } else { + #setup the snmp destination foreach (keys(%masterhash)) { my $ref2=$masterhash{$_}; if (@$ref2==0) { next;} @@ -259,7 +566,7 @@ sub configMPA { $ret_val=1; $ret_text .= "Converting to IP: $ptmp->[1]\n"; } else { - #print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1]\n"; + print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1]\n"; my $result2 = `XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1] 2>&1`; if ($?) { xCAT::MsgUtils->message('S', "[mon]: Changing SNMP destination for Blade Center MM $nr2:\n $result2\n"); @@ -269,6 +576,14 @@ sub configMPA { } } + if ($callback) { + my $rsp={}; + if ($ret_val) { + $rsp->{data}->[0]="$ret_text"; + } + $callback->($rsp); + } + return ($ret_val, $ret_text); } @@ -324,7 +639,7 @@ sub configSNMP { s/\s*forward/\#forward/; #comment out the old one if (!$forward_handled) { print FILE "forward default $master\n"; - $forward_handle=1; + $forward_handled=1; } } } @@ -350,6 +665,7 @@ sub configSNMP { } else { # The snmptrapd.conf file does not exists # create the file: + my $handle = new IO::File; open($handle, ">/usr/share/snmp/snmptrapd.conf"); print $handle "authCommunity log,execute,net public\n"; if ($isSN) { @@ -361,27 +677,7 @@ sub configSNMP { } # TODO: put the mib files to /usr/share/snmp/mibs - - # get the PID of the currently running snmptrapd if it is running. - # then stop it and restart it again so that it reads our new - # snmptrapd.conf configuration file. Then the process - chomp(my $pid= `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`); - if($pid){ - `/bin/kill -9 $pid`; - } - # start it up again! - system("/usr/sbin/snmptrapd -m ALL"); - - # get the PID of the currently running snmpd if it is running. - # if it's running then we just leave. Otherwise, if we don't get A PID, then we - # assume that it isn't running, and start it up again! - chomp(my $pid= `/bin/ps -ef | /bin/grep snmpd | /bin/grep -v grep | /bin/awk '{print \$2}'`); - unless($pid){ - # start it up again! - system("/usr/sbin/snmpd"); - } - - return (0, "started"); + return (0, ""); } #-------------------------------------------------------------------------------- @@ -414,175 +710,7 @@ sub configMail { } -#-------------------------------------------------------------------------------- -=head3 stop - This function gets called by the monitorctrl module when - xcatd stops. - Arguments: - none - Returns: - (return code, message) -=cut -#-------------------------------------------------------------------------------- -sub stop { - #print "snmpmon::stop called\n"; - # do not turn it on on the service node - #if (xCAT::Utils->isServiceNode()) { return (0, "");} - - #disable MMAs if any - configMPA(0); - - #disable BMC so that it stop senging alerts (PETs) to this node - configBMC(0); - - if (-f "/usr/share/snmp/snmptrapd.conf.orig"){ - # copy back the old one - `mv -f /usr/share/snmp/snmptrapd.conf.orig /usr/share/snmp/snmptrapd.conf`; - } else { - if (-f "/usr/share/snmp/snmptrapd.conf"){ - - # if the file exists, delete all entries that have xcat_traphandler - my $cmd = "grep -v xcat_traphandler /usr/share/snmp/snmptrapd.conf "; - $cmd .= "> /usr/share/snmp/snmptrapd.conf.unconfig "; - `$cmd`; - - # move it back to the snmptrapd.conf file. - `mv -f /usr/share/snmp/snmptrapd.conf.unconfig /usr/share/snmp/snmptrapd.conf`; - } - } - - # now check to see if the daemon is running. If it is then we need to resart or stop? - # it with the new snmptrapd.conf file that will not forward events to RMC. - chomp(my $pid= `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`); - if($pid){ - `/bin/kill -9 $pid`; - # start it up again! - #system("/usr/sbin/snmptrapd"); - } - - return (0, "stopped"); -} - - - - -#-------------------------------------------------------------------------------- -=head3 supportNodeStatusMon - This function is called by the monitorctrl module to check - if SNMP can help monitoring and returning the node status. - SNMP does not support this function. - - Arguments: - none - Returns: - 1 -=cut -#-------------------------------------------------------------------------------- -sub supportNodeStatusMon { - return 0; -} - - - -#-------------------------------------------------------------------------------- -=head3 startNodeStatusMon - This function is called by the monitorctrl module to tell - SNMP to start monitoring the node status and feed them back - to xCAT. SNMP does not have this support. - - Arguments: - None. - Returns: - (return code, message) - -=cut -#-------------------------------------------------------------------------------- -sub startNodeStatusMon { - return (1, "This function is not supported."); -} - - -#-------------------------------------------------------------------------------- -=head3 stopNodeStatusMon - This function is called by the monitorctrl module to tell - SNMP to stop feeding the node status info back to xCAT. - SNMP does not support this function. - - Arguments: - none - Returns: - (return code, message) -=cut -#-------------------------------------------------------------------------------- -sub stopNodeStatusMon { - return (1, "This function is not supported."); -} - - -#-------------------------------------------------------------------------------- -=head3 addNodes - This function adds the nodes into the SNMP domain. - Arguments: - nodes --nodes to be added. It is a pointer to an array. If the next argument is - 1, each element is a ref to an array of [nodes, status]. For example: - [['node1', 'active'], ['node2', 'booting']..]. - if the next argument is 0, each element is a node name to be added. - boolean -- 1, or 0. - Returns: - (error code, error message) -=cut -#-------------------------------------------------------------------------------- -sub addNodes { -# print "snmpmon::addNodes\n"; -# $noderef=shift; -# if ($noderef =~ /xCAT_monitoring::snmpmon/) { -# $noderef=shift; -# } -# my $info=shift; -# if ($info) { -# foreach(@$noderef) { -# my $node_info=$_; -# print " node=$node_info->[0], status=$node_info->[1]\n"; -# } -# } else { -# print "noderef=@$noderef\n"; -# } - - return (0, "ok"); -} - -#-------------------------------------------------------------------------------- -=head3 removeNodes - This function removes the nodes from the SNMP domain. - Arguments: - nodes --nodes to be added. It is a pointer to an array. If the next argument is - 1, each element is a ref to an array of [nodes, status]. For example: - [['node1', 'active'], ['node2', 'booting']..]. - if the next argument is 0, each element is a node name to be added. - boolean -- 1, or 0. - Returns: - (error code, error message) -=cut -#-------------------------------------------------------------------------------- -sub removeNodes { -# print "snmpmon::removeNodes\n"; -# $noderef=shift; -# if ($noderef =~ /xCAT_monitoring::snmpmon/) { -# $noderef=shift; -# } -# my $info=shift; -# if ($info) { -# foreach(@$noderef) { -# my $node_info=$_; -# print " node=$node_info->[0], status=$node_info->[1]\n"; -# } -# } else { -# print "noderef=@$noderef\n"; -# } - - return (0, "ok"); -} #-------------------------------------------------------------------------------- =head3 processSettingChanges @@ -646,3 +774,101 @@ sub getDescription { system events.\n" } +#-------------------------------------------------------------------------------- +=head3 getNodesMonServers + This function checks the given nodes, if they are bmc/ipmi nodes, the monserver pairs of + the nodes will be returned. If the nodes are managed by MM, the monserver pairs of their + mpa will be returned. + Arguments: + p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all. + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + A pointer to a hash table with monserver pairs as the key and an array + pointer of nodes as the value. + For example: { "sv1,ma1"=>[node1,node2], "sv2,ma2"=>node3...} + The pair is in the format of "monserver,monmaser". First one is the monitoring service + node ip/hostname that faces the mn and the second one is the monitoring service + node ip/hostname that faces the cn. + The value of the first one can be "noservicenode" meaning that there is no service node + for that node. In this case the second one is the site master. +=cut +#-------------------------------------------------------------------------------- +sub getNodesMonServers +{ + print "snmpmon:getNodesMonServer called\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::snmpmon/) { + $noderef=shift; + } + my $callback=shift; + + my $ret={}; + my $localhostname=hostname(); + my $pPairHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair($noderef, 0); + + #check for blades, only returns the MPAs and their monservers + my %mpa_hash=(); + my $table=xCAT::Table->new("mp"); + if ($table) { + my @tmp1=$table->getAllNodeAttribs(['node','mpa']); + if (@tmp1 > 0) { + foreach(@tmp1) { + my $node=$_->{node}; + my $mpa=$_->{mpa}; + if ((!exists($pPairHash->{$node})) && (!exists($pPairHash->{$mpa}))) {next;} #not in input + + #if (exists($pPairHash->{$node})) { delete($pPairHash->{$node}); } + if ($mpa_hash{$mpa}) { next;} #already handled + + $mpa_hash{$mpa}=1; + + my $pairs; + if (exists($pPairHash->{$mpa})) { + $pairs=$pPairHash->{$mpa}; + } else { + my $pHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0); + $pairs=$pHash->{$mpa}; + } + + if (exists($ret->{$pairs})) { + my $pa=$ret->{$pairs}; + push(@$pa, $mpa); + } + else { + $ret->{$pairs}=[$mpa]; + } + + #if (exists($pPairHash->{$mpa}))) { delete($pPairHash->{$mpa}); } + } #foreach + } + $table->close(); + } + + + #check BMC/IPMI nodes + $table=xCAT::Table->new("ipmi"); + if ($table) { + my @tmp1=$table->getAllNodeAttribs(['node','bmc']); + if (@tmp1 > 0) { + foreach(@tmp1) { + my $node=$_->{node}; + my $bmc=$_->{bmc}; + if (! exists($pPairHash->{$node})) {next;} + my $pairs=$pPairHash->{$node}; + + if (exists($ret->{$pairs})) { + my $pa=$ret->{$pairs}; + push(@$pa, $node); + } + else { + $ret->{$pairs}=[$node]; + } + + #delete($pPairHash->{$node}); + } #foreach + } + $table->close(); + } + + return $ret; +} diff --git a/xCAT-server/lib/xcat/monitoring/xcatmon.pm b/xCAT-server/lib/xcat/monitoring/xcatmon.pm index b44574039..02183f67e 100644 --- a/xCAT-server/lib/xcat/monitoring/xcatmon.pm +++ b/xCAT-server/lib/xcat/monitoring/xcatmon.pm @@ -6,10 +6,11 @@ BEGIN $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; } use lib "$::XCATROOT/lib/perl"; +use strict; use xCAT::Utils; use xCAT::GlobalDef; use xCAT_monitoring::monitorctrl; - +use Sys::Hostname; 1; @@ -24,16 +25,23 @@ use xCAT_monitoring::monitorctrl; #-------------------------------------------------------------------------------- =head3 start - This function gets called by the monitorctrl module - when xcatd starts. + This function gets called by the monitorctrl module when monstart command + gets called and when xcatd starts. + Arguments: - None. + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: - (return code, message) + (return code, message) + if the callback is set, use callback to display the status and error. + =cut #-------------------------------------------------------------------------------- sub start { - #print "xcatmon.start\n"; + print "xcatmon.start\n"; return (0, "started"); } @@ -42,15 +50,20 @@ sub start { #-------------------------------------------------------------------------------- =head3 stop - This function gets called by the monitorctrl module when - xcatd stops. + This function gets called by the monitorctrl module when monstop command gets called. Arguments: - none + p_nodes -- a pointer to an arrays of nodes to be stoped for monitoring. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: - (return code, message) + (return code, message) + if the callback is set, use callback to display the status and error. =cut #-------------------------------------------------------------------------------- sub stop { + print "xcatmon.stop\n"; return (0, "stopped"); } @@ -78,23 +91,30 @@ sub supportNodeStatusMon { #-------------------------------------------------------------------------------- =head3 startNodeStatusMon - This function is called by the monitorctrl module to tell - the product to start monitoring the node status and feed them back + This function is called by the monitorctrl module when monstart gets called and + when xcatd starts. It starts monitoring the node status and feed them back to xCAT. Arguments: - None. + p_nodes -- a pointer to an arrays of nodes to be monitored. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + note: p_nodes and scope are ignored by this plugin. Returns: - (return code, message) - + (return code, message) + if the callback is set, use callback to display the status and error. =cut #-------------------------------------------------------------------------------- -sub startNodeStatusMon { - my $temp=shift; - if ($temp =~ /xCAT_monitoring::xcatmon/) { - $temp=shift; +sub startNodeStatusMon +{ + print "xcatmon.startNodeStatusMon\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::xcatmon/) { + $noderef=shift; } - - #print "xcatmon.startNodeStatusMon\n"; + my $scope=shift; + my $callback=shift; #run the command first to update the status, my $cmd="$::XCATROOT/sbin/xcatnodemon"; @@ -134,71 +154,112 @@ sub startNodeStatusMon { $newentry="*/$value * * * * XCATROOT=$::XCATROOT PATH=$ENV{'PATH'} XCATCFG='$ENV{'XCATCFG'}' $cmd"; } my ($code, $msg)=xCAT::Utils::add_cron_job($newentry); - if ($code==0) { return (0, "started"); } - else { return ($code, $msg); } + my $localhostname=hostname(); + if ($code==0) { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: started. Refresh interval is $value minute(s)."; + $callback->($rsp); + } + return (0, "started"); } + else { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: $code $msg"; + $callback->($rsp); + } + return ($code, $msg); + } } #-------------------------------------------------------------------------------- =head3 stopNodeStatusMon - This function is called by the monitorctrl module to tell - the product to stop feeding the node status info back to xCAT. - + This function is called by the monitorctrl module when monstop command is issued. + It stops feeding the node status info back to xCAT. Arguments: - none + p_nodes -- a pointer to an arrays of nodes to stoped for monitoring. null means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + note: p_nodes and scope are ignored by this plugin. Returns: - (return code, message) + (return code, message) + if the callback is set, use callback to display the status and error. =cut #-------------------------------------------------------------------------------- sub stopNodeStatusMon { - #TODO: turn off the node status monitoring. + print "xcatmon.stopNodeStatusMon\n"; + my $noderef=shift; + if ($noderef =~ /xCAT_monitoring::xcatmon/) { + $noderef=shift; + } + my $scope=shift; + my $callback=shift; my $job="$::XCATROOT/sbin/xcatnodemon"; my ($code, $msg)=xCAT::Utils::remove_cron_job($job); - if ($code==0) { return (0, "stopped"); } - else { return ($code, $msg); } - + my $localhostname=hostname(); + if ($code==0) { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: stopped."; + $callback->($rsp); + } + return (0, "stopped"); } + else { + if ($callback) { + my $rsp={}; + $rsp->{data}->[0]="$localhostname: $code $msg"; + $callback->($rsp); + } + return ($code, $msg); + } } #-------------------------------------------------------------------------------- -=head3 addNodes - This function is called by the monitorctrl module when new nodes are added - to the xCAT cluster. It should add the nodes into the product for monitoring. +=head3 config + This function configures the cluster for the given nodes. + This function is called by when monconfig command is issued or when xcatd starts + on the service node. It will configure the cluster to include the given nodes within + the monitoring doamin. Arguments: - nodes --nodes to be added. It is a pointer to an array. If the next argument is - 1, each element is a ref to an array of [nodes, status]. For example: - [['node1', 'active'], ['node2', 'booting']..]. - if the next argument is 0, each element is a node name to be added. - boolean -- 1, or 0. + p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: (error code, error message) =cut #-------------------------------------------------------------------------------- -sub addNodes { +sub config { - #print "xcatmon:addNodes called\n"; + print "xcatmon:config called\n"; return (0, "ok"); } #-------------------------------------------------------------------------------- -=head3 removeNodes +=head3 deconfig + This function de-configures the cluster for the given nodes. This function is called by the monitorctrl module when nodes are removed from the xCAT cluster. It should remove the nodes from the product for monitoring. Arguments: - nodes --nodes to be added. It is a pointer to an array. If the next argument is - 1, each element is a ref to an array of [nodes, status]. For example: - [['node1', 'active'], ['node2', 'booting']..]. - if the next argument is 0, each element is a node name to be added. - boolean -- 1, or 0. + p_nodes -- a pointer to an arrays of nodes to be removed for monitoring. none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. Returns: (error code, error message) =cut #-------------------------------------------------------------------------------- -sub removeNodes { +sub deconfig { - #print "xcatmon:removeNodes called\n"; + print "xcatmon:deconfig called\n"; return (0, "ok"); } @@ -216,7 +277,7 @@ sub removeNodes { =cut #-------------------------------------------------------------------------------- sub getMonNodesStatus { - %status=(); + my %status=(); my @inactive_nodes=(); my @active_nodes=(); my @unknown_nodes=(); @@ -262,9 +323,8 @@ sub getMonNodesStatus { #-------------------------------------------------------------------------------- -=head3 processNodeStatusChanges - This function will update the status column of the - nodelist table with the new node status. +=head3 setNodeStatusAttributes + This function will update the status column of the nodelist table with the new node status. Arguments: status -- a hash pointer of the node status. A key is a status string. The value is an array pointer of nodes that have the same status. @@ -274,12 +334,12 @@ sub getMonNodesStatus { non-0 for not successful. =cut #-------------------------------------------------------------------------------- -sub processNodeStatusChanges { +sub setNodeStatusAttributes { my $temp=shift; if ($temp =~ /xCAT_monitoring::xcatmon/) { $temp=shift; } - return xCAT_monitoring::monitorctrl->processNodeStatusChanges($temp); + return xCAT_monitoring::monitorctrl->setNodeStatusAttributes($temp); } #-------------------------------------------------------------------------------- @@ -295,8 +355,8 @@ sub processNodeStatusChanges { #-------------------------------------------------------------------------------- sub processSettingChanges { #restart the cron job - xCAT_monitoring::xcatmon->stopNodeStatusMon(); - xCAT_monitoring::xcatmon->startNodeStatusMon(); + xCAT_monitoring::xcatmon->stopNodeStatusMon([], 0); + xCAT_monitoring::xcatmon->startNodeStatusMon([], 0); } #-------------------------------------------------------------------------------- diff --git a/xCAT-server/lib/xcat/plugins/aixinstall.pm b/xCAT-server/lib/xcat/plugins/aixinstall.pm index 6b03b3b3b..674caf916 100644 --- a/xCAT-server/lib/xcat/plugins/aixinstall.pm +++ b/xCAT-server/lib/xcat/plugins/aixinstall.pm @@ -144,18 +144,6 @@ sub process_request } my $errored = 0; -sub pass_along { - my $resp = shift; - $::callback->($resp); - if ($resp and ($resp->{errorcode} and $resp->{errorcode}->[0]) or ($resp->{error} and $resp->{error}->[0])) { - $errored=1; - } - foreach (@{$resp->{node}}) { - if ($_->{error} or $_->{errorcode}) { - $errored=1; - } - } -} #---------------------------------------------------------------------------- @@ -539,16 +527,7 @@ ll~; my $rsp; push @{$rsp->{data}}, "AIX/NIM nodes were initialized.\n"; xCAT::MsgUtils->message("I", $rsp, $callback); - ################### - #give monitoring code a chance to prepare the master for the node deployment - #push @{$rsp->{data}}, "Initializing for the node monitoring.\n"; - #xCAT::MsgUtils->message("I", $rsp, $callback); - my %new_request = ( - command => ['moncfgmaster'], - node => \@nodelist - ); - $sub_req->(\%new_request, \&pass_along); - ################### + return 0; } return 0; @@ -3003,16 +2982,7 @@ ll~; my $rsp; push @{$rsp->{data}}, "AIX/NIM diskless nodes were initialized.\n"; xCAT::MsgUtils->message("I", $rsp, $callback); - ################# - #give monitoring code a chance to prepare the master for the node deployment - #push @{$rsp->{data}}, "Initializing for the node monitoring.\n"; - #xCAT::MsgUtils->message("I", $rsp, $callback); - my %new_request = ( - command => ['moncfgmaster'], - node => \@nodelist - ); - $sub_req->(\%new_request, \&pass_along); - ################# + return 0; } } diff --git a/xCAT-server/lib/xcat/plugins/monctrlcmds.pm b/xCAT-server/lib/xcat/plugins/monctrlcmds.pm index 3d074504b..aef345422 100644 --- a/xCAT-server/lib/xcat/plugins/monctrlcmds.pm +++ b/xCAT-server/lib/xcat/plugins/monctrlcmds.pm @@ -6,14 +6,14 @@ BEGIN $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; } use lib "$::XCATROOT/lib/perl"; - +use strict; use xCAT::NodeRange; use xCAT::Table; use xCAT::MsgUtils; use xCAT_monitoring::monitorctrl; use xCAT::Utils; +use Sys::Hostname; -my $callback; 1; @@ -41,11 +41,11 @@ sub handled_commands { return { monstart => "monctrlcmds", monstop => "monctrlcmds", - monupdate => "monctrlcmds", monls => "monctrlcmds", - monaddnode => "monctrlcmds", - monrmnode => "monctrlcmds", - moncfgmaster => "monctrlcmds", + monadd => "monctrlcmds", + monrm => "monctrlcmds", + moncfg => "monctrlcmds", + mondecfg => "monctrlcmds", } } @@ -59,53 +59,84 @@ sub handled_commands { sub preprocess_request { my $req = shift; - my $cb = shift; + my $callback = shift; my $command = $req->{command}->[0]; if ($req->{_xcatdest}) { return [$req]; } #exit if preprocessed + my $args=$req->{arg}; my @requests=(); - if ($command ne "moncfgmaster") { + + if (($command eq "monstart") || ($command eq "monstop") || ($command eq "moncfg") || ($command eq "mondecfg") ) { + my @a_ret; #(0, $modulename, $nodestatutmon, $scope, \@nodes) + if ($command eq "monstart") { + @a_ret=preprocess_monstart($args, $callback); + } elsif ($command eq "monstop") { + @a_ret=preprocess_monstop($args, $callback); + } elsif ($command eq "moncfg") { + @a_ret=preprocess_moncfg($args, $callback); + } else { + @a_ret=preprocess_mondecfg($args, $callback); + } + + if ($a_ret[0] != 0) { + $req = {}; + return; + } else { + my $allnodes=$a_ret[4]; + print "allnodes=@$allnodes\n"; + my $pname=$a_ret[1]; + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + my $module_name="xCAT_monitoring::$pname"; + undef $SIG{CHLD}; + #initialize and start monitoring + no strict "refs"; + my $mon_hierachy; + if (defined(${$module_name."::"}{getNodesMonServers})) { + $mon_hierachy = ${$module_name."::"}{getNodesMonServers}->($allnodes, $callback); + } else { + $mon_hierachy=xCAT_monitoring::monitorctrl->getNodeMonServerPair($allnodes, 1); + } + + my @mon_servers=keys(%$mon_hierachy); + my @hostinfo=xCAT::Utils->determinehostname(); + #print "hostinfo=@hostinfo\n"; + my $isSV=xCAT::Utils->isServiceNode(); + my %iphash=(); + foreach(@hostinfo) {$iphash{$_}=1;} + if (!$isSV) { $iphash{'noservicenode'}=1;} + + foreach (@mon_servers) { + #service node come in pairs, the first one is the monserver adapter that facing the mn, + # the second one is facing the cn. we use the first one here + my @server_pair=split(',', $_); + my $sv=$server_pair[0]; + my $mon_nodes=$mon_hierachy->{$_}; + if ((!$mon_nodes) || (@$mon_nodes ==0)) { next; } + print "sv=$sv, nodes=@$mon_nodes\n"; + + my $reqcopy = {%$req}; + if (! $iphash{$sv}) { + if ($isSV) { next; } #if the command is issued on the monserver, + # only handle its children. + $reqcopy->{'_xcatdest'}=$sv; + my $rsp2={}; + $rsp2->{data}->[0]="sending request to $sv..."; + $callback->($rsp2); + } + + push @{$reqcopy->{module}}, $a_ret[1]; + push @{$reqcopy->{nodestatmon}}, $a_ret[2]; + push @{$reqcopy->{scope}}, $a_ret[3]; + push @{$reqcopy->{nodeinfo}}, join(',', @$mon_nodes); + push @requests, $reqcopy; + } + } + } else { my $reqcopy = {%$req}; push @requests, $reqcopy; - } else { - if (! xCAT_monitoring::monitorctrl->shouldConfigMaster()) { - $req = {}; - return; - } + } - my $nodes = $req->{node}; - my $noderef=xCAT_monitoring::monitorctrl->getMonServer($nodes); - - #the identification of this node - my @hostinfo=xCAT::Utils->determinehostname(); - my $isSV=xCAT::Utils->isServiceNode(); - %iphash=(); - foreach(@hostinfo) {$iphash{$_}=1;} - if (!$isSV) { $iphash{'noservicenode'}=1;} - - foreach my $key (keys (%$noderef)) { - my @key_a=split(',', $key); - my $mon_nodes=$noderef->{$key}; - @nodes_to_add=(); - if ($mon_nodes) { - foreach(@$mon_nodes) { - my $node=$_->[0]; - push(@nodes_to_add, $node); - } - } - if ($iphash{$key_a[0]}) { #current node is the master for the nodes - my $reqcopy = {%$req}; - $reqcopy->{node}=\@nodes_to_add; - push @requests, $reqcopy; - } else { #push the request to the monitoring server - my $reqcopy = {%$req}; - $reqcopy->{node}=\@nodes_to_add; - $reqcopy->{'_xcatdest'} = $key_a[0]; - push @requests, $reqcopy; - } - } - } return \@requests; } @@ -114,9 +145,8 @@ sub preprocess_request =head3 process_request It processes the monitoring control commands. Arguments: - request -- a hash table which contains the command name. + request -- a hash table which contains the command name and the arguments. callback -- a callback pointer to return the response to. - args -- a list of arguments that come with the command. Returns: 0 for success. The output is returned through the callback pointer. 1. for unsuccess. The error messages are returns through the callback pointer. @@ -128,439 +158,415 @@ sub process_request { Getopt::Long::Configure("bundling") ; $Getopt::Long::ignorecase=0; + #print "process_request get called\n"; my $request = shift; - $callback = shift; + my $callback = shift; my $command = $request->{command}->[0]; my $args=$request->{arg}; my $doreq = shift; if ($command eq "monstart") { - my ($ret, $msg) = monstart($args, $callback, $doreq); - if ($msg) { - my %rsp=(); - $rsp->{dara}->[0]= $msg; - $callback->($rsp); - } - return $ret; + return monstart($request, $callback, $doreq); } elsif ($command eq "monstop") { - my ($ret, $msg) = monstop($args, $callback, $doreq); - if ($msg) { - my %rsp=(); - $rsp->{data}->[0]= $msg; - $callback->($rsp); - } - return $ret; + return monstop($request, $callback, $doreq); } - elsif ($command eq "monupdate") { - xCAT_monitoring::monitorctrl::sendMonSignal(); - } elsif ($command eq "monls") { - my ($ret, $msg) = monls($args, $callback); - if ($msg) { - my %rsp=(); - $rsp->{data}->[0]= $msg; - $callback->($rsp); - } - return $ret; + return monls($request, $callback, $doreq); + } - elsif ($command eq "monaddnode") { - my ($ret, $msg) = monaddnode($args, $callback); - if ($msg) { - my %rsp=(); - $rsp->{data}->[0]= $msg; - $callback->($rsp); - } - return $ret; + elsif ($command eq "monadd") { + return monadd($request, $callback, $doreq); } - elsif ($command eq "monrmnode") { - my ($ret, $msg) = monrmnode($args, $callback); - if ($msg) { - my %rsp=(); - $rsp->{data}->[0]= $msg; - $callback->($rsp); - } - return $ret; + elsif ($command eq "monrm") { + return monrm($request, $callback, $doreq); } - elsif ($command eq "moncfgmaster") { - my $nodes = $request->{node}; - if ($nodes) { - my ($ret, $msg) = moncfgmaster($nodes, $callback); - if ($msg) { - my %rsp=(); - $rsp->{data}->[0]= $msg; - $callback->($rsp); - } - return $ret; - } else { - my %rsp=(); - $rsp->{data}->[0]= "This command requires noderange."; - $callback->($rsp); - return 1; - } + elsif ($command eq "moncfg") { + return moncfg($request, $callback, $doreq); } - else { - my %rsp=(); + elsif ($command eq "mondecfg") { + return mondecfg($request, $callback, $doreq); + } else { + my $rsp={}; $rsp->{data}->[0]= "unsupported command: $command."; $callback->($rsp); return 1; } } -sub take_answer { - my $resp = shift; - $callback->($resp); -} - #-------------------------------------------------------------------------------- -=head3 monstart - This function registers the given monitoring plug-in to the 'monitoring' table. - xCAT will invoke the monitoring plug-in to start the 3rd party software, which - this plug-in connects to, to monitor the xCAT cluster. +=head3 preprocess_monstart + This function handles the syntax checking for monstart command, + turn on the given monitoring plug-in to the 'monitoring' table. Arguments: callback - the pointer to the callback function. args - The format of the args is: [-h|--help|-v|--version] or - name [-n|--nodestatmon] [-s|--settings ...] + name [noderange] [-r|--remote] where name is the monitoring plug-in name. For example: rmcmon. - The specified plug-in will be registered and invoked - for monitoring the xCAT cluster. - -n|--nodestatmon indicates that this plug-in will be used for feeding the node liveness - status to the xCAT nodelist table. If not specified, the plug-in will not be used - for feeding node status to xCAT. - -s|--settings settings are used by the plug-in to customize it behavor. + The specified plug-in will be invoked for monitoring the xCAT cluster. + noderange a range of nodes to be monitored. Default is all. + -r|--remote indicates that both monservers and the nodes need to be called to start + the monitoring. The defaults is monservers only. Returns: - 0 for success. The output is returned through the callback pointer. - 1. for unsuccess. The error messages are returns through the callback pointer. + (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the + actions. 1 means monervers only, 2 means both nodes and monservers. + (1, "") for unsuccess. The error messages are returns through the callback pointer. =cut #-------------------------------------------------------------------------------- -sub monstart { +sub preprocess_monstart +{ my $args=shift; my $callback=shift; - my $doreq = shift; - my $VERSION; - my $HELP; if (xCAT::Utils->isServiceNode()) { - my %rsp=(); + my $rsp={}; $rsp->{data}->[0]= "This command is not supported on a service node."; $callback->($rsp); - return 0; + return (1, ""); } - # subroutine to display the usage sub monstart_usage { - my %rsp; + my $cb=shift; + my $rsp={}; $rsp->{data}->[0]= "Usage:"; - $rsp->{data}->[1]= " monstart name [-n|--nodestatmon] [-s|--settings settings]"; + $rsp->{data}->[1]= " monstart name [noderange] [-r|--remote]"; $rsp->{data}->[2]= " monstart [-h|--help|-v|--version]"; - $rsp->{data}->[3]= " name is the name of the monitoring plug-in module to be registered and invoked."; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module to be invoked."; $rsp->{data}->[4]= " Use 'monls -a' command to list all the monitoring plug-in names."; - $rsp->{data}->[5]= " settings is used by the monitoring plug-in to customize its behavior."; - $rsp->{data}->[6]= " Format: [key1=value1],[key2=value2]... "; - $rsp->{data}->[7]= " Please note that the square brackets are needed. "; - $rsp->{data}->[7]= " Use 'monls name -d' command to look for the possible settings for a plug-in."; - $rsp->{data}->[8]= " Example: monstart xcatmon -n -s [ping-interval=10]"; - $callback->($rsp); + $rsp->{data}->[5]= " noderange is a range of nodes to be monitored. The default is all nodes."; + $rsp->{data}->[6]= " -r|--remote indicates that both monservers and the nodes need to be called\n to start the monitoring. The default is monservers only."; + $cb->($rsp); } - @ARGV=@{$args}; + @ARGV=(); + if ($args) { @ARGV=@{$args};} + my $settings; # parse the options if(!GetOptions( 'h|help' => \$::HELP, 'v|version' => \$::VERSION, - 'n|nodestatmon' => \$::NODESTATMON, - 's|settings=s' => \$settings)) + 'r|remote' => \$::REMOTE,)) { - &monstart_usage; - return; + &monstart_usage($callback); + return (1, ""); } # display the usage if -h or --help is specified if ($::HELP) { - &monstart_usage; - return; + &monstart_usage($callback); + return 1; + } + # display the version statement if -v or --verison is specified + if ($::VERSION) + { + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version(); + $callback->($rsp); + return (1, ""); + } + + my $pname=""; + my $scope=0; #set it to 0 instead of 1 because it will be distributed to monservers. + my @nodes=(); + my $nodestatmon=0; + + if ($::REMOTE) { $scope=2; } + + if (@ARGV < 1) + { + &monstart_usage($callback); + return (1, ""); + } + else { + #@product_names=split(/,/, $ARGV[0]); + $pname=$ARGV[0]; + if (@ARGV > 1) { + my $noderange=$ARGV[1]; + @nodes = noderange($noderange); + if (nodesmissed) { + my $rsp={}; + $rsp->{data}->[0]= "Invalid nodes in noderange:".join(',',nodesmissed); + $callback->($rsp); + return (1, ""); + } + } + + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + if (!-e $file_name) { + my $rsp={}; + $rsp->{data}->[0]="File $file_name does not exist."; + $callback->($rsp); + return (1, ""); + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + my $rsp={}; + $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; + $callback->($rsp); + return (1, ""); + } + } + } + my $table=xCAT::Table->new("monitoring", -create => 1,-autocommit => 1); + if ($table) { + my $found=0; + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + if ($pname eq $_->{name}) { + $found=1; + if ($_->{disable} !~ /0|NO|No|no|N|n/) { + my %key_col = (name=>$pname); + my %tb_cols=(disable=>"0"); + $table->setAttribs(\%key_col, \%tb_cols); + } + if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon=1;} + last; + } + } + } + + if (!$found) { + my $rsp={}; + $rsp->{data}->[0]="$pname has not been added to the monitoring table. Please run 'monadd' command to add."; + $callback->($rsp); + $table->close(); + return (1, ""); + } + + $table->close(); + } else { + my $rsp={}; + $rsp->{data}->[0]="Failed to open the monitoring table."; + $callback->($rsp); + return (1, ""); + } + + return (0, $pname, $nodestatmon, $scope, \@nodes); +} + +#-------------------------------------------------------------------------------- +=head3 monstart + This function calls moniutoring control to start the monitoring and node + status monitoring for the given plug-in module. + Arguments: + request -- pointer to a hash with keys are command, module and nodestatmon. + callback - the pointer to the callback function. + Returns: + 0 for success. The output is returned through the callback pointer. + 1. for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub monstart { + my $request=shift; + my $callback=shift; + + my $pname=$request->{module}->[0]; + my $nodestatmon=$request->{nodestatmon}->[0]; + my $scope=$request->{scope}->[0]; + my $nodeinfo=$request->{nodeinfo}->[0]; + + my @nodes=split(',', $nodeinfo); + print "monstart get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=$nodeinfo\nscope=$scope\n"; + + xCAT_monitoring::monitorctrl->startMonitoring([$pname], \@nodes, $scope, $callback); + + if ($nodestatmon) { + xCAT_monitoring::monitorctrl->startNodeStatusMonitoring($pname, \@nodes, $scope, $callback); + } + return; +} + +#-------------------------------------------------------------------------------- +=head3 preprocess_monstop + This function unregisters the given monitoring plug-in from the 'monitoring' table. + Arguments: + callback - the pointer to the callback function. + args - The format of the args is: + [-h|--help|-v|--version] or + name [noderange] [-r|--remote] + name + where + name is the monitoring plug-in name. For example: rmcmon. + The specified plug-in will be stoped for monitoring the xCAT cluster. + noderange a range of nodes. Default is all. + -r|--remote indicates that both monservers and the nodes need to be called to stop + the monitoring. The defaults is monservers only. + Returns: + (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the + actions. 1 means monervers only, 2 means both nodes and monservers. + (1, "") for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub preprocess_monstop +{ + my $args=shift; + my $callback=shift; + + if (xCAT::Utils->isServiceNode()) { + my $rsp={}; + $rsp->{data}->[0]= "This command is not supported on a service node."; + $callback->($rsp); + return (1, ""); + } + + # subroutine to display the usage + sub monstop_usage + { + my $cb=shift; + my $rsp={}; + $rsp->{data}->[0]= "Usage:"; + $rsp->{data}->[1]= " monstop name [noderange] [-r|--remote]"; + $rsp->{data}->[2]= " monstop [-h|--help|-v|--version]"; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module registered in the monitoring table."; + $cb->($rsp); + } + + @ARGV=(); + if ($args) { @ARGV=@{$args};} + + # parse the options + if(!GetOptions( + 'h|help' => \$::HELP, + 'r|remote' => \$::REMOTE, + 'v|version' => \$::VERSION,)) + { + &monstop_usage($callback); + return (1, ""); + } + + # display the usage if -h or --help is specified + if ($::HELP) { + &monstop_usage($callback); + return (1, ""); } # display the version statement if -v or --verison is specified if ($::VERSION) { - my %rsp; - $rsp->{data}->[0]= "monstart version 1.0"; + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version();; $callback->($rsp); - return; + return (1, ""); } - #my @product_names; - my $pname; + my $pname=""; + my $scope=0; + my @nodes=(); + my $nodestatmon=0; + + if ($::REMOTE) { $scope=2;} + if (@ARGV < 1) { - &monstart_usage; - return; + &monstop_usage($callback); + return (1, ""); } else { - #@product_names=split(/,/, $ARGV[0]); $pname=$ARGV[0]; - $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; - if (!-e $file_name) { - my %rsp; - $rsp->{data}->[0]="File $file_name does not exist."; + if (@ARGV > 1) { + my $noderange=$ARGV[1]; + @nodes = noderange($noderange); + if (nodesmissed) { + my $rsp={}; + $rsp->{data}->[0]= "Invalid nodes in noderange:".join(',',nodesmissed); $callback->($rsp); - return 1; - } else { - #load the module in memory - eval {require($file_name)}; - if ($@) { - my %rsp; - $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; - $callback->($rsp); - return 1; - } + return (1, ""); } + } + + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + if (!-e $file_name) { + my $rsp={}; + $rsp->{data}->[0]="File $file_name does not exist."; + $callback->($rsp); + return (1, ""); + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + my $rsp={}; + $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; + $callback->($rsp); + return (1, ""); + } + } } - - #my %ret = xCAT_monitoring::monitorctrl::startmonitoring(@product_names); - - #my %rsp; - #$rsp->{data}->[0]= "starting @product_names"; - #my $i=1; - #foreach (keys %ret) { - # my $ret_array=$ret{$_}; - # $rsp->{data}->[$i++]= "$_: $ret_array->[1]"; - #} - - #my $nodestatmon=xCAT_monitoring::monitorctrl::nodeStatMonName(); - #if ($nodestatmon) { - # foreach (@product_names) { - # if ($_ eq $nodestatmon) { - # my ($code, $msg)=xCAT_monitoring::monitorctrl::startNodeStatusMonitoring($nodestatmon); - # $rsp->{data}->[$i++]="node status monitoring with $nodestatmon: $msg"; - # } - # } - #} - my $table=xCAT::Table->new("monitoring", -create => 1,-autocommit => 1); if ($table) { - (my $ref) = $table->getAttribs({name => $pname}, name); - if ($ref and $ref->{name}) { - my %rsp; - $rsp->{data}->[0]="$pname has already been activated for monitoring."; - $callback->($rsp); + my $found=0; + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + if ($pname eq $_->{name}) { + $found=1; + if ($_->{disable} =~ /0|NO|No|no|N|n/) { + my %key_col = (name=>$pname); + my %tb_cols=(disable=>"1"); + $table->setAttribs(\%key_col, \%tb_cols); + } + if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon=1;} + last; + } + } + } + + if (!$found) { + my $rsp={}; + $rsp->{data}->[0]="$pname cannot be found in the monitoring table."; + $callback->($rsp); + $table->close(); + return (1, ""); } - else { - #update the monsetting table - if ($settings) { - my $table1=xCAT::Table->new("monsetting", -create => 1,-autocommit => 1); - my %key_col1 = (name=>$pname); - #parse the settings. Setting format: key="value",key="value".... - while ($settings =~ s/^\[([^\[\]\=]*)=([^\[\]]*)\](,)*//) { - $key_col1{key}=$1; - $setting_hash{value}=$2; - $table1->setAttribs(\%key_col1, \%setting_hash); - } - $table1->close(); - } - #update the monitoring table - my %key_col = (name=>$pname); - my $nstat='N'; - if ($::NODESTATMON) { - $nstat='Y'; - } - my %tb_cols=(nodestatmon=>$nstat, disable=>"0"); - $table->setAttribs(\%key_col, \%tb_cols); - } $table->close(); + } else { + my $rsp={}; + $rsp->{data}->[0]="Failed to open the monitoring table."; + $callback->($rsp); + return (1, ""); } - #tell the service node to start monitoring too - my $mon_hierachy=xCAT_monitoring::monitorctrl->getMonHierarchy(); - my @mon_servers=keys(%$mon_hierachy); - my @hostinfo=xCAT::Utils->determinehostname(); - #print "hostinfo=@hostinfo\n"; - %iphash=(); - foreach(@hostinfo) {$iphash{$_}=1;} - foreach (@mon_servers) { - #service node come in pairs, the first one is the monserver adapter that facing the mn, - # the second one is facing the cn. we use the first one here - my @server_pair=split(',', $_); - my $sv=$server_pair[0]; - if (! $iphash{$sv} && ($sv ne "noservicenode")) { #if it is not this node, meaning it is ms - my %rsp2; - $rsp2->{data}->[0]="sending request to $sv..."; - $callback->($rsp2); -# my $result=`psh --nonodecheck $_ monupdate 2>1&`; -# if ($result) { -# $rsp2->{data}->[0]="$result"; -# $callback->($rsp2); -# } - my %req=(); - push @{$req{command}}, "monupdate"; - $req{'_xcatdest'}=$sv; - $doreq->(\%req,\&take_answer); - } - } - - my %rsp1; - $rsp1->{data}->[0]="done."; - $callback->($rsp1); - - return; + return (0, $pname, $nodestatmon, $scope, \@nodes); } #-------------------------------------------------------------------------------- =head3 monstop - This function unregisters the given monitoring plug-in from the 'monitoring' table. - xCAT will ask the monitoring plug-in to stop the 3rd party software, which - this plug-in connects to, to monitor the xCAT cluster. + This function calls moniutoring control to stop the monitoring and node + status monitoring for the given plug-in module. Arguments: + request -- pointer to a hash with keys are command, module and nodestatmon. callback - the pointer to the callback function. - args - The format of the args is: - [-h|--help|-v|--version] or - name - where - name is the monitoring plug-in name. For example: rmcmon. - The specified plug-in will be un-registered and stoped - for monitoring the xCAT cluster. Returns: 0 for success. The output is returned through the callback pointer. 1. for unsuccess. The error messages are returns through the callback pointer. =cut #-------------------------------------------------------------------------------- sub monstop { - my $args=shift; + my $request=shift; my $callback=shift; - my $doreq = shift; - my $VERSION; - my $HELP; - - if (xCAT::Utils->isServiceNode()) { - my %rsp=(); - $rsp->{data}->[0]= "This command is not supported on a service node."; - $callback->($rsp); - return 0; - } - - # subroutine to display the usage - sub monstop_usage - { - my %rsp; - $rsp->{data}->[0]= "Usage:"; - $rsp->{data}->[1]= " monstop name"; - $rsp->{data}->[2]= " monstop [-h|--help|-v|--version]"; - $rsp->{data}->[3]= " name is the name of the monitoring plug-in module registered in the monitoring table."; - $callback->($rsp); - } - - @ARGV=@{$args}; - # parse the options - if(!GetOptions( - 'h|help' => \$::HELP, - 'v|version' => \$::VERSION,)) - { - &monstop_usage; - return; - } - - # display the usage if -h or --help is specified - if ($::HELP) { - &monstop_usage; - return; - } - - # display the version statement if -v or --verison is specified - if ($::VERSION) - { - my %rsp; - $rsp->{data}->[0]= "monstop version 1.0"; - $callback->($rsp); - return; - } - - - #my @product_names; - my $pname; - if (@ARGV < 1) - { - &monstop_usage; - return; - } - else { - #@product_names=split(/,/, $ARGV[0]); - $pname=$ARGV[0]; - } - - #my %ret = xCAT_monitoring::monitorctrl::stopMonitoring(@product_names); - #my %rsp; - #$rsp->{data}->[0]= "stopping @product_names"; - #my $i=1; - #foreach (keys %ret) { - # my $ret_array=$ret{$_}; - # $rsp->{data}->[$i++]= "$_: $ret_array->[1]"; - #} - - #my $nodestatmon=xCAT_monitoring::monitorctrl::nodeStatMonName(); - #if ($nodestatmon) { - # foreach (@product_names) { - # if ($_ eq $nodestatmon) { - # my ($code, $msg)=xCAT_monitoring::monitorctrl::stopNodeStatusMonitoring($nodestatmon); - # $rsp->{data}->[$i++]="node status monitoring with $nodestatmon: $msg"; - # } - # } - #} - my $table=xCAT::Table->new("monitoring", -create => 1,-autocommit => 1); - if ($table) { - (my $ref) = $table->getAttribs({name => $pname}, name); - if ($ref and $ref->{name}) { - my %key_col = (name=>$pname); - my %tb_cols=(disable=>"1"); - $table->setAttribs(\%key_col, \%tb_cols); - } - else { - my %rsp; - $rsp->{data}->[0]="$pname was not registered or not activated."; - $callback->($rsp); - } - $table->close(); - } - - #tell all the service nodes to stop monitoring too - my $mon_hierachy=xCAT_monitoring::monitorctrl->getMonHierarchy(); - my @mon_servers=keys(%$mon_hierachy); - my @hostinfo=xCAT::Utils->determinehostname(); - %iphash=(); - foreach(@hostinfo) {$iphash{$_}=1;} - foreach (@mon_servers) { - #service node come in pairs, the first one is the monserver adapter that facing the mn, - # the second one is facing the cn. we use the first one here - my @server_pair=split(',', $_); - my $sv=$server_pair[0]; - if (! $iphash{$sv} && ($sv ne "noservicenode")) { #if it is not this node, meaning it is ms - my %rsp2; - $rsp2->{data}->[0]="sending request to $sv..."; - $callback->($rsp2); - # my $result=`psh --nonodecheck $_ monupdate 2>1&`; - # if ($result) { - # $rsp2->{data}->[0]="$result"; - # $callback->($rsp2); - #} - my %req=(); - push @{$req{command}}, "monupdate"; - $req{'_xcatdest'}=$sv; - $doreq->(\%req,\&take_answer); - } - } - - my %rsp1; - $rsp1->{data}->[0]="done."; - $callback->($rsp1); + my $pname=$request->{module}->[0]; + my $nodestatmon=$request->{nodestatmon}->[0]; + my $scope=$request->{scope}->[0]; + my $nodeinfo=$request->{nodeinfo}->[0]; + + my @nodes=split(',', $nodeinfo); + print "monstop get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n"; + + xCAT_monitoring::monitorctrl->stopMonitoring([$pname], \@nodes, $scope, $callback); + + if ($nodestatmon) { + xCAT_monitoring::monitorctrl->stopNodeStatusMonitoring($pname, \@nodes, $scope, $callback); + } return; } @@ -579,24 +585,28 @@ sub monstop { =cut #-------------------------------------------------------------------------------- sub monls { - my $args=shift; - my $callback=shift; - my $VERSION; - my $HELP; + my $request = shift; + my $callback = shift; + my $args=$request->{arg}; + my $doreq = shift; # subroutine to display the usage sub monls_usage { - my %rsp; + my $cb=shift; + my $rsp={}; $rsp->{data}->[0]= "Usage:"; $rsp->{data}->[1]= " monls name [-d|--description]"; $rsp->{data}->[2]= " monls [-a|--all] [-d|--description]"; $rsp->{data}->[3]= " monls [-h|--help|-v|--version]"; $rsp->{data}->[4]= " name is the name of the monitoring plug-in module."; - $callback->($rsp); + $cb->($rsp); } - @ARGV=@{$args}; + @ARGV=(); + if ($args) { + @ARGV=@{$args}; + } # parse the options if(!GetOptions( @@ -605,31 +615,31 @@ sub monls { 'a|all' => \$::ALL, 'd|discription' => \$::DESC)) { - &monls_usage; + &monls_usage($callback); return; } # display the usage if -h or --help is specified if ($::HELP) { - &monls_usage; + &monls_usage($callback); return; } # display the version statement if -v or --verison is specified if ($::VERSION) { - my %rsp; - $rsp->{data}->[0]= "monls version 1.0"; + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version(); $callback->($rsp); return; } + my $usetab=0; my %names=(); my $plugin_dir="$::XCATROOT/lib/perl/xCAT_monitoring"; - my $usetab=0; if (@ARGV > 0) { - $names{$ARGV[0]}=0; + $names{$ARGV[0]}=0; } else { if ($::ALL) { @@ -657,27 +667,31 @@ sub monls { my $pname=$_->{name}; if (($usetab) || exists($names{$pname})) { $names{$pname}=1; + #find out the monitoring plugin file and module name for the product + my $rsp={}; + + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + my $module_name="xCAT_monitoring::$pname"; + #load the module in memory + eval {require($file_name)}; + if ($@) { + $rsp->{data}->[0]="$pname: The file $file_name cannot be located or has compiling errors."; + $callback->($rsp); + next; + } else { + no strict "refs"; + if (! defined(${$module_name."::"}{start})) { next; } + } + my $monnode=0; my $disable=1; if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $monnode=1; } if ($_->{disable} =~ /0|NO|No|no|N|n/) { $disable=0; } - my %rsp; + if ($disable) { $monnode=0; } $rsp->{data}->[0]="$pname\t\t". ($disable ? "not-monitored" : "monitored") . ($monnode ? "\tnode-status-monitored" : ""); - if ($::DESC) { - #find out the monitoring plugin file and module name for the product - my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; - my $module_name="xCAT_monitoring::$pname"; - #load the module in memory - eval {require($file_name)}; - if ($@) { - $rsp->{data}->[1]=" Description:\n not available. The file $file_name cannot be located or has compiling errors."; - } - else { - $rsp->{data}->[1]=${$module_name."::"}{getDescription}->() . "\n"; - } - } + if ($::DESC) { getModuleDescription($rsp, $module_name); } $callback->($rsp); } } #foreach @@ -689,21 +703,25 @@ sub monls { #now handle the ones that are not in the table foreach(keys(%names)) { my $pname=$_; - if ($names{$pname}==0) { - my %rsp; + if (! $names{$pname}) { + my $rsp={}; + #find out the monitoring plugin file and module name for the product + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + my $module_name="xCAT_monitoring::$pname"; + #load the module in memory + eval {require($file_name)}; + if ($@) { + $rsp->{data}->[0]="$pname: The file $file_name cannot be located or has compiling errors."; + $callback->($rsp); + next; + } else { + no strict "refs"; + if (! defined(${$module_name."::"}{start})) { next; } + } $rsp->{data}->[0]="$pname\t\tnot-monitored"; + if ($::DESC) { - #find out the monitoring plugin file and module name for the product - my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; - my $module_name="xCAT_monitoring::$pname"; - #load the module in memory - eval {require($file_name)}; - if ($@) { - $rsp->{data}->[1]=" Description:\n not available. The file $file_name cannot be located or has compiling errors."; - } - else { - $rsp->{data}->[1]=${$module_name."::"}{getDescription}->(). "\n"; - } + getModuleDescription($rsp, $module_name); } $callback->($rsp); } @@ -713,226 +731,818 @@ sub monls { #-------------------------------------------------------------------------------- -=head3 monaddnode - This function informs all the active monitoring plug-ins to add the given - nodes to their monitoring domain +=head3 getModuleDescription + This function gets description, postscripts and other info from the + the given monitoring plug_in and stored it in the given hash. Arguments: + Returns: + 0 for success. + 1. for unsuccess. +=cut +#-------------------------------------------------------------------------------- +sub getModuleDescription { + my $rsp=shift; + my $module_name=shift; + no strict "refs"; + #description + if (defined(${$module_name."::"}{getDescription})) { + $rsp->{data}->[1]=${$module_name."::"}{getDescription}->(); + } else { + $rsp->{data}->[1]=" No description available."; + } + + #postscripts + $rsp->{data}->[2] = " Postscripts:\n"; + if (defined(${$module_name."::"}{getPostscripts})) { + my $desc=${$module_name."::"}{getPostscripts}->(); + my @pn=keys(%$desc); + + if (@pn>0) { + foreach my $group (@pn) { + $rsp->{data}->[2] .= " $group: " . $desc->{$group}; + } + } else { $rsp->{data}->[2] .= " None";} + } else { $rsp->{data}->[2] .= " None";} + + #support node status monitoring + $rsp->{data}->[3] = " Support node status monitoring:\n"; + my $snodestatusmon=0; + if (defined(${$module_name."::"}{supportNodeStatusMon})) { + $snodestatusmon=${$module_name."::"}{supportNodeStatusMon}->(); + } + if ($snodestatusmon) { $rsp->{data}->[3] .= " Yes\n";} + else { $rsp->{data}->[3] .= " No\n"; } + return 0; +} + +#-------------------------------------------------------------------------------- +=head3 monadd + This function adds the given module name into the monitoring table and + sets the postsctipts in the postsctipts table. It also sets the given + settings into the monsetting table. + Arguments: + request -- a hash table which contains the command name and the arguments. callback - the pointer to the callback function. args - The format of the args is: [-h|--help|-v|--version] or - noderange + name [-n|--nodestatmon] [-s|--settings ...] + where + name is the monitoring plug-in name. For example: rmcmon. + The specified plug-in will be registered and invoked + for monitoring the xCAT cluster. + -n|--nodestatmon indicates that this plug-in will be used for feeding the node liveness + status to the xCAT nodelist table. If not specified, the plug-in will not be used + for feeding node status to xCAT. + -s|--settings settings are used by the plug-in to customize it behavor. Returns: 0 for success. The output is returned through the callback pointer. 1. for unsuccess. The error messages are returns through the callback pointer. =cut #-------------------------------------------------------------------------------- -sub monaddnode { - my $args=shift; - my $callback=shift; - my $VERSION; - my $HELP; +sub monadd { + my $request = shift; + my $callback = shift; + my $args=$request->{arg}; + my $doreq = shift; # subroutine to display the usage - sub monaddnode_usage + sub monadd_usage { - my %rsp; + my $cb=shift; + my $rsp={}; $rsp->{data}->[0]= "Usage:"; - $rsp->{data}->[1]= " monaddnode noderange"; - $rsp->{data}->[2]= " monaddnode [-h|--help|-v|--version]"; - $rsp->{data}->[3]= " noderange is a list of comma separated node or node group names."; - $callback->($rsp); + $rsp->{data}->[1]= " monadd name [-n|--nodestatmon] [-s|--settings settings]"; + $rsp->{data}->[2]= " monadd [-h|--help|-v|--version]"; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module to be added."; + $rsp->{data}->[4]= " Use 'monls -a' command to list all the monitoring plug-in names."; + $rsp->{data}->[5]= " settings is used by the monitoring plug-in to customize its behavior."; + $rsp->{data}->[6]= " Format: [key1=value1],[key2=value2]... "; + $rsp->{data}->[7]= " Please note that the square brackets are needed. "; + $rsp->{data}->[7]= " Use 'monls name -d' command to look for the possible settings for a plug-in."; + $rsp->{data}->[8]= " Example: monadd xcatmon -n -s [ping-interval=10]"; + $cb->($rsp); + } + + @ARGV=(); + if ($args) { @ARGV=@{$args};} + my $settings; + + # parse the options + if(!GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION, + 'n|nodestatmon' => \$::NODESTATMON, + 's|settings=s' => \$settings)) + { + &monadd_usage($callback); + return 1; } - @ARGV=@{$args}; + # display the usage if -h or --help is specified + if ($::HELP) { + &monadd_usage($callback); + return 1; + } + # display the version statement if -v or --verison is specified + if ($::VERSION) + { + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version(); + $callback->($rsp); + return 1; + } + + #my @product_names; + my $pname; + my $nodestatmon=0; + if (@ARGV < 1) + { + &monadd_usage($callback); + return 1; + } + else { + #@product_names=split(/,/, $ARGV[0]); + $pname=$ARGV[0]; + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + if (!-e $file_name) { + my $rsp={}; + $rsp->{data}->[0]="File $file_name does not exist."; + $callback->($rsp); + return 1; + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + my $rsp={}; + $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; + $callback->($rsp); + return 1; + } + } + } + my $table=xCAT::Table->new("monitoring", -create =>1); + if ($table) { + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + my $name=$_->{name}; + if ($name eq $pname) { + my $rsp={}; + $rsp->{data}->[0]="$pname has already been added in the monitoring table."; + $callback->($rsp); + $table->close(); + return 1; + } + } + } + + my $module_name="xCAT_monitoring::$pname"; + + #check if the module suppors node status monitoring or not. + if ($::NODESTATMON) { + no strict "refs"; + my $snodestatusmon=0; + if (defined(${$module_name."::"}{supportNodeStatusMon})) { + $snodestatusmon=${$module_name."::"}{supportNodeStatusMon}->(); + } + if (!$snodestatusmon) { + my $rsp={}; + $rsp->{data}->[0]="$pname does not support node status monitoring."; + $callback->($rsp); + $table->close(); + return 1; + } + } + + #update the monsetting table + if ($settings) { + my $table1=xCAT::Table->new("monsetting", -create => 1,-autocommit => 1); + my %key_col1 = (name=>$pname); + #parse the settings. Setting format: key="value",key="value".... + while ($settings =~ s/^\[([^\[\]\=]*)=([^\[\]]*)\](,)*//) { + $key_col1{key}=$1; + my %setting_hash=(); + $setting_hash{value}=$2; + $table1->setAttribs(\%key_col1, \%setting_hash); + } + $table1->close(); + } + #update the monitoring table + my %key_col = (name=>$pname); + my $nstat='N'; + if ($::NODESTATMON) { + $nstat='Y'; + $nodestatmon=1; + } + my %tb_cols=(nodestatmon=>$nstat, disable=>"1"); + $table->setAttribs(\%key_col, \%tb_cols); + $table->close(); + + #updating the postscript table + no strict "refs"; + my $postscripts_h={}; + if (defined(${$module_name."::"}{getPostscripts})) { + my $postscripts_h=${$module_name."::"}{getPostscripts}->(); + my @pn=keys(%$postscripts_h); + if (@pn>0) { + my $table2=xCAT::Table->new("postscripts", -create =>1); + if (!$table2) { + my $rsp={}; + $rsp->{data}->[0]="Cannot open the postscripts table.\nFailed to set the postscripts for $pname."; + $callback->($rsp); + return 1; + } + foreach my $group (@pn) { + my $posts=$postscripts_h->{$group}; + if ($posts) { + (my $ref) = $table2->getAttribs({node => $group}, 'postscripts'); + if ($ref and $ref->{postscripts}) { + my @old_a=split(',', $ref->{postscripts}); + my @new_a=split(',', $posts); + my %new_h=(); + foreach my $new_tmp (@new_a) { + my $found=0; + foreach my $old_tmp (@old_a) { + if ($old_tmp eq $new_tmp) { $found=1; last; } + } + if (!$found) { $new_h{$new_tmp}=1;} + } + + if (keys(%new_h) > 0) { + foreach (keys(%new_h)) { push(@old_a, $_); } + my $new_post=join(',', @old_a); + my %key_col2 = (node=>$group); + my %tb_cols2=(postscripts=>$new_post); + $table2->setAttribs(\%key_col2, \%tb_cols2); + } + } else { + my %key_col2 = (node=>$group); + my %tb_cols2=(postscripts=>$posts); + $table2->setAttribs(\%key_col2, \%tb_cols2); + } + } + } + $table2->close(); + } + } + } else { + my $rsp={}; + $rsp->{data}->[0]="Failed to open the monitoring table."; + $callback->($rsp); + return 1; + } + + return 0; +} + + +#-------------------------------------------------------------------------------- +=head3 monrm + This function removes the given monitoring plug-in from the 'monitoring' table. + It also removed the postscritps for the module from the 'postscritps' table. + Arguments: + request -- a hash table which contains the command name and the arguments. + callback - the pointer to the callback function. + args - The format of the args is: + [-h|--help|-v|--version] or + name + where + name is the monitoring plug-in name. For example: rmcmon. + The specified plug-in will be stopped for monitoring the xCAT + cluster if it is running and then removed from the monitoring table. + Returns: + 0 for success. + 1 for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub monrm { + my $request = shift; + my $callback = shift; + my $args=$request->{arg}; + my $doreq = shift; + + if (xCAT::Utils->isServiceNode()) { + my $rsp={}; + $rsp->{data}->[0]= "This command is not supported on a service node."; + $callback->($rsp); + return (1, ""); + } + + # subroutine to display the usage + sub monrm_usage + { + my $cb=shift; + my $rsp={}; + $rsp->{data}->[0]= "Usage:"; + $rsp->{data}->[1]= " monrm name"; + $rsp->{data}->[2]= " monrm [-h|--help|-v|--version]"; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module registered in the monitoring table."; + $cb->($rsp); + } + + @ARGV=(); + if ($args) { @ARGV=@{$args};} + # parse the options if(!GetOptions( 'h|help' => \$::HELP, - 'v|version' => \$::VERSION, - 'local' => \$::LOCAL,)) # this flag is used internally to indicate - # that there is no need to find the monserver for the nodes - # just handle them on the lccal host + 'v|version' => \$::VERSION,)) { - &monaddnode_usage; + &monrm_usage($callback); + return (1, ""); + } + + # display the usage if -h or --help is specified + if ($::HELP) { + &monrm_usage($callback); + return (1, ""); + } + + # display the version statement if -v or --verison is specified + if ($::VERSION) + { + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version();; + $callback->($rsp); + return (1, ""); + } + + my $pname; + if (@ARGV < 1) + { + &monrm_usage($callback); + return (1, ""); + } + else { + $pname=$ARGV[0]; + } + + my $disable=1; + my $found=0; + my $table=xCAT::Table->new("monitoring", -create =>1); + if ($table) { + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + if ($pname eq $_->{name}) { + if ($_->{disable} =~ /0|NO|No|no|N|n/) { $disable=0; } + $found=1; + } + } + } + + if (!$found) { + my $rsp={}; + $rsp->{data}->[0]="$pname is not in the monitoring talble."; + $callback->($rsp); + $table->close(); + return 0; + } + + if (!$disable) { + my $rsp={}; + $rsp->{data}->[0]="Please run command 'monstop $pname' to stop monitoring before running this command."; + $callback->($rsp); + $table->close(); + return 0; + } + + my %key_col = (name=>$pname); + $table->delEntries(\%key_col); + $table->close(); + + + #remove the postscripts for the module from the postscript table + no strict "refs"; + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + my $module_name="xCAT_monitoring::$pname"; + if (!-e $file_name) { + return 0; + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + return 0; + } + } + + my $postscripts_h={}; + if (defined(${$module_name."::"}{getPostscripts})) { + my $postscripts_h=${$module_name."::"}{getPostscripts}->(); + my @pn=keys(%$postscripts_h); + if (@pn>0) { + my $table2=xCAT::Table->new("postscripts", -create =>1); + if (!$table2) { + my $rsp={}; + $rsp->{data}->[0]="Cannot open the postscripts table.\nFailed to remove the postscripts for $pname."; + $callback->($rsp); + return 1; + } + foreach my $group (@pn) { + my $posts=$postscripts_h->{$group}; + if ($posts) { + (my $ref) = $table2->getAttribs({node => $group}, 'postscripts'); + if ($ref and $ref->{postscripts}) { + my @old_a=split(',', $ref->{postscripts}); + my @new_a=split(',', $posts); + my %new_h=(); + my @new_post_a=(); + foreach my $old_tmp (@old_a) { + my $found=0; + foreach my $new_tmp (@new_a) { + if ($old_tmp eq $new_tmp) { $found=1; last; } + } + if (!$found) { push(@new_post_a,$old_tmp); } + } + + if (@new_post_a > 0) { + my $new_post=join(',', @new_post_a); + if ( $new_post ne $ref->{postscripts} ) { + my %key_col2 = (node=>$group); + my %tb_cols2=(postscripts=>$new_post); + $table2->setAttribs(\%key_col2, \%tb_cols2); + } + } else { + my %key_col2 = (node=>$group); + $table2->delEntries(\%key_col2); + } + } + } + } + $table2->close(); + } + } + } else { + my $rsp={}; + $rsp->{data}->[0]="Cannot open monitoring table."; + $callback->($rsp); + return 1; + } + + return 0; +} + +#-------------------------------------------------------------------------------- +=head3 preprocess_moncfg + This function handles the syntax checking for moncfg command. + Arguments: + callback - the pointer to the callback function. + args - The format of the args is: + [-h|--help|-v|--version] or + name [noderange] [-r|--remote] + where + name is the monitoring plug-in name. For example: rmcmon. + The specified plug-in will be invoked for configuring the cluster to monitor the nodes. + noderange a range of nodes to be configured for. Default is all. + -r|--remote indicates that both monservers and the nodes need to configured. + The defaults is monservers only. + Returns: + (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the + actions. 1 means monervers only, 2 means both nodes and monservers. + (1, "") for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub preprocess_moncfg +{ + my $args=shift; + my $callback=shift; + + # subroutine to display the usage + sub moncfg_usage + { + my $cb=shift; + my $rsp={}; + $rsp->{data}->[0]= "Usage:"; + $rsp->{data}->[1]= " moncfg name [noderange] [-r|--remote]"; + $rsp->{data}->[2]= " moncfg [-h|--help|-v|--version]"; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module to be invoked."; + $rsp->{data}->[4]= " Use 'monls -a' command to list all the monitoring plug-in names."; + $rsp->{data}->[5]= " noderange is a range of nodes to be configured for. The default is all nodes."; + $rsp->{data}->[6]= " -r|--remote indicates that both monservers and the nodes need to be configured.\n The default is monservers only."; + $rsp->{data}->[7]= " The default is monservers only."; + $cb->($rsp); + } + + @ARGV=(); + if ($args) { @ARGV=@{$args};} + + # parse the options + if(!GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION, + 'r|remote' => \$::REMOTE,)) + { + &moncfg_usage($callback); return; } # display the usage if -h or --help is specified if ($::HELP) { - &monaddnode_usage; + &moncfg_usage($callback); return; } # display the version statement if -v or --verison is specified if ($::VERSION) { - my %rsp; - $rsp->{data}->[0]= "monaddnode version 1.0"; + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version(); $callback->($rsp); return; } - my $noderange; + my $pname=""; + my $scope=0; + my @nodes=(); + my $nodestatmon=0; + + if ($::REMOTE) { $scope=2;} + if (@ARGV < 1) { - &monaddnode_usage; - return; + &moncfg_usage($callback); + return (1, ""); } else { - $noderange=$ARGV[0]; - } + $pname=$ARGV[0]; + if (@ARGV > 1) { + my $noderange=$ARGV[1]; + @nodes = noderange($noderange); + if (nodesmissed) { + my $rsp={}; + $rsp->{data}->[0]= "Invalid nodes in noderange:".join(',',nodesmissed); + $callback->($rsp); + return (1, ""); + } + } - my @nodenames=noderange($noderange); - my @missed=nodesmissed(); - if (@missed > 0) { - my %rsp1; - $rsp1->{data}->[0]="Invalide nodes:@missed"; - $callback->($rsp1); - return; - } - - my %ret=xCAT_monitoring::monitorctrl->addNodes(\@nodenames,$::LOCAL); - - if (%ret) { - foreach(keys(%ret)) { - my $retstat=$ret{$_}; - my %rsp1; - $rsp1->{data}->[0]="$_: @$retstat"; - $callback->($rsp1); + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + if (!-e $file_name) { + my $rsp={}; + $rsp->{data}->[0]="File $file_name does not exist."; + $callback->($rsp); + return (1, ""); + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + my $rsp={}; + $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; + $callback->($rsp); + return (1, ""); + } } } - - return 0; + my $table=xCAT::Table->new("monitoring", -create => 1,-autocommit => 1); + if ($table) { + my $found=0; + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + if ($pname eq $_->{name}) { + $found=1; + if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon=1;} + last; + } + } + } + if (!$found) { + my $rsp={}; + $rsp->{data}->[0]="$pname cannot be found in the monitoring table."; + $callback->($rsp); + $table->close(); + return (1, ""); + } + + $table->close(); + } else { + my $rsp={}; + $rsp->{data}->[0]="Failed to open the monitoring table."; + $callback->($rsp); + return (1, ""); + } + + return (0, $pname, $nodestatmon, $scope, \@nodes); } - - #-------------------------------------------------------------------------------- -=head3 monrmnode - This function informs all the active monitoring plug-ins to remove the given - nodes to their monitoring domain +=head3 moncfg + This function configures the cluster for the given nodes. It includes configuring + and setting up the 3rd party monitoring software for monitoring the given nodes. Arguments: - callback - the pointer to the callback function. - args - The format of the args is: - [-h|--help|-v|--version] or - noderange + request -- a hash table which contains the command name and the arguments. + callback -- the callback pointer for error and status displaying. It can be null. Returns: 0 for success. The output is returned through the callback pointer. 1. for unsuccess. The error messages are returns through the callback pointer. =cut #-------------------------------------------------------------------------------- -sub monrmnode { - my $args=shift; - my $callback=shift; - my $VERSION; - my $HELP; - - # subroutine to display the usage - sub monrmnode_usage - { - my %rsp; - $rsp->{data}->[0]= "Usage:"; - $rsp->{data}->[1]= " monrmnode noderange"; - $rsp->{data}->[2]= " monrmnode [-h|--help|-v|--version]"; - $rsp->{data}->[3]= " noderange is a list of comma separated node or node group names."; - $callback->($rsp); - } - - @ARGV=@{$args}; - # parse the options - if(!GetOptions( - 'h|help' => \$::HELP, - 'v|version' => \$::VERSION, - 'local' => \$::LOCAL,)) # this flag is used internally to indicate - # that there is no need to find the monserver for the nodes - # just handle them on the lccal host - - { - &monrmnode_usage; - return; - } - - # display the usage if -h or --help is specified - if ($::HELP) { - &monrmnode_usage; - return; - } - - # display the version statement if -v or --verison is specified - if ($::VERSION) - { - my %rsp; - $rsp->{data}->[0]= "monrmnode version 1.0"; - $callback->($rsp); - return; - } - - - my $noderange; - if (@ARGV < 1) - { - &monrmnode_usage; - return; - } - else { - $noderange=$ARGV[0]; - } - - my @nodenames=noderange($noderange, 0); - if (@nodenames==0) { return 0;} - - my %ret=xCAT_monitoring::monitorctrl->removeNodes(\@nodenames, $::LOCAL); - if (%ret) { - foreach(keys(%ret)) { - my $retstat=$ret{$_}; - my %rsp1; - $rsp1->{data}->[0]="$_: @$retstat"; - $callback->($rsp1); - } - } - - return 0; - -} - - - -#-------------------------------------------------------------------------------- -=head3 moncfgmaster - This function goes asks the monitoring plug-ins to configure the local host - to include the given nodes into the monitoring domain. (The nodes configuration - is done via post installation scripts during deployment process). - Arguments: - nodes - a pointer to a array of nodes. - callback - the pointer to the callback function. - Returns: - 0 for success. The output is returned through the callback pointer. - 1. for unsuccess. The error messages are returns through the callback pointer. -=cut -#-------------------------------------------------------------------------------- -sub moncfgmaster { - my $noderef=shift; +sub moncfg +{ + my $request=shift; my $callback=shift; - my ($ret, $msg) = xCAT_monitoring::monitorctrl->configMaster4Nodes($noderef); - if ($ret) { - my %rsp1; - $rsp1->{data}->[0]="$msg"; - $callback->($rsp1); - } - return $ret; + my $pname=$request->{module}->[0]; + my $nodestatmon=$request->{nodestatmon}->[0]; + my $scope=$request->{scope}->[0]; + my $nodeinfo=$request->{nodeinfo}->[0]; + + my @nodes=split(',', $nodeinfo); + print "moncfg get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n"; + + xCAT_monitoring::monitorctrl->config([$pname], \@nodes, $scope, $callback); + return 0; +} + + +#-------------------------------------------------------------------------------- +=head3 preprocess_mondecfg + This function handles the syntax checking for mondecfg command. + Arguments: + callback - the pointer to the callback function. + args - The format of the args is: + [-h|--help|-v|--version] or + name [noderange] [-r|--remote] + where + name is the monitoring plug-in name. For example: rmcmon. + The specified plug-in will be invoked for deconfiguring the cluster to monitor the nodes. + noderange a range of nodes to be deconfigured for. Default is all. + -r|--remote indicates that both monservers and the nodes need to be deconfigured. + The defaults is monservers only. + Returns: + (0, $modulename, $nodestatutmon, $scope, \@nodes) for success. scope is the scope of the + actions. 1 means monervers only, 2 means both nodes and monservers. + (1, "") for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub preprocess_mondecfg +{ + my $args=shift; + my $callback=shift; + + # subroutine to display the usage + sub mondecfg_usage + { + my $cb=shift; + my $rsp={}; + $rsp->{data}->[0]= "Usage:"; + $rsp->{data}->[1]= " mondecfg name [noderange] [-r|--remote]"; + $rsp->{data}->[2]= " mondecfg [-h|--help|-v|--version]"; + $rsp->{data}->[3]= " name is the name of the monitoring plug-in module to be invoked."; + $rsp->{data}->[4]= " Use 'monls -a' command to list all the monitoring plug-in names."; + $rsp->{data}->[5]= " noderange is a range of nodes to be deconfigured for."; + $rsp->{data}->[6]= " The default is all nodes."; + $rsp->{data}->[7]= " -r|--remote indicates that both monservers and the nodes need to be deconfigured."; + $rsp->{data}->[8]= " The default is monservers only."; + $cb->($rsp); + } + + @ARGV=(); + if ($args) { @ARGV=@{$args} ; } + + # parse the options + if(!GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION, + 'r|remote' => \$::REMOTE,)) + { + &mondecfg_usage($callback); + return; + } + + # display the usage if -h or --help is specified + if ($::HELP) { + &mondecfg_usage($callback); + return; + } + + # display the version statement if -v or --verison is specified + if ($::VERSION) + { + my $rsp={}; + $rsp->{data}->[0]= xCAT::Utils->Version(); + $callback->($rsp); + return; + } + + + my $pname=""; + my $scope=0; + my @nodes=(); + my $nodestatmon=0; + + if ($::REMOTE) { $scope=2;} + + if (@ARGV < 1) + { + &mondecfg_usage($callback); + return (1, ""); + } + else { + $pname=$ARGV[0]; + if (@ARGV > 1) { + my $noderange=$ARGV[1]; + @nodes = noderange($noderange); + if (nodesmissed) { + my $rsp={}; + $rsp->{data}->[0]= "Invalid nodes in noderange:".join(',',nodesmissed); + $callback->($rsp); + return (1, ""); + } + } + + my $file_name="$::XCATROOT/lib/perl/xCAT_monitoring/$pname.pm"; + if (!-e $file_name) { + my $rsp={}; + $rsp->{data}->[0]="File $file_name does not exist."; + $callback->($rsp); + return (1, ""); + } else { + #load the module in memory + eval {require($file_name)}; + if ($@) { + my $rsp={}; + $rsp->{data}->[0]="The file $file_name has compiling errors:\n$@\n"; + $callback->($rsp); + return (1, ""); + } + } + } + + my $table=xCAT::Table->new("monitoring", -create => 1,-autocommit => 1); + if ($table) { + my $found=0; + my $tmp1=$table->getAllEntries(); + if (defined($tmp1) && (@$tmp1 > 0)) { + foreach(@$tmp1) { + if ($pname eq $_->{name}) { + $found=1; + if ($_->{nodestatmon} =~ /1|Yes|yes|YES|Y|y/) { $nodestatmon=1;} + last; + } + } + } + + if (!$found) { + my $rsp={}; + $rsp->{data}->[0]="$pname cannot be found in the monitoring table."; + $callback->($rsp); + $table->close(); + return (1, ""); + } + + $table->close(); + } else { + my $rsp={}; + $rsp->{data}->[0]="Failed to open the monitoring table."; + $callback->($rsp); + return (1, ""); + } + + return (0, $pname, $nodestatmon, $scope, \@nodes); +} + +#-------------------------------------------------------------------------------- +=head3 mondecfg + This function deconfigures the cluster for the given nodes. It includes deconfiguring + and clearning up the 3rd party monitoring software for monitoring the given nodes. + Arguments: + names -- a pointer to an array of monitoring plug-in names. If non is specified, + all the plug-ins registered in the monitoring table will be notified. + p_nodes -- a pointer to an arrays of nodes to be removed from the monitoring domain. + none means all. + scope -- the action scope, it indicates the node type the action will take place. + 0 means localhost only. + 1 means monserver only, + 2 means both monservers and nodes, + callback -- the callback pointer for error and status displaying. It can be null. + Returns: + 0 for success. The output is returned through the callback pointer. + 1. for unsuccess. The error messages are returns through the callback pointer. +=cut +#-------------------------------------------------------------------------------- +sub mondecfg +{ + my $request=shift; + my $callback=shift; + + my $pname=$request->{module}->[0]; + my $nodestatmon=$request->{nodestatmon}->[0]; + my $scope=$request->{scope}->[0]; + my $nodeinfo=$request->{nodeinfo}->[0]; + + my @nodes=split(',', $nodeinfo); + print "mondecfg get called: pname=$pname\nnodestatmon=$nodestatmon\nnodeinfo=@nodes\nscope=$scope\n"; + + xCAT_monitoring::monitorctrl->deconfig([$pname], \@nodes, $scope, $callback); + return 0; } - - - - - - diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index c86a9cfeb..856ca8edd 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -295,15 +295,6 @@ sub process_request { } } - ################################## - #give monitoring code a chance to prepare the master for the node deployment - my %new_request = ( - command => ['moncfgmaster'], - node => \@rnodes - ); - $sub_req->(\%new_request, \&pass_along); - ################################## - } diff --git a/xCAT-server/lib/xcat/plugins/yaboot.pm b/xCAT-server/lib/xcat/plugins/yaboot.pm index e87aae8bd..7bf460aa4 100644 --- a/xCAT-server/lib/xcat/plugins/yaboot.pm +++ b/xCAT-server/lib/xcat/plugins/yaboot.pm @@ -282,14 +282,6 @@ sub process_request { node=>\@breaknetboot, arg=>['-s','filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";']},$callback); - ##################################### - # give monitoring code a chance to prepare the master for the node deployment - my %new_request = ( - command => ['moncfgmaster'], - node => \@rnodes - ); - $sub_req->(\%new_request, \&pass_along); - ##################################### } diff --git a/xCAT-server/sbin/xcatnodemon b/xCAT-server/sbin/xcatnodemon index 2569a3fd6..0e864cf91 100755 --- a/xCAT-server/sbin/xcatnodemon +++ b/xCAT-server/sbin/xcatnodemon @@ -56,7 +56,7 @@ if (@changed_inactive>0) { #only set the node status for the changed ones if (keys(%node_status) > 0) { - xCAT_monitoring::xcatmon::processNodeStatusChanges(\%node_status); + xCAT_monitoring::xcatmon::setNodeStatusAttributes(\%node_status); } #($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);