From fb84149886fae1b6bfc745fdef2b7428777c0d35 Mon Sep 17 00:00:00 2001 From: linggao Date: Wed, 1 Apr 2009 18:03:08 +0000 Subject: [PATCH] added IB monitoring support git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3067 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- .../resources/sn/IBM.Condition/IBSwitchLog.pm | 13 + .../sn/IBM.Sensor/IBSwitchLogSensor.pm | 20 + xCAT-rmc/scripts/errmsgque | 67 ++- xCAT-rmc/scripts/monaixsyslog | 509 +++++++++++++++++ xCAT-rmc/scripts/monerrorlog | 528 +++++++++++------- 5 files changed, 921 insertions(+), 216 deletions(-) create mode 100644 xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm create mode 100644 xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm create mode 100755 xCAT-rmc/scripts/monaixsyslog diff --git a/xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm b/xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm new file mode 100644 index 000000000..0c0629f0a --- /dev/null +++ b/xCAT-rmc/resources/sn/IBM.Condition/IBSwitchLog.pm @@ -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; diff --git a/xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm b/xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm new file mode 100644 index 000000000..25019f511 --- /dev/null +++ b/xCAT-rmc/resources/sn/IBM.Sensor/IBSwitchLogSensor.pm @@ -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; diff --git a/xCAT-rmc/scripts/errmsgque b/xCAT-rmc/scripts/errmsgque index adedc227f..358c148fe 100755 --- a/xCAT-rmc/scripts/errmsgque +++ b/xCAT-rmc/scripts/errmsgque @@ -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; diff --git a/xCAT-rmc/scripts/monaixsyslog b/xCAT-rmc/scripts/monaixsyslog new file mode 100755 index 000000000..de96a76f3 --- /dev/null +++ b/xCAT-rmc/scripts/monaixsyslog @@ -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 = ; + 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 : ., the default value is "*.warn" + -f : , 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 = ) + { + 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; +} + diff --git a/xCAT-rmc/scripts/monerrorlog b/xCAT-rmc/scripts/monerrorlog index f31176908..6af6f3e0e 100755 --- a/xCAT-rmc/scripts/monerrorlog +++ b/xCAT-rmc/scripts/monerrorlog @@ -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 = ; + 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 : ., the default value is "*.warn" + -f : , 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 = ; - 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; +}