httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject cvs commit: apache-1.3/src/main http_main.c (fwd)
Date Sat, 14 Feb 1998 12:21:56 GMT
I would like to backport this patch to 1.2 and apply it for 1.2.6.  But
before I do that I need more input from folks running other architectures.
So can folks do something like:

grep '(client socket)\|(listen)' error_log | sed -e 's#.*\]##' | sort | uniq -c

and send the output here?

I'm completely convinced that our current code for errno on accept()
and select() couldn't be more wrong, see the PRs mentioned.  Dying on all
errnos except EINTR wouldn't be terribly bad (they should be infrequent
or something is really wrong), so I don't think what I've done here
is unreasonable.

Dean

---------- Forwarded message ----------
Date: 14 Feb 1998 12:17:30 -0000
From: dgaudet@hyperreal.org
To: apache-1.3-cvs@hyperreal.org
Subject: cvs commit: apache-1.3/src/main http_main.c
Reply-To: new-httpd@apache.org

dgaudet     98/02/14 04:17:30

  Modified:    src      CHANGES
               src/main http_main.c
  Log:
  Deal gracefully with unexpected accept() and select() errors in the
  child_main() loop.  This was built based on data from a bunch of PRs,
  and data from the new-httpd archives, nh.9603 and nh.9701 in particular.
  
  I've actually been running with the extra errno tests for linux for
  the past 6 or 7 months.  Without them there is a LOT of spam in the
  error log on a linux box, compared to none on a solaris box on the
  same segment.
  
  PR:             1747, 1107, 588, 1787
  
  Revision  Changes    Path
  1.631     +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.630
  retrieving revision 1.631
  diff -u -r1.630 -r1.631
  --- CHANGES	1998/02/14 10:54:39	1.630
  +++ CHANGES	1998/02/14 12:17:26	1.631
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3b6
   
  +  *) Various errors from select() and accept() in child_main() would
  +     result in an infinite loop.  It seems these two tickle kernel
  +     or library bugs occasionally, and result in log spammage and
  +     a generally bad scene.  Now the child exits immediately,
  +     which seems to be a good workaround.
  +     [Dean Gaudet] PR#1747, 1107, 588, 1787
  +
     *) Cleaned up some race conditions in unix child_main during
        initialization. [Dean Gaudet]
   
  
  
  
  1.289     +62 -15    apache-1.3/src/main/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v
  retrieving revision 1.288
  retrieving revision 1.289
  diff -u -r1.288 -r1.289
  --- http_main.c	1998/02/14 10:54:41	1.288
  +++ http_main.c	1998/02/14 12:17:28	1.289
  @@ -3032,14 +3032,14 @@
   		srv = ap_select(listenmaxfd + 1, &main_fds, NULL, NULL, NULL);
   
   		if (srv < 0 && errno != EINTR) {
  -#ifdef LINUX
  -		    if (errno == EFAULT) {
  -			aplog_error(APLOG_MARK, APLOG_ERR, server_conf,
  -				    "select: (listen) fatal, child exiting");
  -			clean_child_exit(1);
  -		    }
  -#endif
  +		    /* Single Unix documents select as returning errnos
  +		     * EBADF, EINTR, and EINVAL... and in none of those
  +		     * cases does it make sense to continue.  In fact
  +		     * on Linux 2.0.x we seem to end up with EFAULT
  +		     * occasionally, and we'd loop forever due to it.
  +		     */
   		    aplog_error(APLOG_MARK, APLOG_ERR, server_conf, "select: (listen)");
  +		    clean_child_exit(1);
   		}
   
   		if (srv <= 0)
  @@ -3075,15 +3075,62 @@
   		break;		/* We have a socket ready for reading */
   	    else {
   
  -#if defined(EPROTO) && defined(ECONNABORTED)
  -		if ((errno != EPROTO) && (errno != ECONNABORTED))
  -#elif defined(EPROTO)
  -		    if (errno != EPROTO)
  -#elif defined(ECONNABORTED)
  -			if (errno != ECONNABORTED)
  +		/* Our old behaviour here was to continue after accept()
  +		 * errors.  But this leads us into lots of troubles
  +		 * because most of the errors are quite fatal.  For
  +		 * example, EMFILE can be caused by slow descriptor
  +		 * leaks (say in a 3rd party module, or libc).  It's
  +		 * foolish for us to continue after an EMFILE.  We also
  +		 * seem to tickle kernel bugs on some platforms which
  +		 * lead to never-ending loops here.  So it seems best
  +		 * to just exit in most cases.
  +		 */
  +                switch (errno) {
  +#ifdef EPROTO
  +		    /* EPROTO on certain older kernels really means
  +		     * ECONNABORTED, so we need to ignore it for them.
  +		     * See discussion in new-httpd archives nh.9701
  +		     * search for EPROTO.
  +		     *
  +		     * Also see nh.9603, search for EPROTO:
  +		     * There is potentially a bug in Solaris 2.x x<6,
  +		     * and other boxes that implement tcp sockets in
  +		     * userland (i.e. on top of STREAMS).  On these
  +		     * systems, EPROTO can actually result in a fatal
  +		     * loop.  But we don't deal with that.
  +		     */
  +                case EPROTO:
  +#endif
  +#ifdef ECONNABORTED
  +                case ECONNABORTED:
  +#endif
  +		    /* Linux generates the rest of these, other tcp
  +		     * stacks (i.e. bsd) tend to hide them behind
  +		     * getsockopt() interfaces.  They occur when
  +		     * the net goes sour or the client disconnects
  +		     * after the three-way handshake has been done
  +		     * in the kernel but before userland has picked
  +		     * up the socket.
  +		     */
  +#ifdef ECONNRESET
  +                case ECONNRESET:
  +#endif
  +#ifdef ETIMEDOUT
  +                case ETIMEDOUT:
   #endif
  -			    aplog_error(APLOG_MARK, APLOG_ERR, server_conf,
  -					"accept: (client socket)");
  +#ifdef EHOSTUNREACH
  +		case EHOSTUNREACH:
  +#endif
  +#ifdef ENETUNREACH
  +		case ENETUNREACH:
  +#endif
  +                    break;
  +
  +		default:
  +		    aplog_error(APLOG_MARK, APLOG_ERR, server_conf,
  +				"accept: (client socket)");
  +		    clean_child_exit(1);
  +		}
   	    }
   
   	    /* go around again, safe to die */
  
  
  


Mime
View raw message