On Thu, Jan 22, 2004 at 05:02:50PM -0600, Ben Collins-Sussman wrote:
...
> * for some reason, the 'rotatelogs' process dies. It's not clear
> whether it's responding to a signal, or if the httpd parent is
> killing it, or what. A new 'rotatelogs' takes its place, with new
> httpd children connecting to it. Meanwhile, the "old" httpd child
> continues to service svn, and continues to write logdata to a dead
> pipe... there's nobody reading data from the pipe on the other end
> anymore!
It is SIGTERMed by the parent on a restart, yes.
> * Eventually the pipe fills up, and the httpd child just hangs
> trying to write to it.
Nice, this is easy enough to reproduce. It only fills up because the
httpd children all have the read end of the pipe open, which is a bug in
itself. Applying below ensures that the pipe gets closed when the piped
logger exits, and so writes() fail with ETERM rather than blocking up in
the leftover children.
To fix this properly, I suppose piped loggers should not get SIGTERMed
during a graceful restart, they should read till EOF then exit(0): then
when the last child attached to the piped logger for a particular
generation quits, the pipe is closed and the piped logger terminates
gracefully too, without losing log messages.
Index: server/log.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/log.c,v
retrieving revision 1.140
diff -u -r1.140 log.c
--- server/log.c 12 Jan 2004 22:48:08 -0000 1.140
+++ server/log.c 23 Jan 2004 14:02:38 -0000
@@ -865,8 +865,6 @@
static apr_status_t piped_log_cleanup_for_exec(void *data)
{
piped_log *pl = data;
-
- apr_file_close(ap_piped_log_read_fd(pl));
apr_file_close(ap_piped_log_write_fd(pl));
return APR_SUCCESS;
}
@@ -905,6 +903,7 @@
errno = save_errno;
return NULL;
}
+ apr_file_close(ap_piped_log_read_fd(pl));
return pl;
}