#include "dnxNebMain.h"
#include "dnxCfgParser.h"
#include "dnxError.h"
#include "dnxDebug.h"
#include "nagios.h"
#include "objects.h"
#include "nebmodules.h"
#include "nebstructs.h"
#include "nebcallbacks.h"
#include "neberrors.h"
#include "broker.h"
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <regex.h>
Go to the source code of this file.
Data Structures | |
struct | DnxCfgData |
The internal server module configuration data structure. More... | |
Defines | |
#define | VERSION "<unknown>" |
#define | SYSCONFDIR "/etc" |
#define | SYSLOGDIR "/var/log" |
#define | LIBEXECDIR "/usr/libexec" |
#define | elemcount(x) (sizeof(x)/sizeof(*(x))) |
#define | DNX_DEFAULT_SERVER_CONFIG_FILE SYSCONFDIR "/dnxServer.cfg" |
#define | DNX_DEFAULT_LOG SYSLOGDIR "/dnxsrv.log" |
#define | DNX_DEFAULT_DBGLOG SYSLOGDIR "/dnxsrv.dbg.log" |
#define | DNX_DEFAULT_SERVER LIBEXECDIR "/dnxServer" |
#define | P0R 0 |
#define | P0W 1 |
#define | P1R 2 |
#define | P1W 3 |
#define | P2R 4 |
#define | P2W 5 |
#define | PMX 6 |
Functions | |
NEB_API_VERSION (CURRENT_NEB_API_VERSION) | |
specify event broker API version (required by Nagios). | |
static void | releaseConfig (void) |
Cleanup the config file parser. | |
static int | validateCfg (DnxCfgDict *dict, void **vptrs, void *passthru) |
Validate a configuration data structure in context. | |
static int | initConfig (char *cfgfile) |
Read and parse the dnxServer configuration file. | |
static int | nagiosGetServiceCount (void) |
Return the number of services configured in Nagios. | |
static int | dnxPostResult (void *data, time_t start_time, unsigned delta, int early_timeout, int res_code, char *res_data) |
static int | GetMsgHeader (DnxMsgHeader *phdr) |
Retrieve and validate the next message's header. | |
static int | ProcessResultTransferMsg (DnxResultTransfer *result) |
Transfer a result from the server and post it to Nagios. | |
static void * | dnxResultsListener (void *arg) |
Results listener thread. | |
static int | GetAckNak (void) |
Read a single ACK/NAK from the server. | |
static int | AllocateNodeRequest (void) |
Request a client node request from the server. | |
static int | TransferJobToServer (DnxJobTransfer *job) |
Transfer a job to the dnx server. | |
static int | dnxPostNewJob (unsigned long serial, nebstruct_service_check_data *ds) |
Post a new job from Nagios to the dnx server. | |
static int | ehSvcCheck (int event_type, void *data) |
Service Check Event Handler. | |
static int | dnxCalculateJobListSize (void) |
Calculate the optimal size of the job list. | |
static int | execServerProcess (void) |
Exec a server child process with comm channels on well-known descriptors. | |
static int | terminateServerProcess (void) |
Terminate an existing server process. | |
static int | ehProcessData (int event_type, void *data) |
Process Data Event Handler. | |
static int | dnxPluginDeInit (void) |
Deinitialize the DNX Plugin. | |
static int | dnxPluginInit (void) |
Initialize the DNX plugin. | |
static int | launchScript (char *script) |
Launches an external command and waits for it to return a status code. | |
int | nebmodule_deinit (int flags, int reason) |
The main NEB module deinitialization routine. | |
int | nebmodule_init (int flags, char *args, nebmodule *handle) |
The main NEB module initialization routine. | |
Variables | |
static char * | cfgfile |
The server configuration file. | |
static DnxCfgData | cfg |
The server configuration parameters. | |
static DnxCfgParser * | parser |
The system configuration parser. | |
static time_t | start_time |
The module start time. | |
static void * | myHandle |
Private NEB module handle. | |
static regex_t | regEx |
Compiled regular expression structure. | |
static pid_t | serverpid |
Server child process id. | |
static int | outdatafd |
Pipe write channel to server. | |
static int | inackfd |
Pipe ack/nak channel from server. | |
static int | indatafd |
Pipe read channel from server. | |
static pthread_t | rlthread |
Thread handle for results listener. |
This version of the DNX Nagios Event Broker (NEB) module plugin library only implements the most basic of services required as a Nagios plugin. It starts the DNX Server as a child process, then creates a thread to listen for response data from the server. Finally, it registers a service check handler which begins to receive event service notifications.
It intercepts all service checks and dispatches them to distributed worker nodes via the DNX server child process. Communication with the child process is managed through inherited pipe file handles dup'd to well-known file descriptor numbers.
Definition in file dnxNebMain.c.
#define DNX_DEFAULT_DBGLOG SYSLOGDIR "/dnxsrv.dbg.log" |
Definition at line 101 of file dnxNebMain.c.
#define DNX_DEFAULT_LOG SYSLOGDIR "/dnxsrv.log" |
Definition at line 100 of file dnxNebMain.c.
#define DNX_DEFAULT_SERVER LIBEXECDIR "/dnxServer" |
Definition at line 102 of file dnxNebMain.c.
#define DNX_DEFAULT_SERVER_CONFIG_FILE SYSCONFDIR "/dnxServer.cfg" |
Definition at line 99 of file dnxNebMain.c.
#define elemcount | ( | x | ) | (sizeof(x)/sizeof(*(x))) |
Definition at line 97 of file dnxNebMain.c.
#define LIBEXECDIR "/usr/libexec" |
Definition at line 86 of file dnxNebMain.c.
#define P0R 0 |
#define P0W 1 |
#define P1R 2 |
#define P1W 3 |
#define P2R 4 |
#define P2W 5 |
#define PMX 6 |
#define SYSCONFDIR "/etc" |
Definition at line 78 of file dnxNebMain.c.
#define SYSLOGDIR "/var/log" |
Definition at line 82 of file dnxNebMain.c.
#define VERSION "<unknown>" |
Definition at line 74 of file dnxNebMain.c.
static int AllocateNodeRequest | ( | void | ) | [static] |
Request a client node request from the server.
Once a node request allocation has been successfully requested, it must be followed (asap) by a job transfer because the server has one on hold and is now waiting for the job to be transferred. Additionally, a node request has a timeout, and too much delay will cause it to be replaced.
Definition at line 939 of file dnxNebMain.c.
References DNX_MSG_RESERVE_NODEREQ, DNX_MSG_SIGNATURE, dnxDebug(), GetAckNak(), DnxMsgHeader::msgtype, outdatafd, DnxMsgHeader::signature, and DnxMsgHeader::structsz.
static int dnxCalculateJobListSize | ( | void | ) | [static] |
Calculate the optimal size of the job list.
Assumes the caller will actually use the returned value to allocate the job list. Based on this assumption, this routine logs messages indicating when various configuration overrides have taken effect.
Definition at line 1162 of file dnxNebMain.c.
References dnxLog(), and nagiosGetServiceCount().
static int dnxPluginDeInit | ( | void | ) | [static] |
Deinitialize the DNX Plugin.
Definition at line 1313 of file dnxNebMain.c.
References dnxLog(), ehProcessData(), ehSvcCheck(), indatafd, neb_deregister_callback(), NEBCALLBACK_PROCESS_DATA, NEBCALLBACK_SERVICE_CHECK_DATA, NEBCALLBACK_TIMED_EVENT_DATA, OK, rlthread, serverpid, and terminateServerProcess().
static int dnxPluginInit | ( | void | ) | [static] |
Initialize the DNX plugin.
Definition at line 1344 of file dnxNebMain.c.
References dnxErrorString(), dnxLog(), dnxResultsListener(), ehSvcCheck(), execServerProcess(), myHandle, neb_register_callback(), NEBCALLBACK_SERVICE_CHECK_DATA, NEBCALLBACK_TIMED_EVENT_DATA, OK, and rlthread.
static int dnxPostNewJob | ( | unsigned long | serial, | |
nebstruct_service_check_data * | ds | |||
) | [static] |
Post a new job from Nagios to the dnx server.
The payload of the job transfer structure is the address of the structure itself. This structure is allocated here, but freed when the results are collected and posted. If no result is posted, the structure address is lost.
[in] | serial | - the serial number of the new job. |
[in] | ds | - a pointer to the nagios job that's being posted. |
Definition at line 1044 of file dnxNebMain.c.
References AllocateNodeRequest(), check_result_struct::check_options, nebstruct_service_check_struct::command_line, DNX_ERR_MEMORY, check_result_struct::reschedule_check, check_result_struct::scheduled_check, nebstruct_service_check_struct::start_time, nebstruct_service_check_struct::timeout, TransferJobToServer(), and xmalloc.
static int dnxPostResult | ( | void * | data, | |
time_t | start_time, | |||
unsigned | delta, | |||
int | early_timeout, | |||
int | res_code, | |||
char * | res_data | |||
) | [static] |
Definition at line 701 of file dnxNebMain.c.
References DnxJobTransfer::chkopts, DnxJobTransfer::reschedule, DnxJobTransfer::schedule, SERVICE_CHECK_ACTIVE, STATE_UNKNOWN, DnxJobTransfer::svc, and xfree.
static void* dnxResultsListener | ( | void * | arg | ) | [static] |
Results listener thread.
Listens for the server to post results. Captures each result and posts it to the Nagios results queue.
arg | the thread routine argument. |
Definition at line 842 of file dnxNebMain.c.
References DNX_MSG_RESULT_TRANSFER, dnxLog(), GetMsgHeader(), DnxResultTransfer::hdr, DnxMsgHeader::msgtype, ProcessResultTransferMsg(), DnxMsgHeader::structsz, xfree, and xrealloc.
static int ehProcessData | ( | int | event_type, | |
void * | data | |||
) | [static] |
Process Data Event Handler.
We actually register for service check events and start the child process server program in this event handler because Nagios starts NEB modules long before it's fully configured its service check list. By waiting to initialize the server in this event handler, we have access to the number of service checks that Nagios is configured to manage, and we can thus properly configure the DNX server child process with a properly sized job queue.
[in] | event_type | - the event regarding which we were called by Nagios. |
[in] | data | - an opaque pointer to an event-specific data structure. |
Definition at line 1426 of file dnxNebMain.c.
References dnxDebug(), dnxLog(), dnxPluginDeInit(), dnxPluginInit(), ERROR, launchScript(), NEBCALLBACK_PROCESS_DATA, NEBTYPE_PROCESS_EVENTLOOPSTART, OK, DnxCfgData::syncScript, and nebstruct_process_struct::type.
static int ehSvcCheck | ( | int | event_type, | |
void * | data | |||
) | [static] |
Service Check Event Handler.
Nagios calls this routine multiple times for each service check. We only care about the INITIATE call, so we return OK for all others.
[in] | event_type | - the event type for which we're being called. |
[in] | data | - an opaque pointer to nagios event-specific data. |
Definition at line 1104 of file dnxNebMain.c.
References nebstruct_service_check_struct::command_line, DNX_OK, dnxDebug(), dnxErrorString(), dnxPostNewJob(), ERROR, DnxCfgData::localCheckPattern, NEBCALLBACK_SERVICE_CHECK_DATA, NEBERROR_CALLBACKOVERRIDE, NEBTYPE_SERVICECHECK_INITIATE, OK, regEx, nebstruct_service_check_struct::start_time, and nebstruct_service_check_struct::type.
static int execServerProcess | ( | void | ) | [static] |
Exec a server child process with comm channels on well-known descriptors.
The child process is an entirely different program, so we have to dup the pipe descriptors onto well-known descriptor numbers so the server will know where to find them. I considered using STDIO channels for this, but the server may want to use STDIO for other reasons. Too bad, because it's a perfect fit: STDIN = job xfer, STDOUT = ack/nak, and STDERR = results. If I can find a way to keep the user from configuring any logging on STDIO, I may yet convert over. The handle values are defined in the plugin main header file, so it would be simple to redefine those descriptor values.
Definition at line 1191 of file dnxNebMain.c.
References cfgfile, DNX_PLGFD, DNX_SAKFD, DNX_SRVFD, dnxCalculateJobListSize(), elemcount, inackfd, indatafd, outdatafd, P0R, P0W, P1R, P1W, P2R, P2W, PMX, DnxCfgData::serverPath, and serverpid.
static int GetAckNak | ( | void | ) | [static] |
Read a single ACK/NAK from the server.
The ack/nak is actually a DNX error code (zero on success).
Definition at line 897 of file dnxNebMain.c.
References dnxDebug(), and inackfd.
static int GetMsgHeader | ( | DnxMsgHeader * | phdr | ) | [static] |
Retrieve and validate the next message's header.
[in] | phdr | - the header buffer to be filled. |
Definition at line 747 of file dnxNebMain.c.
References DNX_ERR_UNSUPPORTED, DNX_MAX_XFER_SIZE, DNX_MSG_SIGNATURE, dnxDebug(), indatafd, DnxMsgHeader::signature, and DnxMsgHeader::structsz.
static int initConfig | ( | char * | cfgfile | ) | [static] |
Read and parse the dnxServer configuration file.
[in] | cfgfile | - the configuration file to be read. |
Definition at line 205 of file dnxNebMain.c.
References DnxCfgData::auditFilePath, DnxCfgData::debugFilePath, DnxCfgData::debugLevel, DNX_CFG_FSPATH, DNX_CFG_STRING, DNX_CFG_UNSIGNED, DNX_DEFAULT_DBGLOG, DNX_DEFAULT_LOG, DNX_DEFAULT_SERVER, dnxCfgParserCreate(), dnxCfgParserDestroy(), dnxCfgParserParse(), DnxCfgData::localCheckPattern, DnxCfgData::logFilePath, regEx, DnxCfgData::serverPath, DnxCfgData::syncScript, and validateCfg().
static int launchScript | ( | char * | script | ) | [static] |
Launches an external command and waits for it to return a status code.
[in] | script | - the command line to be launched. |
Definition at line 1388 of file dnxNebMain.c.
References DNX_ERR_INVALID, DNX_OK, and dnxLog().
static int nagiosGetServiceCount | ( | void | ) | [static] |
Return the number of services configured in Nagios.
This technique works fine as long as it's called after Nagios has had a chance to build the list. Since Nagios loads NEB modules before configuring itself, we can't call this routine until Nagios calls our ehProcessData handler.
Definition at line 256 of file dnxNebMain.c.
References service_struct::next, and service_list.
NEB_API_VERSION | ( | CURRENT_NEB_API_VERSION | ) |
specify event broker API version (required by Nagios).
int nebmodule_deinit | ( | int | flags, | |
int | reason | |||
) |
The main NEB module deinitialization routine.
This function gets called when the module is unloaded by the event broker.
[in] | flags | - nagios NEB module flags - not used. |
[in] | reason | - nagios reason code - not used. |
Definition at line 1478 of file dnxNebMain.c.
References dnxLog(), dnxPluginDeInit(), releaseConfig(), and xheapchk.
int nebmodule_init | ( | int | flags, | |
char * | args, | |||
nebmodule * | handle | |||
) |
The main NEB module initialization routine.
This function gets called when the module is loaded by the event broker.
[in] | flags | - module flags - not used |
[in] | args | - module arguments. These come from the nagios configuration file, and are passed through to the module as it loads. |
[in] | handle | - our module handle - passed from the OS to nagios as nagios loaded us. |
Definition at line 1504 of file dnxNebMain.c.
References DnxCfgData::auditFilePath, cfgfile, DnxCfgData::debugFilePath, DnxCfgData::debugLevel, DNX_DEFAULT_SERVER_CONFIG_FILE, dnxErrorString(), dnxLog(), dnxLogInit(), ehProcessData(), ERROR, initConfig(), DnxCfgData::logFilePath, myHandle, neb_register_callback(), NEBCALLBACK_PROCESS_DATA, OK, releaseConfig(), terminateServerProcess(), and VERSION.
static int ProcessResultTransferMsg | ( | DnxResultTransfer * | result | ) | [static] |
Transfer a result from the server and post it to Nagios.
[in,out] | result | - the current result structure pointer. |
Definition at line 794 of file dnxNebMain.c.
References DnxResultTransfer::delta, dnxDebug(), dnxLog(), dnxPostResult(), DnxResultTransfer::early_timeout, DnxResultTransfer::hdr, indatafd, DnxResultTransfer::payload, DnxResultTransfer::res_code, DnxResultTransfer::res_data, DnxResultTransfer::serial, DnxResultTransfer::start_time, and DnxMsgHeader::structsz.
static void releaseConfig | ( | void | ) | [static] |
Cleanup the config file parser.
Definition at line 137 of file dnxNebMain.c.
References dnxCfgParserDestroy(), DnxCfgData::localCheckPattern, and regEx.
static int terminateServerProcess | ( | void | ) | [static] |
Terminate an existing server process.
Definition at line 1290 of file dnxNebMain.c.
static int TransferJobToServer | ( | DnxJobTransfer * | job | ) | [static] |
Transfer a job to the dnx server.
A job transfer request must be preceded by an allocate client node request.
The request is larger than an integer, so we assume it can take more than one pass, but the result is an int, so we hope we can read it in one pass.
[in] | job | - the job to be transferred to the server. |
Definition at line 990 of file dnxNebMain.c.
References DNX_MSG_JOB_TRANSFER, DNX_MSG_SIGNATURE, dnxDebug(), GetAckNak(), DnxJobTransfer::hdr, DnxMsgHeader::msgtype, outdatafd, DnxMsgHeader::signature, and DnxMsgHeader::structsz.
static int validateCfg | ( | DnxCfgDict * | dict, | |
void ** | vptrs, | |||
void * | passthru | |||
) | [static] |
Validate a configuration data structure in context.
[in] | dict | - the dictionary used by the DnxCfgParser. |
[in] | vptrs | - an array of opaque objects (either pointers or values) to be checked. |
[in] | passthru | - an opaque pointer passed through from dnxCfgParserCreate. In this routine, it's the regex_t object into which we should parse the regular expression if one is given. |
Definition at line 159 of file dnxNebMain.c.
References DnxCfgData::auditFilePath, DnxCfgData::debugFilePath, DnxCfgData::debugLevel, DNX_ERR_INVALID, dnxLog(), DnxCfgData::localCheckPattern, DnxCfgData::logFilePath, DnxCfgData::serverPath, and DnxCfgData::syncScript.
DnxCfgData cfg [static] |
char* cfgfile [static] |
int inackfd [static] |
int indatafd [static] |
void* myHandle [static] |
int outdatafd [static] |
DnxCfgParser* parser [static] |
regex_t regEx [static] |
pthread_t rlthread [static] |
pid_t serverpid [static] |
time_t start_time [static] |