From: Tim W. <tim...@gm...> - 2005-01-20 06:04:50
|
All, I'd like to have your input on the following problem: whenever things go wrong in perfparsed (usually a problem with the database), the application will exit immediately. In the case of perfparsed using the pipe method as input, this has a very nasty side-effect on Nagios: every process sending data to the pipe never ends, and Nagios's check latency times start to skyrocket. This behaviour is not seen when you manually kill perfparsed. In an attempt to figure out why the 'kill' does not induce the same effect on Nagios, I concluded that the reason is that kill sends a SIGTERM to perfparsed, which is nicely handled in log_reader.c. The sighandler _closes all log sources_. A simple exit somewehere in the application does not, and subsequent write attempts to the pipe are hanging (blocked). Question 1: is my conclusion correct? Question 2: if so, is there any way you can catch an exit call with a signal handler? Or should you use something like raise(SIGxxx) instead of exit? (Q3: has anyone else experienced this problem?) Regards, Tim |
From: Yves <yme...@pe...> - 2005-01-20 10:36:23
|
> In an attempt to figure out why the 'kill' does not induce the same > effect on Nagios, I concluded that the reason is that kill sends a > SIGTERM to perfparsed, which is nicely handled in log_reader.c. The > sighandler _closes all log sources_. > A simple exit somewehere in the application does not, and subsequent > write attempts to the pipe are hanging (blocked). > > Question 1: is my conclusion correct? I am not sure, but I would say yes. > Question 2: if so, is there any way you can catch an exit call with a > signal handler? Or should you use something like raise(SIGxxx) instead > of exit? Yes, and it is already implemented. We use atexit() to catch the exit call. When you kill the application, there is a signal handling, that only wait= for the end of critical operations before the normal behaviour that is leaving graciousl= y. When perfparsed exit, there are places where we cannot work with the atex= it() registered functions. So it does not exits with exit() but with _exit(). Maybe this = is where to change things ? But I have a better idea : what about creating our own exit() function, t= hat call the functions we register with atexit() ? And don't use exit(), _exit() and a= texit() at all ? This is some big development. Tim and Ben (and others) could you check if what I say is correct ? How m= uch work it represents ? If this is not too hard, maybe Bruno and Remi can do it ? (they have not been introduced yet, but I'm waiting that they manage to i= nstall nagios and perfparse : they began 2 days ago). > (Q3: has anyone else experienced this problem?) Maybe you should ask nagios mailing-list about this, to know if somebody = had this problem and how they solved it ? However, the bug is in perfparse, not in= nagios, and it has to be fixed in perfparse. Yves --=20 - Homepage - http://ymettier.free.fr - http://www.logicacmg.com - - GPG key - http://ymettier.free.fr/gpg.txt - - Maitretarot - http://www.nongnu.org/maitretarot/ - - Perfparse - http://perfparse.sf.net/ - |
From: Tim W. <tim...@gm...> - 2005-01-20 13:04:18
|
FYI: I tried to register my own atexit function in perfparsed, that calls storage_atexit & close_all_log_sources. Unfortunately, this function gets called serveral times (each time a forked subprocess exits), and hence it does not do what you'd want. I'm not experienced enough in this matter to figure out how to get the exit handler to run only when the main process exits. If you have an idea how to do this, let me know, and I'll try it to see if it fixes this problem. Tim On Thu, 20 Jan 2005 11:36:16 +0100 (CET), Yves <yme...@pe...> wrote: > > In an attempt to figure out why the 'kill' does not induce the same > > effect on Nagios, I concluded that the reason is that kill sends a > > SIGTERM to perfparsed, which is nicely handled in log_reader.c. The > > sighandler _closes all log sources_. > > A simple exit somewehere in the application does not, and subsequent > > write attempts to the pipe are hanging (blocked). > > > > Question 1: is my conclusion correct? > > I am not sure, but I would say yes. > > > Question 2: if so, is there any way you can catch an exit call with a > > signal handler? Or should you use something like raise(SIGxxx) instead > > of exit? > > Yes, and it is already implemented. > We use atexit() to catch the exit call. > > When you kill the application, there is a signal handling, that only wait for the end of > critical operations before the normal behaviour that is leaving graciously. > > When perfparsed exit, there are places where we cannot work with the atexit() registered > functions. So it does not exits with exit() but with _exit(). Maybe this is where to > change things ? > But I have a better idea : what about creating our own exit() function, that call the > functions we register with atexit() ? And don't use exit(), _exit() and atexit() at all > ? > This is some big development. > > Tim and Ben (and others) could you check if what I say is correct ? How much work it > represents ? If this is not too hard, maybe Bruno and Remi can do it ? > (they have not been introduced yet, but I'm waiting that they manage to install nagios > and perfparse : they began 2 days ago). > > > (Q3: has anyone else experienced this problem?) > > Maybe you should ask nagios mailing-list about this, to know if somebody had this > problem and how they solved it ? However, the bug is in perfparse, not in nagios, and it > has to be fixed in perfparse. > > Yves > -- > - Homepage - http://ymettier.free.fr - http://www.logicacmg.com - > - GPG key - http://ymettier.free.fr/gpg.txt - > - Maitretarot - http://www.nongnu.org/maitretarot/ - > - Perfparse - http://perfparse.sf.net/ - > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > Tool for open source databases. Create drag-&-drop reports. Save time > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > _______________________________________________ > Perfparse-devel mailing list > Per...@li... > https://lists.sourceforge.net/lists/listinfo/perfparse-devel > |
From: Yves <yme...@pe...> - 2005-01-20 13:22:08
|
The registered atexit() functions are inherited by subprocesses. I found = that problem when I coded periodic cleanup procedures. Now you find that problem too. Maybe it's time to think of a smarter way to exit ? Reimplement exit() with a way to remove atexit() handlers ? I found no wa= y to remove a handler that was registered with atexit. If you know one, maybe all what = I say below is N/A ? :) Here is what I suggest (I hope Remi and Bruno have had time to subscribe = to this list) 1/ Implement a basic pp_exit() function : void pp_exit(void) { exit(); } 2/ Replace *all* calls to exit() with pp_exit(). Don't make a macro for t= hat. It has to be a real replacement. 3/ Make a macro for exit() for security : void unexpected_exit(void) { pp_log(..., "This is a bug : this function should not have been called"= ); exit() } #define exit unexpected_exit Any programmer who would then use exit() (because they don't necessarily = know about pp_exit) would generate this message. 4/ work on pp_exit() in order to make it do what we want. Also remove the= calls to atexit() and do something else. Tim, I don't have an idea for a shorter way for you to test. And I think = this change is necessary, at least for perfparsed. > FYI: > I tried to register my own atexit function in perfparsed, that calls > storage_atexit & close_all_log_sources. > Unfortunately, this function gets called serveral times (each time a > forked subprocess exits), and hence it does not do what you'd want. > I'm not experienced enough in this matter to figure out how to get the > exit handler to run only when the main process exits. If you have an > idea how to do this, let me know, and I'll try it to see if it fixes > this problem. > > Tim --=20 - Homepage - http://ymettier.free.fr - http://www.logicacmg.com - - GPG key - http://ymettier.free.fr/gpg.txt - - Maitretarot - http://www.nongnu.org/maitretarot/ - - Perfparse - http://perfparse.sf.net/ - |
From: Tim W. <tim...@gm...> - 2005-01-20 14:12:52
|
On Thu, 20 Jan 2005 14:22:03 +0100 (CET), Yves <yme...@pe...> wrote: > The registered atexit() functions are inherited by subprocesses. I found that problem > when I coded periodic cleanup procedures. > Now you find that problem too. > Maybe it's time to think of a smarter way to exit ? > Reimplement exit() with a way to remove atexit() handlers ? I found no way to remove a > handler that was registered with atexit. If you know one, maybe all what I say below is > N/A ? :) > > Here is what I suggest (I hope Remi and Bruno have had time to subscribe to this list) > 1/ Implement a basic pp_exit() function : > void pp_exit(void) { > exit(); > } void pp_exit(int status) preferably. > > 2/ Replace *all* calls to exit() with pp_exit(). Don't make a macro for that. It has to > be a real replacement. there are around 50 exit calls :) > > 3/ Make a macro for exit() for security : > void unexpected_exit(void) { > pp_log(..., "This is a bug : this function should not have been called"); > exit() > } > #define exit unexpected_exit > > Any programmer who would then use exit() (because they don't necessarily know about > pp_exit) would generate this message. > > 4/ work on pp_exit() in order to make it do what we want. Also remove the calls to > atexit() and do something else. In the case of this problem: if the main process finishes, you should call close_all_log_sources, but any subproces that exits should not do this. perhaps pp_exit can do different things depending on the status flag. So I have a feeling this will not be trivial. > > Tim, I don't have an idea for a shorter way for you to test. And I think this change is > necessary, at least for perfparsed. I agree. Tim. > > > > FYI: > > I tried to register my own atexit function in perfparsed, that calls > > storage_atexit & close_all_log_sources. > > Unfortunately, this function gets called serveral times (each time a > > forked subprocess exits), and hence it does not do what you'd want. > > I'm not experienced enough in this matter to figure out how to get the > > exit handler to run only when the main process exits. If you have an > > idea how to do this, let me know, and I'll try it to see if it fixes > > this problem. > > > > Tim > > > -- > - Homepage - http://ymettier.free.fr - http://www.logicacmg.com - > - GPG key - http://ymettier.free.fr/gpg.txt - > - Maitretarot - http://www.nongnu.org/maitretarot/ - > - Perfparse - http://perfparse.sf.net/ - > > ------------------------------------------------------- > This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting > Tool for open source databases. Create drag-&-drop reports. Save time > by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. > Download a FREE copy at http://www.intelliview.com/go/osdn_nl > _______________________________________________ > Perfparse-devel mailing list > Per...@li... > https://lists.sourceforge.net/lists/listinfo/perfparse-devel > |
From: Yves <yme...@pe...> - 2005-01-20 15:40:49
|
>> 1/ Implement a basic pp_exit() function : >> void pp_exit(void) { >> exit(); >> } > > void pp_exit(int status) > preferably. Yes of course. In the future, it could become pp_exit(int status, int par= am) where param is an int or can be something else (like what to close and what not to cl= ose). Depends on what we need. >> 2/ Replace *all* calls to exit() with pp_exit(). Don't make a macro fo= r that. It has >> to >> be a real replacement. > > there are around 50 exit calls :) OK. Much work, but can be done. >> 4/ work on pp_exit() in order to make it do what we want. Also remove = the calls to >> atexit() and do something else. > > In the case of this problem: if the main process finishes, you should > call close_all_log_sources, but any subproces that exits should not do > this. perhaps pp_exit can do different things depending on the status > flag. So I have a feeling this will not be trivial. With pp_exit, it can become trivial, with the use of additionnal paramete= rs to pp_exit. You can think of a binary OR of options to say what pp_exit should do and= should not do. For example : pp_exit(EXIT_FAILURE, CLOSE_ALL | WRITE_A_NICE_MESSAGE_IN_THE_LOG | DO_NOT_REMOVE_THE_PIPE); Yves --=20 - Homepage - http://ymettier.free.fr - http://www.logicacmg.com - - GPG key - http://ymettier.free.fr/gpg.txt - - Maitretarot - http://www.nongnu.org/maitretarot/ - - Perfparse - http://perfparse.sf.net/ - |