From: Eric Covener Date: Tue, 17 Mar 2015 20:12:19 +0000 (+0000) Subject: Retry ENOENT like ECONNREFUSED, but only near a server restart. X-Git-Tag: 2.5.0-alpha~3372 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c27569bfd3bc1b4562588fb8161e22788cea24a7;p=apache Retry ENOENT like ECONNREFUSED, but only near a server restart. PR57685 Submitted By: Edward Lu Committed By: covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1667385 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index b19045cead..93577cd773 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ Changes with Apache 2.5.0 to a local URL-path with the INCLUDES filter active, introduced in 2.4.11. PR 57531. [Yann Ylavic] + *) mod_cgid: Within the first minute of a server start or restart, + allow mod_cgid to retry connecting to its daemon process. Previously, + 'No such file or directory: unable to connect to cgi daemon...' could + be logged without an actual retry. PR57685. + [Edward Lu ] + *) core: Cleanup the request soon/even if some output filter fails to handle the EOR bucket. [Yann Ylavic] diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 50cc883067..2a0e94db5a 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -170,6 +170,10 @@ static int is_scriptaliased(request_rec *r) #define DEFAULT_CONNECT_ATTEMPTS 15 #endif +#ifndef DEFAULT_CONNECT_STARTUP_DELAY +#define DEFAULT_CONNECT_STARTUP_DELAY 60 +#endif + typedef struct { const char *logname; long logbytes; @@ -1203,18 +1207,26 @@ static int connect_to_daemon(int *sdptr, request_rec *r, { int sd; int connect_tries; + int connect_errno; apr_interval_time_t sliding_timer; connect_tries = 0; sliding_timer = 100000; /* 100 milliseconds */ while (1) { + connect_errno = 0; ++connect_tries; if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, APLOGNO(01255) "unable to create socket to cgi daemon"); } if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { - if (errno == ECONNREFUSED && connect_tries < DEFAULT_CONNECT_ATTEMPTS) { + /* Save errno for later */ + connect_errno = errno; + /* ECONNREFUSED means the listen queue is full; ENOENT means that + * the cgid server either hasn't started up yet, or we're pointing + * at the wrong socket file */ + if ((errno == ECONNREFUSED || errno == ENOENT) && + connect_tries < DEFAULT_CONNECT_ATTEMPTS) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, APLOGNO(01256) "connect #%d to cgi daemon failed, sleeping before retry", connect_tries); @@ -1235,9 +1247,20 @@ static int connect_to_daemon(int *sdptr, request_rec *r, close_unix_socket, apr_pool_cleanup_null); break; /* we got connected! */ } + + /* If we didn't find the socket but the server was not recently restarted, + * chances are there's something wrong with the cgid daemon + */ + if (connect_errno == ENOENT && + apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > + DEFAULT_CONNECT_STARTUP_DELAY) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, + apr_pstrcat(r->pool, APLOGNO(02831) "ScriptSock ", sockname, " does not exist", NULL)); + } + /* gotta try again, but make sure the cgid daemon is still around */ - if (kill(daemon_pid, 0) != 0) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01258) + if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258) "cgid daemon is gone; is Apache terminating?"); } }