From: Jeff Trawick Date: Fri, 8 Dec 2006 12:41:20 +0000 (+0000) Subject: merge from trunk: X-Git-Tag: 2.2.4~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c893b2201c7b74ad03bf3f92d299acd7be5be7b9;p=thirdparty%2Fapache%2Fhttpd.git merge from trunk: *) Fix issue which could cause piped loggers to be orphaned and never terminate after a graceful restart. PR 40651. [Joe Orton, Ruediger Pluem] Reviewed by: trawick, wrowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@483967 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6d02ff9db9a..2be0f177a7e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.4 + *) Fix issue which could cause piped loggers to be orphaned and never + terminate after a graceful restart. PR 40651. [Joe Orton, + Ruediger Pluem] + *) Fix address-in-use startup failure caused by corruption of the list of listen sockets in some configurations with multiple generic Listen directives. [Jeff Trawick] diff --git a/STATUS b/STATUS index 0fea0314dc8..6d52aab4895 100644 --- a/STATUS +++ b/STATUS @@ -90,14 +90,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: Trunk: http://svn.apache.org/viewvc?view=rev&revision=450089 +1: minfrin, jim, wrowe - * core: Orphaned piped logger process after graceful restart - PR: 40651 - Trunk version of patch: - http://svn.apache.org/viewvc?view=rev&rev=452431 - 2.2.x version of patch: - Trunk version works - +1: rpluem, trawick, wrowe - * mod_dbd: Key the storage of prepared statements on the hex string value of server_rec, rather than the server name, as the server name may change (eg when the server name is set) at any time, causing diff --git a/server/log.c b/server/log.c index 057672f2394..c027f002415 100644 --- a/server/log.c +++ b/server/log.c @@ -225,8 +225,13 @@ static void log_child_errfn(apr_pool_t *pool, apr_status_t err, "%s", description); } +/* Create a child process running PROGNAME with a pipe connected to + * the childs stdin. The write-end of the pipe will be placed in + * *FPIN on successful return. If dummy_stderr is non-zero, the + * stderr for the child will be the same as the stdout of the parent. + * Otherwise the child will inherit the stderr from the parent. */ static int log_child(apr_pool_t *p, const char *progname, - apr_file_t **fpin) + apr_file_t **fpin, int dummy_stderr) { /* Child process code for 'ErrorLog "|..."'; * may want a common framework for this, since I expect it will @@ -235,6 +240,7 @@ static int log_child(apr_pool_t *p, const char *progname, apr_status_t rc; apr_procattr_t *procattr; apr_proc_t *procnew; + apr_file_t *errfile; if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) && ((rc = apr_procattr_cmdtype_set(procattr, @@ -244,7 +250,12 @@ static int log_child(apr_pool_t *p, const char *progname, APR_NO_PIPE, APR_NO_PIPE)) == APR_SUCCESS) && ((rc = apr_procattr_error_check_set(procattr, 1)) == APR_SUCCESS) - && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS)) { + && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS) + && (!dummy_stderr + || ((rc = apr_file_open_stdout(&errfile, p)) == APR_SUCCESS + && (rc = apr_procattr_child_err_set(procattr, + errfile, + errfile)) == APR_SUCCESS))) { char **args; const char *pname; @@ -261,12 +272,21 @@ static int log_child(apr_pool_t *p, const char *progname, * close_handle_in_child() */ } + + /* apr_procattr_child_err_set dups errfile twice: close the + * remaining "parent-side" copy (apr_proc_create closes the + * other). */ + if (dummy_stderr) { + apr_file_close(procnew->err); + } } return rc; } -static int open_error_log(server_rec *s, apr_pool_t *p) +/* Open the error log for the given server_rec. If IS_MAIN is + * non-zero, s is the main server. */ +static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) { const char *fname; int rc; @@ -274,8 +294,11 @@ static int open_error_log(server_rec *s, apr_pool_t *p) if (*s->error_fname == '|') { apr_file_t *dummy = NULL; - /* This starts a new process... */ - rc = log_child (p, s->error_fname + 1, &dummy); + /* Spawn a new child logger. If this is the main server_rec, + * the new child must use a dummy stderr since the current + * stderr might be a pipe to the old logger. Otherwise, the + * child inherits the parents stderr. */ + rc = log_child(p, s->error_fname + 1, &dummy, is_main); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start ErrorLog process"); @@ -338,7 +361,7 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, apr_pool_cleanup_register(p, NULL, clear_handle_list, apr_pool_cleanup_null); - if (open_error_log(s_main, p) != OK) { + if (open_error_log(s_main, 1, p) != OK) { return DONE; } @@ -377,7 +400,7 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, } if (q == virt) { - if (open_error_log(virt, p) != OK) { + if (open_error_log(virt, 0, p) != OK) { return DONE; } } @@ -955,7 +978,7 @@ AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) apr_file_t *dummy = NULL; int rc; - rc = log_child(p, program, &dummy); + rc = log_child(p, program, &dummy, 0); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start piped log process");