added IB monitoring support
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3067 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
dbe741dcef
commit
fb84149886
13
xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm
Normal file
13
xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm
Normal file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
$RES::Condition{'IBSwitchLog'} = {
|
||||
Name => q(IBSwitchLog),
|
||||
ResourceClass => q(IBM.Sensor),
|
||||
EventExpression => q(String != ""),
|
||||
EventDescription => q(An event will be generated when an error is logged to the Syslog in the local node for IB.),
|
||||
SelectionString => q(Name="IBSwitchLogSensor"),
|
||||
Severity => q(0),
|
||||
};
|
||||
|
||||
|
||||
1;
|
20
xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm
Normal file
20
xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm
Normal file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
|
||||
my $cmd;
|
||||
if ($^O =~ /^linux/i) { $cmd="$::XCATROOT/sbin/rmcmon/monerrorlog";}
|
||||
else {$cmd="$::XCATROOT/sbin/rmcmon/monaixsyslog";}
|
||||
|
||||
$RES::Sensor{'IBSwitchLogSensor'} = {
|
||||
Name => q(IBSwitchLogSensor),
|
||||
Command => "$cmd -p local6.info",
|
||||
UserName => q(root),
|
||||
RefreshInterval => q(60),
|
||||
ErrorExitValue => q(1),
|
||||
ControlFlags => q(0),
|
||||
};
|
||||
1;
|
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
use strict;
|
||||
use locale;
|
||||
|
||||
@ -8,6 +7,42 @@ use Getopt::Std;
|
||||
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
|
||||
use IPC::Msg;
|
||||
|
||||
|
||||
|
||||
my $m = ord('xcat');
|
||||
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
|
||||
|
||||
# my $msg = new IPC::Msg($key, IPC_CREAT|S_IRUSR|S_IWUSR );
|
||||
# my $message = join " ", @ARGV;
|
||||
# $msg->snd(1, "$message");
|
||||
|
||||
my $message = join " ", @ARGV;
|
||||
|
||||
runcmd("/usr/bin/refsensor ErrorLogSensor String=\"$message\" 1>/dev/null 2>/dev/null", 0);
|
||||
if($::RUNCMD_RC != 0){
|
||||
my $msg = new IPC::Msg($key, IPC_CREAT|S_IRUSR|S_IWUSR );
|
||||
my $stat = $msg->stat;
|
||||
my $qcurrentlen = $$stat[5];
|
||||
if ($qcurrentlen >= 10000)
|
||||
{
|
||||
if (!-d "/var/opt/xcat_err_mon/")
|
||||
{
|
||||
my $cmd = "mkdir -p \"/var/opt/xcat_err_mon\"";
|
||||
runcmd($cmd, -1);
|
||||
}
|
||||
open(FILE, ">>/var/opt/xcat_err_mon/errmsgqueerr.log");
|
||||
my $sdate = `/bin/date`;
|
||||
chomp $sdate;
|
||||
print FILE "$sdate:\n";
|
||||
print FILE "Can not write the message to queue because the queue is almost full, the message content is: $message\n\n\n";
|
||||
close FILE;
|
||||
exit 0;
|
||||
}
|
||||
$msg->snd(1, "$message");
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
@ -39,9 +74,8 @@ sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
@ -122,7 +156,7 @@ sub runcmd
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
@ -140,26 +174,3 @@ sub filterRmcApiOutput
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
my $m = ord('xcat_rmc');
|
||||
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
|
||||
|
||||
my $msg = new IPC::Msg($key, IPC_CREAT|S_IRUSR|S_IWUSR );
|
||||
my $message = join " ", @ARGV;
|
||||
my $stat = $msg->stat;
|
||||
my $qcurrentlen = $$stat[5];
|
||||
if ($qcurrentlen >= 10000) {
|
||||
if (!-d "/var/opt/xcat_rmc_err_mon/") {
|
||||
my $cmd = "mkdir -p \"/var/opt/xcat_rmc_err_mon\"";
|
||||
runcmd($cmd, -1);
|
||||
}
|
||||
open(FILE, ">>/var/opt/xcat_rmc_err_mon/errmsgqueerr.log");
|
||||
my $sdate = `/bin/date`;
|
||||
chomp $sdate;
|
||||
print FILE "$sdate:\n";
|
||||
print FILE "Can not write the message to queue because the queue is almost full, the message content is: $message\n\n\n";
|
||||
close FILE;
|
||||
exit 0;
|
||||
}
|
||||
$msg->snd(1, "$message");
|
||||
|
||||
exit 0;
|
||||
|
509
xCAT-rmc/scripts/monaixsyslog
Executable file
509
xCAT-rmc/scripts/monaixsyslog
Executable file
@ -0,0 +1,509 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#------------------------------------------------------------------------------
|
||||
=head1 monaixsyslog
|
||||
=head2
|
||||
=cut
|
||||
#------------------------------------------------------------------------------
|
||||
use locale;
|
||||
use Getopt::Long;
|
||||
|
||||
my $dirname = "xcat_aix_syslog";
|
||||
my $vardir = "/var/opt/$dirname";
|
||||
|
||||
my $default_runfile = "$vardir/.monaixsyslog_run";
|
||||
my $default_file = "$vardir/syslog.out";
|
||||
my $default_pri = "*.warn";
|
||||
|
||||
$::MAX_SENSOR_STRING = 10240;
|
||||
my ($facility_priority, $logfile, $runfile) = &getArgs();
|
||||
|
||||
my ($syslogconf, $embedinfo);
|
||||
|
||||
$syslogconf = "/etc/syslog.conf";
|
||||
$embedinfo = "$facility_priority $logfile rotate size 4m files 1";
|
||||
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
|
||||
#check to see if this is the first time this script has been run
|
||||
if (!-e $runfile)
|
||||
{ #first time
|
||||
if ($^O =~ /^aix/i)
|
||||
{
|
||||
runcmd("grep \"$embedinfo\" $syslogconf", -1);
|
||||
if ($::RUNCMD_RC == 1)
|
||||
{ #grep did not find embedinfo
|
||||
#update syslog.conf
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
if (!-e $logfile)
|
||||
{
|
||||
touchFile($logfile);
|
||||
}
|
||||
runcmd("echo \"$embedinfo\" >> $syslogconf");
|
||||
my $cmd = "refresh -s syslogd";
|
||||
runcmd($cmd);
|
||||
}
|
||||
touchFile($runfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "non-AIX platform, this scripts should not be ran.\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
#Check for errors
|
||||
|
||||
if ($^O =~ /^aix/i)
|
||||
{
|
||||
unless (open(RUNFILE, "<$runfile"))
|
||||
{
|
||||
print "Cannot open file $runfile\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $marker = <RUNFILE>;
|
||||
close(RUNFILE);
|
||||
|
||||
my ($new_number, $new_content, $to_rfile);
|
||||
# If the $runfile is empty, then we should read the $logfile from the beginning.
|
||||
if (!$marker)
|
||||
{
|
||||
($new_number, $new_content, $to_rfile) = &refreshSensorFromLogfile($logfile, 0, undef);
|
||||
}
|
||||
else
|
||||
{
|
||||
my @info = split ':::', $marker;
|
||||
my ($last_modified_time, $line_number, $mark_content) = @info;
|
||||
|
||||
my @stats = stat($logfile);
|
||||
my $time = $stats[9];
|
||||
if ($time == $last_modified_time)
|
||||
{
|
||||
# The log file has not been updated since last modified.
|
||||
exit 0;
|
||||
}
|
||||
|
||||
($new_number, $new_content, $to_rfile) = &refreshSensorFromLogfile($logfile, $line_number, $mark_content);
|
||||
|
||||
# If the $to_rfile is set, then we should refresh the info from rotated file to Sensor first.
|
||||
if ($to_rfile)
|
||||
{
|
||||
# Read the rotated file first.
|
||||
my $rotated_file = "$logfile" . ".0";
|
||||
($new_number, $new_content, $to_rfile) = &refreshSensorFromLogfile($rotated_file, $line_number, $mark_content);
|
||||
|
||||
# Then read the log file just from the beginning to refresh the Sensor.
|
||||
($new_number, $new_content, $to_rfile) = &refreshSensorFromLogfile($logfile, 0, undef);
|
||||
}
|
||||
}
|
||||
|
||||
# Get the last modified time for this log file
|
||||
my @stats = stat($logfile);
|
||||
my $new_time = $stats[9];
|
||||
|
||||
&updateRunfile($new_time, $new_number, $new_content, $runfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "non-AIX platform, this scripts should not be ran.\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 getArgs
|
||||
|
||||
parse the command line and check the values
|
||||
|
||||
paras:
|
||||
-p : <facility>.<priority>, the default value is "*.warn"
|
||||
-f : <fifo_name>, the default value is "/var/opt/xcat_aix_syslog/syslog_fifo"
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub getArgs()
|
||||
{
|
||||
my $routine = "getArgs";
|
||||
print "ENTERING: $routine\n" if $::DEBUG;
|
||||
|
||||
my @command_line = ();
|
||||
@command_line = @ARGV;
|
||||
|
||||
# Checks case in GetOptions
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
|
||||
my ($facility_priority, $file, $runfile);
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
'p=s' => \$facility_priority,
|
||||
'f=s' => \$file,
|
||||
)
|
||||
)
|
||||
{
|
||||
print "LEAVING: $routine\n" if $::DEBUG;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Set runfile mark file
|
||||
if ($facility_priority || $file)
|
||||
{
|
||||
my @para = split '/', $file;
|
||||
my $newpara = join '-', @para;
|
||||
$runfile = "$vardir/.monaixsyslog_run" . "-$facility_priority". "-$newpara";
|
||||
}
|
||||
else
|
||||
{
|
||||
$runfile = $default_runfile;
|
||||
}
|
||||
|
||||
if (!$file)
|
||||
{
|
||||
$file = $default_file;
|
||||
}
|
||||
|
||||
if (!$facility_priority)
|
||||
{
|
||||
$facility_priority = $default_pri;
|
||||
}
|
||||
|
||||
return ($facility_priority, $file, $runfile);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 refreshSensorFromLogfile
|
||||
|
||||
read the log file line by line to refresh the Sensor
|
||||
|
||||
Args:
|
||||
$file - the log file
|
||||
$bgnline - the beginning line number that we should read from
|
||||
$bgncontent - the line content related to $line
|
||||
|
||||
Return:
|
||||
$i - the line number that has been read and refreshed to Sensor.
|
||||
$mark_content - the line content related to $i
|
||||
$to_rfile - the flag that indicates whether we need to read from the
|
||||
rotated file.
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub refreshSensorFromLogfile()
|
||||
{
|
||||
my ($file, $bgnline, $bgncontent) = @_;
|
||||
unless (open(FILE, "<$file"))
|
||||
{
|
||||
# The file may be opened by syslogd.
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $i = 0;
|
||||
my $matchflag = 0;
|
||||
my $to_rfile = 0;
|
||||
my $mark_content;
|
||||
my $allinfo = "";
|
||||
while (my $line = <FILE>)
|
||||
{
|
||||
if ($matchflag || $bgnline == 0)
|
||||
{
|
||||
# Start reading the file from this line and push it to the sensor
|
||||
# and update the mark file
|
||||
$allinfo .= $line;
|
||||
$i = $i + 1;
|
||||
$mark_content = $line;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($i != $bgnline - 1)
|
||||
{
|
||||
$i = $i + 1;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($line eq $bgncontent)
|
||||
{
|
||||
$matchflag = 1;
|
||||
$i = $i + 1;
|
||||
next;
|
||||
}
|
||||
else
|
||||
{
|
||||
# The line number is the same, but the content is different
|
||||
# that indicates the log file has been rotated.
|
||||
$to_rfile = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($allinfo)
|
||||
{
|
||||
my $strlen = length($allinfo);
|
||||
# The condition/response can not handle
|
||||
# the long sensor String very well,
|
||||
# use file to pass messages.
|
||||
# file name: /var/opt/xcat_aix_syslog/tmplogmsg_$$
|
||||
if ($strlen > $::MAX_SENSOR_STRING)
|
||||
{
|
||||
srand(time | $$);
|
||||
my $filename = "$vardir/tmplogmsg_$$";
|
||||
while (-e $filename)
|
||||
{
|
||||
$filename = createRandomName($filename);
|
||||
}
|
||||
if (open(TMPLOG, ">$filename"))
|
||||
{
|
||||
print TMPLOG $allinfo;
|
||||
close TMPLOG;
|
||||
print "XCAT_MONAIXSYSLOG_FILE:$filename";
|
||||
}
|
||||
else
|
||||
{
|
||||
#open failed, why?
|
||||
print "OPEN_FILE_FAILED: $filename";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print $allinfo;
|
||||
}
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
return ($i, $mark_content, $to_rfile);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 updateRunfile
|
||||
|
||||
use the new marker line to update the runfile
|
||||
|
||||
Args:
|
||||
$time - last mofidied time
|
||||
$line - line number
|
||||
$content - line content
|
||||
$file - the run file
|
||||
|
||||
Return:
|
||||
$i - the line number that has been read and refreshed to Sensor.
|
||||
$mark_content - the line content related to $i
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub updateRunfile()
|
||||
{
|
||||
my ($time, $line, $content, $file) = @_;
|
||||
|
||||
# the marker line is something like "last_modified_time:::line_number:::mark_content"
|
||||
my $new_marker = join(":::", $time, $line, $content);
|
||||
runcmd("echo \"$new_marker\" > $file");
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
Run the given cmd and return the output in an array (already chopped). Alternatively,
|
||||
if this function is used in a scalar context, the output is joined into a single string
|
||||
with the newlines separating the lines.
|
||||
Arguments:
|
||||
command, exitcode and reference to output
|
||||
Returns:
|
||||
see below
|
||||
Error:
|
||||
Normally, if there is an error running the cmd, it will display the error msg
|
||||
and exit with the cmds exit code, unless exitcode is given one of the
|
||||
following values:
|
||||
0: display error msg, DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-1: DO NOT display error msg and DO NOT exit on error, but set
|
||||
$::RUNCMD_RC to the exit code.
|
||||
-2: DO the default behavior (display error msg and exit with cmds
|
||||
exit code.
|
||||
number > 0: Display error msg and exit with the given code
|
||||
Example:
|
||||
my $outref = runcmd($cmd, -2, 1);
|
||||
Comments:
|
||||
If refoutput is true, then the output will be returned as a reference to
|
||||
an array for efficiency.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
{
|
||||
$::RUNCMD_RC = $? >> 8;
|
||||
my $displayerror = 1;
|
||||
my $rc;
|
||||
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
|
||||
{
|
||||
if ($exitcode > 0)
|
||||
{
|
||||
$rc = $exitcode;
|
||||
} # if not zero, exit with specified code
|
||||
elsif ($exitcode <= 0)
|
||||
{
|
||||
$rc = ''; # if zero or negative, do not exit
|
||||
if ($exitcode < 0) { $displayerror = 0; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rc = $::RUNCMD_RC;
|
||||
} # if exitcode not specified, use cmd exit code
|
||||
if ($displayerror)
|
||||
{
|
||||
my $errmsg = '';
|
||||
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
|
||||
{
|
||||
$errmsg = "Segmentation fault $errmsg";
|
||||
}
|
||||
else
|
||||
{
|
||||
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
$errmsg = join('', @$outref);
|
||||
chomp $errmsg;
|
||||
}
|
||||
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
|
||||
}
|
||||
}
|
||||
if ($refoutput)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return $outref;
|
||||
}
|
||||
elsif (wantarray)
|
||||
{
|
||||
chomp(@$outref);
|
||||
return @$outref;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $line = join('', @$outref);
|
||||
chomp $line;
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 filterRmcApiOutput
|
||||
filter RMC Api Output
|
||||
Arguments:
|
||||
RMC command
|
||||
Output reference
|
||||
Returns:
|
||||
none
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
filterRmcApiOutput($cmd, $outref);
|
||||
Comments:
|
||||
The error msgs from the RPM -api cmds are pretty messy.
|
||||
This routine cleans them up a little bit.
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
# Figure out the output delimiter
|
||||
my ($d) = $cmd =~ / -D\s+(\S+)/;
|
||||
if (length($d)) {
|
||||
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
|
||||
# escape any chars perl pattern matching would intepret as special chars
|
||||
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$d = '::';
|
||||
} # this is the default output delimiter for the -api cmds
|
||||
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 touchFile
|
||||
Arguments: $filename, $donotExit
|
||||
Returns: non zero return code indicates error
|
||||
Example: touchFile("/var/opt/xcat/touch");
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub touchFile
|
||||
{
|
||||
my ($filename, $donotExit) = @_;
|
||||
my $fh;
|
||||
my $rc = 0;
|
||||
if (!-e $filename) {
|
||||
#if the file doesn't exist we need to open and close it
|
||||
open($fh, ">>$filename") or $rc++;
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
close($fh) or $rc++;
|
||||
}
|
||||
else {
|
||||
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
|
||||
my $now = time;
|
||||
utime($now, $now, $filename);
|
||||
}
|
||||
if ($rc > 0 && !$donotExit) {
|
||||
print "Touch of file $filename failed with: $!\n";
|
||||
return $rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 createRandomName
|
||||
|
||||
Create a randome file name.
|
||||
|
||||
Arguments:
|
||||
Prefix of name
|
||||
Returns:
|
||||
Prefix with 8 random letters appended
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
$file = createRandomName($namePrefix);
|
||||
Comments:
|
||||
None
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub createRandomName
|
||||
{
|
||||
my $name=shift;
|
||||
|
||||
my $nI;
|
||||
for ($nI = 0 ; $nI < 8 ; $nI++)
|
||||
{
|
||||
my $char = ('a' .. 'z', 'A' .. 'Z')[int(rand(52)) + 1];
|
||||
$name .= $char;
|
||||
}
|
||||
$name;
|
||||
}
|
||||
|
@ -1,26 +1,308 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#------------------------------------------------------------------------------
|
||||
=head1 monerrorlog
|
||||
=head2 When first run (by the sensor) this script adds an entry to the AIX ODM
|
||||
or Linux syslog.conf file so that it will be notified when an error is
|
||||
logged (through a message queue on AIX and a named pipe on Linux). Then
|
||||
it checks for any logged errors. On all subsequent runs this script just
|
||||
checks for errors.
|
||||
=head1 monaixsyslog
|
||||
=head2
|
||||
When first run (by the sensor) this script adds an entry to the AIX ODM
|
||||
or Linux syslog.conf file so that it will be notified when an error is
|
||||
logged (through a message queue on AIX and a named pipe on Linux). Then
|
||||
it checks for any logged errors. On all subsequent runs this script just
|
||||
checks for errors.
|
||||
=cut
|
||||
#------------------------------------------------------------------------------
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
use strict;
|
||||
use locale;
|
||||
use Getopt::Long;
|
||||
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
|
||||
use IPC::Msg;
|
||||
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
|
||||
use strict;
|
||||
use locale;
|
||||
my $dirname = "xcat_err_mon";
|
||||
my $vardir = "/var/opt/$dirname";
|
||||
|
||||
my $default_runfile = "$vardir/.monerrorlog_run";
|
||||
my $default_fifo = "$vardir/syslog_fifo";
|
||||
my $default_pri = "*.warn";
|
||||
$::MAX_SENSOR_STRING = 10240;
|
||||
|
||||
my ($facility_priority, $fifo, $runfile) = &getArgs();
|
||||
my ($syslogconf, $embedinfo);
|
||||
|
||||
if (isNg())
|
||||
{
|
||||
$syslogconf = "/etc/syslog-ng/syslog-ng.conf";
|
||||
if (($facility_priority eq $default_pri) && ($fifo eq $default_fifo))
|
||||
{
|
||||
$embedinfo = "destination warn_fifo { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter(f_warn); destination(warn_fifo); };";
|
||||
}
|
||||
else
|
||||
{
|
||||
my $tmp_dest = createRandomName("fifo");
|
||||
$embedinfo = "destination $tmp_dest { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter($facility_priority); destination($tmp_dest); };";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$syslogconf = "/etc/syslog.conf";
|
||||
$embedinfo = "$facility_priority |$fifo";
|
||||
}
|
||||
my $odmstanza = "$vardir/odmstanza";
|
||||
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 first_time_run
|
||||
|
||||
Notes: check whether this is the first time that monerrlog is run
|
||||
on Linux, check the marker file /var/opt/xcat_err_mon/.monerrorlog_run
|
||||
on AIX, check the errnotify odm entry itself
|
||||
|
||||
Arguments:
|
||||
N/A
|
||||
|
||||
Returns:
|
||||
0 - This is NOT the first time that monerrlog is run
|
||||
1 - This is the first time that monerrlog is run
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub first_time_run()
|
||||
{
|
||||
if($^O =~ /^aix/i)
|
||||
{
|
||||
my $output = runcmd("/bin/odmget -q \"en_name=xcat_errlog_sen\" errnotify", -1);
|
||||
if (!$output)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!-e $runfile)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#check to see if this is the first time this script has been run
|
||||
if (&first_time_run)
|
||||
{ #first time
|
||||
if ($^O =~ /^linux/i)
|
||||
{
|
||||
runcmd("grep \"$embedinfo\" $syslogconf", -1);
|
||||
if ($::RUNCMD_RC == 1)
|
||||
{ #grep did not find dirname
|
||||
#update syslog.conf
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
if (!-e $fifo)
|
||||
{
|
||||
runcmd("/usr/bin/mkfifo $fifo");
|
||||
}
|
||||
runcmd("echo \"$embedinfo\" >> $syslogconf");
|
||||
my $cmd = service("syslog", "restart");
|
||||
runcmd($cmd);
|
||||
}
|
||||
touchFile($runfile);
|
||||
}
|
||||
elsif ($^O =~ /^aix/i)
|
||||
{
|
||||
open(ODM, ">$odmstanza") or die $!;
|
||||
print ODM '
|
||||
errnotify:
|
||||
en_pid = 0
|
||||
en_name = "xcat_errlog_sen"
|
||||
en_persistenceflg = 1
|
||||
en_method = "' . "$::XCATROOT/sbin/rmcmon/errmsgque" . ' sequence = $1 error_id = $2 class = $3 type = $4 alert_flags = $5 res_name = $6 res_type = $7 res_class = $8 label = $9"
|
||||
';
|
||||
close ODM or die $!;
|
||||
runcmd("/usr/bin/odmadd $odmstanza");
|
||||
}
|
||||
else
|
||||
{
|
||||
print "unknown platform\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
#Check for errors
|
||||
|
||||
if ($^O =~ /^linux/i)
|
||||
{
|
||||
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||
eval {
|
||||
alarm 4;
|
||||
open(PIPE, $fifo) or die
|
||||
print "cannot open file$fifo";
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
|
||||
my $allinfo = "";
|
||||
while (1)
|
||||
{
|
||||
my $line;
|
||||
eval {
|
||||
alarm 2;
|
||||
$line = <PIPE>;
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) {
|
||||
close PIPE;
|
||||
# send the messages to sensor
|
||||
if ($allinfo)
|
||||
{
|
||||
my $strlen = length($allinfo);
|
||||
# The condition/response can not handle
|
||||
# the long sensor String very well,
|
||||
# use file to pass messages.
|
||||
# file name: /var/opt/xcat_err_mon/tmplogmsg
|
||||
if ($strlen > $::MAX_SENSOR_STRING)
|
||||
{
|
||||
srand(time | $$);
|
||||
my $filename = "$vardir/tmplogmsg_$$";
|
||||
while (-e $filename)
|
||||
{
|
||||
$filename = createRandomName($filename);
|
||||
}
|
||||
if (open(TMPLOG, ">$filename"))
|
||||
{
|
||||
print TMPLOG $allinfo;
|
||||
close TMPLOG;
|
||||
print "XCAT_MONERRORLOG_FILE:$filename";
|
||||
}
|
||||
else
|
||||
{
|
||||
#open failed, why?
|
||||
print "OPEN_FILE_FAILED: $filename";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print $allinfo;
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
$allinfo .= $line;
|
||||
}
|
||||
close PIPE;
|
||||
}
|
||||
elsif ($^O =~ /^aix/i)
|
||||
{
|
||||
# the monitoring is stopped
|
||||
if ($ENV{'SENSOR_MonitorStatus'} eq '2')
|
||||
{
|
||||
# stopsrc -s IBM.SensorRM will also
|
||||
# set $ENV{'SENSOR_MonitorStatus'} to 2
|
||||
# should not do clean up when IBM.SensorRM is stopped
|
||||
if (isRMrunning("IBM.SensorRM"))
|
||||
{
|
||||
runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_errlog_sen\"", -1);
|
||||
if (-e $runfile)
|
||||
{
|
||||
unlink($runfile);
|
||||
}
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $m = ord('xcat');
|
||||
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
|
||||
my $buf;
|
||||
my $msg = new IPC::Msg($key, IPC_CREAT | S_IRUSR | S_IWUSR);
|
||||
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||
while (1)
|
||||
{
|
||||
eval {
|
||||
alarm 2;
|
||||
my $rectype = $msg->rcv($buf, 256);
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
runcmd(
|
||||
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$buf\' 1>/dev/null 2>/dev/null\" | at now",
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 getArgs
|
||||
|
||||
parse the command line and check the values
|
||||
|
||||
paras:
|
||||
-p : <facility>.<priority>, the default value is "*.warn"
|
||||
-f : <fifo_name>, the default value is "/var/opt/xcat_err_mon/syslog_fifo"
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub getArgs()
|
||||
{
|
||||
my $routine = "getArgs";
|
||||
print "ENTERING: $routine\n" if $::DEBUG;
|
||||
|
||||
my @command_line = ();
|
||||
@command_line = @ARGV;
|
||||
|
||||
# Checks case in GetOptions
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
|
||||
my ($facility_priority, $fifo, $runfile);
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
'p=s' => \$facility_priority,
|
||||
'f=s' => \$fifo,
|
||||
)
|
||||
)
|
||||
{
|
||||
print "LEAVING: $routine\n" if $::DEBUG;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Set runfile mark file
|
||||
if ($facility_priority || $fifo)
|
||||
{
|
||||
my @para = split '/', $fifo;
|
||||
my $newpara = join '-', @para;
|
||||
$runfile = "$vardir/.monerrorlog_run" . "-$facility_priority". "-$newpara";
|
||||
}
|
||||
else
|
||||
{
|
||||
$runfile = $default_runfile;
|
||||
}
|
||||
|
||||
if (!$fifo)
|
||||
{
|
||||
$fifo = $default_fifo;
|
||||
}
|
||||
|
||||
if (!$facility_priority)
|
||||
{
|
||||
$facility_priority = $default_pri;
|
||||
}
|
||||
|
||||
return ($facility_priority, $fifo, $runfile);
|
||||
}
|
||||
|
||||
use Getopt::Std;
|
||||
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
|
||||
use IPC::Msg;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 runcmd
|
||||
@ -53,9 +335,8 @@ sub runcmd
|
||||
{
|
||||
my ($cmd, $exitcode, $refoutput) = @_;
|
||||
$::RUNCMD_RC = 0;
|
||||
if (!$::NO_STDERR_REDIRECT) {
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
}
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
if ($?)
|
||||
@ -136,7 +417,7 @@ sub runcmd
|
||||
sub filterRmcApiOutput
|
||||
{
|
||||
my ($cmd, $outref) = @_;
|
||||
if ($::VERBOSE || !($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
|
||||
return;
|
||||
} # give as much info as possible, if verbose
|
||||
|
||||
@ -188,172 +469,38 @@ sub touchFile
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#do nothing on Linux when stopping.
|
||||
if (($ENV{'SENSOR_MonitorStatus'} eq '2') && ($^O =~ /^linux/i)) {
|
||||
exit 0;
|
||||
}
|
||||
|
||||
#normal
|
||||
my $dirname = "xcat_rmc_err_mon";
|
||||
my $vardir = "/var/opt/$dirname" ;
|
||||
my $runfile = "$vardir/.monerrorlog_run";
|
||||
my $fifo = "$vardir/syslog_fifo";
|
||||
my ($syslogconf, $embedinfo);
|
||||
if (-e "/etc/SuSE-release") { #SLES 10
|
||||
$syslogconf = "/etc/syslog-ng/syslog-ng.conf";
|
||||
$embedinfo = "destination warn_fifo { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter(f_warn); destination(warn_fifo); };";
|
||||
}
|
||||
else { #others
|
||||
$syslogconf = "/etc/syslog.conf";
|
||||
$embedinfo = "*.warn |$fifo";
|
||||
}
|
||||
my $odmstanza = "$vardir/odmstanza";
|
||||
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
|
||||
sub isRMrunning{
|
||||
my $resMan = $_[0];
|
||||
my @output = runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
|
||||
if ($::RUNCMD_RC) { return 0; } # maybe we should try to catch real errors here
|
||||
my ($subsys, $group, $pid, $status) = split(' ', $output[1]);
|
||||
if (defined($status) && $status eq 'active') {
|
||||
#now check to see if IBM.AuditRM is up
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#check to see if this is the first time this script has been run
|
||||
if (!-e $runfile){
|
||||
#first time
|
||||
if ($^O =~ /^linux/i) {
|
||||
runcmd("grep $dirname $syslogconf", -1);
|
||||
if ($::RUNCMD_RC == 1) { #grep did not find dirname
|
||||
#update syslog.conf
|
||||
if (!-d $vardir) { mkdir($vardir); }
|
||||
runcmd("/usr/bin/mkfifo $fifo");
|
||||
runcmd("echo \"$embedinfo\" >> $syslogconf");
|
||||
my $cmd = service("syslog", "restart");
|
||||
runcmd($cmd);
|
||||
}
|
||||
touchFile($runfile);
|
||||
}
|
||||
elsif ($^O =~ /^aix/i) {
|
||||
open(ODM, ">$odmstanza") or die $!;
|
||||
print ODM '
|
||||
errnotify:
|
||||
en_pid = 0
|
||||
en_name = "xcat_rmc_errlog"
|
||||
en_persistenceflg = 1
|
||||
en_method = "' . "$::XCATROOT/sbin/rmcmon/errmsgque" . ' sequence = $1 error_id = $2 class = $3 type = $4 alert_flags = $5 res_name = $6 res_type = $7 res_class = $8 label = $9"
|
||||
';
|
||||
close ODM or die $!;
|
||||
runcmd("/usr/bin/odmadd $odmstanza");
|
||||
touchFile($runfile);
|
||||
}
|
||||
else {
|
||||
print "unknown platform\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
#Check for errors
|
||||
|
||||
#see if at is running
|
||||
verify_atd(); #TODO optimize this by not using at
|
||||
|
||||
if ($^O =~ /^linux/i) {
|
||||
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||
eval {
|
||||
alarm 4;
|
||||
open(PIPE, $fifo) or die
|
||||
print "Could not open $fifo.\n";
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
|
||||
while (1) {
|
||||
my $line;
|
||||
eval {
|
||||
alarm 2;
|
||||
$line = <PIPE>;
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
chomp($line);
|
||||
|
||||
#print "String=\"$line\"\n";
|
||||
runcmd(
|
||||
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$line\' 1>/dev/null 2>/dev/null\" | at now",0);
|
||||
}
|
||||
close PIPE;
|
||||
}
|
||||
elsif ($^O =~ /^aix/i) {
|
||||
# the monitoring is stopped
|
||||
if ($ENV{'SENSOR_MonitorStatus'} eq '2') {
|
||||
# stopsrc -s IBM.SensorRM will also
|
||||
# set $ENV{'SENSOR_MonitorStatus'} to 2
|
||||
# should not do clean up when IBM.SensorRM is stopped
|
||||
if (&isRMrunning("IBM.SensorRM")) {
|
||||
runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_rmc_errlog\"", -1);
|
||||
if (-e $runfile) {
|
||||
unlink($runfile);
|
||||
}
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $m = ord('xcat_rmc');
|
||||
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
|
||||
my $buf;
|
||||
my $msg = new IPC::Msg($key, IPC_CREAT | S_IRUSR | S_IWUSR);
|
||||
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||
while (1) {
|
||||
eval {
|
||||
alarm 2;
|
||||
my $rectype = $msg->rcv($buf, 256);
|
||||
alarm 0;
|
||||
};
|
||||
if ($@ =~ /alarm/) { close PIPE; exit 0; }
|
||||
runcmd(
|
||||
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$buf\' 1>/dev/null 2>/dev/null\" | at now", 0);
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 verify_atd
|
||||
check for atd status. If it is not running, start it.
|
||||
|
||||
=head3 createRandomName
|
||||
|
||||
Create a randome file name.
|
||||
|
||||
Arguments:
|
||||
Prefix of name
|
||||
Returns:
|
||||
$::RUNCMD_RC = 0 atd is running
|
||||
$::RUNCMD_RC > 0 atd is not running
|
||||
Prefix with 8 random letters appended
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
$file = createRandomName($namePrefix);
|
||||
Comments:
|
||||
None
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub verify_atd
|
||||
|
||||
sub createRandomName
|
||||
{
|
||||
my $cmd;
|
||||
$cmd = service("atd", "status");
|
||||
runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC) {
|
||||
$cmd = service("atd", "start");
|
||||
runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC) {
|
||||
# print "Warning: atd has failed to start!\n";
|
||||
my $name = shift;
|
||||
|
||||
my $nI;
|
||||
for ($nI = 0 ; $nI < 8 ; $nI++)
|
||||
{
|
||||
my $char = ('a' .. 'z', 'A' .. 'Z')[int(rand(52)) + 1];
|
||||
$name .= $char;
|
||||
}
|
||||
elsif (!$::RUNCMD_RC) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
;#???
|
||||
}
|
||||
return $::RUNCMD_RC;
|
||||
$name;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
@ -395,20 +542,25 @@ sub isHMC
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub isNg {
|
||||
if (-f "/etc/SuSE-release") {
|
||||
my $sysconfig="/etc/sysconfig/syslog";
|
||||
my $result=`grep "^SYSLOG_DAEMON=" $sysconfig 2>&1`;
|
||||
if ($result =~ /syslog-ng/) { return 1; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub isRMrunning{
|
||||
my $resMan = $_[0];
|
||||
my @output = runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
|
||||
if ($::RUNCMD_RC) { return 0; } # maybe we should try to catch real errors here
|
||||
my ($subsys, $group, $pid, $status) = split(' ', $output[1]);
|
||||
if (defined($status) && $status eq 'active') {
|
||||
#now check to see if IBM.AuditRM is up
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user