Page 1 of 1

Re: [Nagios-devel] NDO utils bug/explanation

Posted: Tue Sep 22, 2009 6:24 am
by Guest
This is a multi-part message in MIME format.

------_=_NextPart_001_01CA3B55.A9FF800E
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hi Michael

=20

Thank you very much for the explanations. Finally I found the problem,
it was a Nagios issue, too many reload where interrupting data flow.

Now everything works very well.

By

Marco

=20

From: Michael Friedrich [mailto:[email protected]]=20
Sent: domenica 20 settembre 2009 2.34
To: Nagios Developers List
Subject: Re: [Nagios-devel] NDO utils bug/explanation

=20

Hi,

Frassinelli, Marco wrote:=20

Hello

The process of starting ndo2db and then Nagios makes sure that there is
actual data within the DB. If there is an outdated data within the DB it
needs to be removed before Nagios even sends new data. So the process of
trimming those table entries is truly intentional at the beginning
(so-called pre-launch state where the if condition matches). If ndo2db
fails for some reason, those data will remain within the database and
then removed during the next start.=20

Ok, when the parent ndo2db process starts. But not when
the child starts.

Considering the fact that the process runs daemonized and forks a child
for each ndomod client connection, that is truly wrong. See the NDOUtils
documentation page 8:
http://www.scribd.com/doc/17608352/Nagios-NDOUtils

Going deeper into the code in ndo2db.c:main you will recognize that
after initialization stuff that the standalone daemon condition matches.

/* standalone daemon... */
else{

/* create socket and wait for clients to connect */
if(ndo2db_wait_for_connections()=3D=3DNDO_ERROR)
return 1;
}

This function opens the socket wether tcp or unix. Then the parent forks
a child to handle client data (0 =3D everythings ok, -1 =3D error).

/* fork... */
new_pid=3Dfork();

switch(new_pid){
[...]
case 0:
#endif
/* child processes data... */
ndo2db_handle_client_connection(new_sd);

/* close socket when we're done */
close(new_sd);
#ifndef DEBUG_NDO2DB
return NDO_OK;
break;
[...]
}

Parent runs in a while loop and if child has died on the client
connection, it forks a new one.
The child then reads the data from the socket within
ndo2db_handle_client_connection. If there's nothing on the socket, the
client connection was lost and the while(1) terminates (also on errors),
meaning the child to terminate too. The child performs the memory
cleanup and db disconnect and then the process of the parent accepting
new client connection and forking a child for each client connection
starts again.=20
Just look that up in the code, it's quite nice commented.=20

/* check for completed lines of input */
ndo2db_check_for_client_input(&idi,&dbuf);

This function also decides if the actual client needs to be
disconnected. So there are 3 main options that can lead to the
termination of the child:

* socket read result fails with -1, eagain/eintr ->
http://linux.die.net/man/2/read
* socket read is empty
* client input is wrong protocol (idi->disconnect_client)

If one line has been read from the socket, it comes to
ndo2db_handle_client_input where the data frame is analyzed. If clients
protocol (ndomod) doesn't match ndo2db protocol, client will be
disconnected and data ignored.

/* client is using wrong protocol version, bail
out here... */
=
if(idi->protocol_version!=3DNDO_API_PROTOVERSION){
syslog(LOG_USER|LOG_INFO,"Error: Client
protocol version %d is incompatible with server version %d.
Disconnecting client...",idi->protocol_version,NDO_API_PROTOVERSION);
idi->disconnect_client=3DNDO_TRUE;
idi->ignore_client_data=3DNDO_TRUE;
return NDO_ERROR;
}

Other data will be read, parsed and saved by type as idi->buffered_input
... If the data section is complete given by =
data_type=3D=3DNDO_API_ENDDATA
then ndo2db_end_input_data will be called wherein the dbhandling starts
e.g.

case NDO2DB_INPUT_DATA_PROGRAMSTATUSDATA:
result=3Dndo2db_handle_programstatusdata(idi);
break;

values for the dbquery will be read
(dbhandler.c:,ndo2db_handle_programstatusdata) and then the queries are
sent to db - currently MySQL

...[email truncated]...


This post was automatically imported from historical nagios-devel mailing list archives
Original poster: ichael Friedrich [mailto:[email protected]]=2