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:
linggao 2009-04-01 18:03:08 +00:00
parent dbe741dcef
commit fb84149886
5 changed files with 921 additions and 216 deletions

View 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;

View 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;

View File

@ -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
View 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;
}

View File

@ -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;
}