NAGIOS PATCH for EXTERNAL COMMAND INTERFACE VIA PLAIN FILES
February 2011
1. BACKGROUND
Nagios' external command interface is heavily based on named pipes.
During porting of Nagios to the Cygwin platform, it's been observed
that the current named pipe implementation in Cygwin is somewhat
broken and unstable. This fact is also verified by Cygwin developers
(See http://cygwin.com/ml/cygwin/2010-08/msg00459.html for more info).
Several approaches have been evaluated to overcome the problem, and a
simple scheme based on 'one-plain-file-for-each-external-command' is
chosen. The basic motivation behind this decision is to use something
that works well at all circumtances (file system/directories).
This is not perfect/sleek/state-of-art solution, but it should be more
than enough for environments with average load and use of external
commands.
The scheme itself is not dependent on Cygwin and can be used
on other platforms as well.
2. DESIGN
2.1. Creation
Every time Nagios receives an external command via the external command
interface, a plain file containing the command itself is created.
The format of the file name is as follows:
nagios.cmd.nnnnnnnnnnnnnnnnnnnn
where 'nnnnnnnnnnnnnnnnnnnn' is 20-digit timestamp in milliseconds:
2.2. Processing
Every time Nagios wants to process external commands, it scans the
external-commands directory and puts up to 512 files to an internal
array. Entries in that array will then be sorted in ascending order
by the built-in quick sort function. If there is enough room in the
external commands buffer, each file is read, the content is submitted
as an external command before the file itself is deleted.
In all circumstances, Nagios will release the memory used for file
entries back to the system.
3. IMPLEMENTATION
Nagios external command interface CGI ('cmd.cgi') is patched to produce
file names according to the format used in that approach.
'utils.c' is patched for processing of external commands.
If sysadmins/developers want to send their external commands directly,
they can use the C-code below, to produce a file name according to the
format used in that approach:
>>C-CODE
#include <stdlib.h>
#include <sys/time.h>
....
struct timeval time_of_day;
char command_file_plain[MAX_FILENAME_LENGTH];
....
gettimeofday(&time_of_day, NULL);
/* create a file name by using time of day in millisecs as postfix
preceded by a dot, largest 64-bit number can be represented by 20
decimal digits */
(void) sprintf (command_file_plain, "%s.%020lu", command_file,
(long) (time_of_day.tv_sec * 1000 + time_of_day.tv_usec / 1000));
>>C-CODE
|