diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-15 11:49:34 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-15 11:52:07 +0100 |
commit | e67ced158a0cac42f6b89a18552dbd69c8f67c54 (patch) | |
tree | 2f1bba002d8cba7255c1ddd264268b6de73e6a87 | |
parent | cc77b892b58494b3795d044b26d9c02e92ebc8f4 (diff) | |
download | rspamd-e67ced158a0cac42f6b89a18552dbd69c8f67c54.tar.gz rspamd-e67ced158a0cac42f6b89a18552dbd69c8f67c54.zip |
[Fix] Try to deal with multiple workers terminated
-rw-r--r-- | src/rspamd.c | 109 |
1 files changed, 55 insertions, 54 deletions
diff --git a/src/rspamd.c b/src/rspamd.c index 9bea4b5c0..5692e315b 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -917,73 +917,74 @@ rspamd_cld_handler (gint signo, short what, gpointer arg) /* Turn off locking for logger */ rspamd_log_nolock (rspamd_main->logger); - msg_debug_main ("catch SIGCHLD signal, finding terminated worker"); + msg_debug_main ("catch SIGCHLD signal, finding terminated workers"); /* Remove dead child form children list */ - wrk = waitpid (0, &res, 0); - if ((cur = - g_hash_table_lookup (rspamd_main->workers, - GSIZE_TO_POINTER (wrk))) != NULL) { - /* Unlink dead process from queue and hash table */ - - g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER ( - wrk)); - - if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { - /* Normal worker termination, do not fork one more */ - msg_info_main ("%s process %P terminated normally", - g_quark_to_string (cur->type), - cur->pid); - } - else { - if (WIFSIGNALED (res)) { + while ((wrk = waitpid (0, &res, WNOHANG)) > 0) { + if ((cur = + g_hash_table_lookup (rspamd_main->workers, + GSIZE_TO_POINTER (wrk))) != NULL) { + /* Unlink dead process from queue and hash table */ + + g_hash_table_remove (rspamd_main->workers, GSIZE_TO_POINTER ( + wrk)); + + if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { + /* Normal worker termination, do not fork one more */ + msg_info_main ("%s process %P terminated normally", + g_quark_to_string (cur->type), + cur->pid); + } + else { + if (WIFSIGNALED (res)) { #ifdef WCOREDUMP - if (WCOREDUMP (res)) { + if (WCOREDUMP (res)) { + msg_warn_main ( + "%s process %P terminated abnormally by signal: %d" + " and created core file", + g_quark_to_string (cur->type), + cur->pid, + WTERMSIG (res)); + } + else { + msg_warn_main ( + "%s process %P terminated abnormally by signal: %d" + " but NOT created core file", + g_quark_to_string (cur->type), + cur->pid, + WTERMSIG (res)); + } +#else msg_warn_main ( - "%s process %P terminated abnormally by signal: %d" - " and created core file", + "%s process %P terminated abnormally by signal: %d", g_quark_to_string (cur->type), cur->pid, WTERMSIG (res)); +#endif } else { - msg_warn_main ( - "%s process %P terminated abnormally by signal: %d" - " but NOT created core file", + msg_warn_main ("%s process %P terminated abnormally " + "with exit code %d", g_quark_to_string (cur->type), cur->pid, - WTERMSIG (res)); + WEXITSTATUS (res)); } -#else - msg_warn_main ( - "%s process %P terminated abnormally by signal: %d", - g_quark_to_string (cur->type), - cur->pid, - WTERMSIG (res)); -#endif - } - else { - msg_warn_main ("%s process %P terminated abnormally " - "with exit code %d", - g_quark_to_string (cur->type), - cur->pid, - WEXITSTATUS (res)); + /* Fork another worker in replace of dead one */ + rspamd_check_core_limits (rspamd_main); + rspamd_fork_delayed (cur->cf, cur->index, rspamd_main); } - /* Fork another worker in replace of dead one */ - rspamd_check_core_limits (rspamd_main); - rspamd_fork_delayed (cur->cf, cur->index, rspamd_main); - } - event_del (&cur->srv_ev); - /* We also need to clean descriptors left */ - close (cur->control_pipe[0]); - close (cur->srv_pipe[0]); - g_free (cur); - } - else { - for (i = 0; i < other_workers->len; i++) { - if (g_array_index (other_workers, pid_t, i) == wrk) { - g_array_remove_index_fast (other_workers, i); - msg_info_main ("related process %P terminated", wrk); + event_del (&cur->srv_ev); + /* We also need to clean descriptors left */ + close (cur->control_pipe[0]); + close (cur->srv_pipe[0]); + g_free (cur); + } + else { + for (i = 0; i < other_workers->len; i++) { + if (g_array_index (other_workers, pid_t, i) == wrk) { + g_array_remove_index_fast (other_workers, i); + msg_info_main ("related process %P terminated", wrk); + } } } } |