httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dgau...@hyperreal.org
Subject cvs commit: apache-1.3/src/main http_main.c
Date Sat, 14 Feb 1998 12:17:30 GMT
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