Author: rjung Date: Mon Jan 5 11:07:35 2015 New Revision: 1649501 URL: http://svn.apache.org/r1649501 Log: Make sure we don't use the main mod_jk log during process shutdown in case it is piped. Write to the error log instead.
During shutdown the piped logger could already be gone and the pipe would block once the buffer gets full. Typically this does not happen, since we don't log much during shutdown. Observed in the main process during "apachectl restart" under load with logging added to process cleanup. Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c tomcat/jk/trunk/native/apache-2.0/mod_jk.c Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-1.3/mod_jk.c?rev=1649501&r1=1649500&r2=1649501&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-1.3/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-1.3/mod_jk.c Mon Jan 5 11:07:35 2015 @@ -265,6 +265,7 @@ typedef struct dir_config_struct static server_rec *main_server = NULL; static jk_logger_t *main_log = NULL; +static int main_log_is_piped = JK_FALSE; static table *jk_log_fds = NULL; static jk_worker_env_t worker_env; static char *jk_shm_file = NULL; @@ -2968,6 +2969,15 @@ static int JK_METHOD jk_log_to_file(jk_l used, what); } } + else { + /* Can't use mod_jk log any more, log to error log instead. + * Choose APLOG_ERR, since we already checked above, that if + * the mod_jk log file would still be open, we would have + * actually logged the message there + */ + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, + "%.*s", used, what); + } return JK_TRUE; } @@ -2995,6 +3005,7 @@ static void open_jk_log(server_rec *s, p const char *fname; int jklogfd; piped_log *pl; + int is_piped = JK_FALSE; jk_logger_t *jkl; jk_file_logger_t *flp; jk_server_conf_t *conf = @@ -3036,6 +3047,7 @@ static void open_jk_log(server_rec *s, p exit(1); } jklogfd = ap_piped_log_write_fd(pl); + is_piped = JK_TRUE; } else { fname = ap_server_root_relative(p, conf->log_file); @@ -3070,6 +3082,7 @@ static void open_jk_log(server_rec *s, p jk_set_time_fmt(conf->log, conf->stamp_format_string); if (main_log == NULL) main_log = conf->log; + main_log_is_piped = is_piped; return; } @@ -3568,6 +3581,17 @@ static void jk_server_cleanup(void *data static void jk_generic_cleanup(server_rec *s) { + /* If the main log is piped, we need to make sure + * it is no longer used. The external log process + * (e.g. rotatelogs) will be gone now and the pipe will + * block, once the buffer gets full + */ + if (main_log && main_log_is_piped && main_log->logger_private) { + jk_file_logger_t *p = main_log->logger_private; + if (p) { + p->log_fd = -1; + } + } if (jk_worker_properties) { jk_map_free(&jk_worker_properties); jk_worker_properties = NULL; Modified: tomcat/jk/trunk/native/apache-2.0/mod_jk.c URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-2.0/mod_jk.c?rev=1649501&r1=1649500&r2=1649501&view=diff ============================================================================== --- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original) +++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Mon Jan 5 11:07:35 2015 @@ -276,6 +276,7 @@ typedef struct apache_private_data apach static server_rec *main_server = NULL; static jk_logger_t *main_log = NULL; +static int main_log_is_piped = JK_FALSE; static apr_hash_t *jk_log_fps = NULL; static jk_worker_env_t worker_env; static apr_global_mutex_t *jk_log_lock = NULL; @@ -2642,6 +2643,17 @@ static const command_rec jk_cmds[] = { */ static apr_status_t jk_cleanup_proc(void *data) { + /* If the main log is piped, we need to make sure + * it is no longer used. The external log process + * (e.g. rotatelogs) will be gone now and the pipe will + * block, once the buffer gets full + */ + if (main_log && main_log_is_piped && main_log->logger_private) { + jk_file_logger_t *p = main_log->logger_private; + if (p) { + p->jklogfp = NULL; + } + } jk_shm_close(main_log); return APR_SUCCESS; } @@ -3217,6 +3229,15 @@ static int JK_METHOD jk_log_to_file(jk_l /* XXX: Maybe this should be fatal? */ } } + else { + /* Can't use mod_jk log any more, log to error log instead. + * Choose APLOG_ERR, since we already checked above, that if + * the mod_jk log file would still be open, we would have + * actually logged the message there + */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "%.*s", used, what); + } return JK_TRUE; } @@ -3249,6 +3270,7 @@ static int open_jklog(server_rec * s, ap apr_status_t rc; apr_file_t *jklogfp; piped_log *pl; + int is_piped = JK_FALSE; jk_logger_t *jkl; jk_file_logger_t *flp; int jklog_flags = (APR_WRITE | APR_APPEND | APR_CREATE); @@ -3281,6 +3303,7 @@ static int open_jklog(server_rec * s, ap return -1; } jklogfp = (void *)ap_piped_log_write_fd(pl); + is_piped = JK_TRUE; } else { fname = ap_server_root_relative(p, conf->log_file); @@ -3312,6 +3335,7 @@ static int open_jklog(server_rec * s, ap jk_set_time_fmt(conf->log, conf->stamp_format_string); if (main_log == NULL) { main_log = conf->log; + main_log_is_piped = is_piped; /* hgomez@20070425 */ /* Shouldn't we clean both conf->log and main_log ? */ --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org