You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@hyperreal.org on 1998/05/03 19:17:01 UTC

cvs commit: apache-1.3/src/main http_log.c http_main.c

jim         98/05/03 10:17:01

  Modified:    .        STATUS
               src      CHANGES
               src/include httpd.h
               src/main http_log.c http_main.c
  Log:
  Submitted by:	Jim Jagielski
  Reviewed by:	Dean Gaudet, Ralf Engelschall
  If a child exits with a status of APEXIT_CHILDFATAL, the main httpd
  process will see this as a "things are totally hosed" and do a server
  abort, shutting down completely. This is to prevent situations where child
  errors prevent the server from running correctly and filling the logs
  up with messages.
  
  Revision  Changes    Path
  1.355     +2 -8      apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.354
  retrieving revision 1.355
  diff -u -r1.354 -r1.355
  --- STATUS	1998/05/03 16:46:47	1.354
  +++ STATUS	1998/05/03 17:16:56	1.355
  @@ -83,6 +83,8 @@
       * Ben's WIN32: Extensive overhaul of the way UNCs are handled.
       * Ralf's fix for referer/agent log entries in installed httpd.conf, PR#2175
       * Jim's fix for MIME type case sensitivity disparity, PR#2112
  +    * Child processes can now "signal" to the parent process that
  +      it (the parent process) should abort, shutting down the server.
   
   Available Patches:
   
  @@ -147,14 +149,6 @@
         errors.  The respective flush_funcs also need to be exercised.
          o Jim's looked over the ap_snprintf() stuff (the changes that Dean
            did to make thread-safe) and they look fine.
  -
  -    * The fatal errors that the children detect and fill up the log with
  -      (such as bogus group id) need to be stopped.  The proposed fix is to
  -      make the child exit with a special code when a fatal error occurs; the
  -      parent would then abort.  See
  -      <Pi...@twinlark.arctic.org>
  -      [PATCH] <19...@devsys.jaguNET.com>
  -      Status: Jim, Dean +1, Ralf +1
   
       * The DoS issue about symlinks to /dev/zero is still present.
         A device checker patch had been sent to the list a while ago.
  
  
  
  1.811     +5 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.810
  retrieving revision 1.811
  diff -u -r1.810 -r1.811
  --- CHANGES	1998/05/03 16:46:48	1.810
  +++ CHANGES	1998/05/03 17:16:57	1.811
  @@ -1,5 +1,10 @@
   Changes with Apache 1.3b7
   
  +  *) Child processes can now "signal" (by exiting with a status
  +     of APEXIT_CHILDFATAL) the parent process to abort and
  +     shutdown the server if the error in the child process was
  +     fatal enough. [Jim Jagielski]
  +
     *) mod_autoindex's find_itme() was sensitive to MIME type case.
        [Jim Jagielski] PR#2112
   
  
  
  
  1.207     +21 -0     apache-1.3/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v
  retrieving revision 1.206
  retrieving revision 1.207
  diff -u -r1.206 -r1.207
  --- httpd.h	1998/04/19 20:10:45	1.206
  +++ httpd.h	1998/05/03 17:16:58	1.207
  @@ -301,6 +301,27 @@
   #endif
   
   /*
  + * Special Apache error codes. These are basically used
  + *  in http_main.c so we can keep track of various errors.
  + *
  + *   APEXIT_OK:
  + *     A normal exit
  + *   APEXIT_INIT:
  + *     A fatal error arising during the server's init sequence
  + *   APEXIT_CHILDINIT:
  + *     The child died during it's init sequence
  + *   APEXIT_CHILDFATAL:
  + *     A fatal error, resulting in the whole server aborting.
  + *     If a child exits with this error, the parent process
  + *     considers this a server-wide fatal error and aborts.
  + *                 
  + */
  +#define APEXIT_OK		0x0
  +#define APEXIT_INIT		0x2
  +#define APEXIT_CHILDINIT	0x3
  +#define APEXIT_CHILDFATAL	0xf
  +
  +/*
    * (Unix, OS/2 only)
    * Interval, in microseconds, between scoreboard maintenance.  During
    * each scoreboard maintenance cycle the parent decides if it needs to
  
  
  
  1.55      +1 -0      apache-1.3/src/main/http_log.c
  
  Index: http_log.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_log.c,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- http_log.c	1998/04/27 22:38:05	1.54
  +++ http_log.c	1998/05/03 17:16:59	1.55
  @@ -177,6 +177,7 @@
       execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
   #endif    
       exit (1);
  +    /* NOT REACHED */
       return(child_pid);
   }
   
  
  
  
  1.329     +51 -40    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.328
  retrieving revision 1.329
  diff -u -r1.328 -r1.329
  --- http_main.c	1998/05/02 11:15:11	1.328
  +++ http_main.c	1998/05/03 17:17:00	1.329
  @@ -404,10 +404,10 @@
   	break;
       case 0:
   	fprintf(stderr, "didn't get lock\n");
  -	exit(-1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       case -1:
   	perror("ussetlock");
  -	exit(-1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -415,7 +415,7 @@
   {
       if (usunsetlock(uslock) == -1) {
   	perror("usunsetlock");
  -	exit(-1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -464,27 +464,27 @@
       fd = open("/dev/zero", O_RDWR);
       if (fd == -1) {
   	perror("open(/dev/zero)");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       accept_mutex = (pthread_mutex_t *) mmap((caddr_t) 0, sizeof(*accept_mutex),
   				 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
       if (accept_mutex == (void *) (caddr_t) - 1) {
   	perror("mmap");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       close(fd);
       if ((errno = pthread_mutexattr_init(&mattr))) {
   	perror("pthread_mutexattr_init");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       if ((errno = pthread_mutexattr_setpshared(&mattr,
   						PTHREAD_PROCESS_SHARED))) {
   	perror("pthread_mutexattr_setpshared");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       if ((errno = pthread_mutex_init(accept_mutex, &mattr))) {
   	perror("pthread_mutex_init");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       sigfillset(&accept_block_mask);
       sigdelset(&accept_block_mask, SIGHUP);
  @@ -499,12 +499,12 @@
   
       if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) {
   	perror("sigprocmask(SIG_BLOCK)");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
       if ((err = pthread_mutex_lock(accept_mutex))) {
   	errno = err;
   	perror("pthread_mutex_lock");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
       have_accept_mutex = 1;
   }
  @@ -516,7 +516,7 @@
       if ((err = pthread_mutex_unlock(accept_mutex))) {
   	errno = err;
   	perror("pthread_mutex_unlock");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
       /* There is a slight race condition right here... if we were to die right
        * now, we'd do another pthread_mutex_unlock.  Now, doing that would let
  @@ -584,12 +584,12 @@
       sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
       if (sem_id < 0) {
   	perror("semget");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       ick.val = 1;
       if (semctl(sem_id, 0, SETVAL, ick) < 0) {
   	perror("semctl(SETVAL)");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       if (!getuid()) {
   	/* restrict it to use only by the appropriate user_id ... not that this
  @@ -601,7 +601,7 @@
   	ick.buf = &buf;
   	if (semctl(sem_id, 0, IPC_SET, ick) < 0) {
   	    perror("semctl(IPC_SET)");
  -	    exit(1);
  +	    exit(APEXIT_INIT);
   	}
       }
       ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
  @@ -619,7 +619,7 @@
   {
       if (semop(sem_id, &op_on, 1) < 0) {
   	perror("accept_mutex_on");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -627,7 +627,7 @@
   {
       if (semop(sem_id, &op_off, 1) < 0) {
   	perror("accept_mutex_off");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -662,7 +662,7 @@
       if (lock_fd == -1) {
   	perror("open");
   	fprintf(stderr, "Cannot open lock file: %s\n", ap_lock_fname);
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       unlink(ap_lock_fname);
   }
  @@ -680,7 +680,7 @@
   		    "fcntl: F_SETLKW: Error getting accept lock, exiting!  "
   		    "Perhaps you need to use the LockFile directive to place "
   		    "your lock file on a local disk!");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -696,7 +696,7 @@
   		    "fcntl: F_SETLKW: Error freeing accept lock, exiting!  "
   		    "Perhaps you need to use the LockFile directive to place "
   		    "your lock file on a local disk!");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -720,7 +720,7 @@
       if (lock_fd == -1) {
   	ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
   		    "Child cannot open lock file: %s\n", ap_lock_fname);
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDINIT);
       }
   }
   
  @@ -736,7 +736,7 @@
       if (lock_fd == -1) {
   	ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
   		    "Parent cannot open lock file: %s\n", ap_lock_fname);
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
   }
  @@ -751,7 +751,7 @@
       if (ret < 0) {
   	ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
   		    "flock: LOCK_EX: Error getting accept lock. Exiting!");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -760,7 +760,7 @@
       if (flock(lock_fd, LOCK_UN) < 0) {
   	ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
   		    "flock: LOCK_UN: Error freeing accept lock. Exiting!");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   }
   
  @@ -1419,7 +1419,7 @@
       m = (caddr_t) create_shared_heap("\\SHAREMEM\\SCOREBOARD", SCOREBOARD_SIZE);
       if (m == 0) {
   	fprintf(stderr, "httpd: Could not create OS/2 Shared memory pool.\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
   
       rc = _uopen((Heap_t) m);
  @@ -1438,7 +1438,7 @@
       m = (caddr_t) get_shared_heap("\\SHAREMEM\\SCOREBOARD");
       if (m == 0) {
   	fprintf(stderr, "httpd: Could not find existing OS/2 Shared memory pool.\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
   
       rc = _uopen((Heap_t) m);
  @@ -1488,19 +1488,19 @@
       fd = shm_open(ap_scoreboard_fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
       if (fd == -1) {
   	perror("httpd: could not open(create) scoreboard");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       if (ltrunc(fd, (off_t) SCOREBOARD_SIZE, SEEK_SET) == -1) {
   	perror("httpd: could not ltrunc scoreboard");
   	shm_unlink(ap_scoreboard_fname);
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       if ((m = (caddr_t) mmap((caddr_t) 0,
   			    (size_t) SCOREBOARD_SIZE, PROT_READ | PROT_WRITE,
   			    MAP_SHARED, fd, (off_t) 0)) == (caddr_t) - 1) {
   	perror("httpd: cannot mmap scoreboard");
   	shm_unlink(ap_scoreboard_fname);
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       close(fd);
       ap_register_cleanup(p, NULL, cleanup_shared_mem, ap_null_cleanup);
  @@ -1544,7 +1544,7 @@
       if (m == (caddr_t) - 1) {
   	perror("mmap");
   	fprintf(stderr, "httpd: Could not mmap memory\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
   #else
   /* Sun style */
  @@ -1554,14 +1554,14 @@
       if (fd == -1) {
   	perror("open");
   	fprintf(stderr, "httpd: Could not open /dev/zero\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       m = mmap((caddr_t) 0, SCOREBOARD_SIZE,
   	     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
       if (m == (caddr_t) - 1) {
   	perror("mmap");
   	fprintf(stderr, "httpd: Could not mmap /dev/zero\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       close(fd);
   #endif
  @@ -1594,7 +1594,7 @@
   #endif
   	ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
   		    "could not call shmget");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
   
       ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf,
  @@ -1647,7 +1647,7 @@
   		shmid);
       }
       if (ap_scoreboard_image == BADSHMAT)	/* now bailout */
  -	exit(1);
  +	exit(APEXIT_INIT);
   
   #ifdef MOVEBREAK
       if (obrk == (char *) -1)
  @@ -1742,7 +1742,7 @@
       if (scoreboard_fd == -1) {
   	perror(ap_scoreboard_fname);
   	fprintf(stderr, "Cannot open scoreboard file:\n");
  -	exit(1);
  +	exit(APEXIT_INIT);
       }
       ap_register_cleanup(p, NULL, cleanup_scoreboard_file, ap_null_cleanup);
   
  @@ -2507,7 +2507,7 @@
   			 "getpwuid: couldn't determine user name from uid %u, "
   			 "you probably need to modify the User directive",
   			 (unsigned)uid);
  -		exit(1);
  +		clean_child_exit(APEXIT_CHILDFATAL);
   	    }
   
   	    name = ent->pw_name;
  @@ -2524,20 +2524,20 @@
   	    ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
   			"initgroups: unable to set groups for User %s "
   			"and Group %u", name, (unsigned)ap_group_id);
  -	    exit(1);
  +	    clean_child_exit(APEXIT_CHILDFATAL);
   	}
   #ifdef MULTIPLE_GROUPS
   	if (getgroups(NGROUPS_MAX, group_id_list) == -1) {
   	    ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
   			"getgroups: unable to get group list");
  -	    exit(1);
  +	    clean_child_exit(APEXIT_CHILDFATAL);
   	}
   #endif
   	if (setgid(ap_group_id) == -1) {
   	    ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
   			"setgid: unable to set group id to Group %u",
   			(unsigned)ap_group_id);
  -	    exit(1);
  +	    clean_child_exit(APEXIT_CHILDFATAL);
   	}
   #endif
       }
  @@ -3150,7 +3150,7 @@
       if (!geteuid() && setuid(ap_user_id) == -1) {
   	ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
   		    "setuid: unable to change uid");
  -	clean_child_exit(1);
  +	clean_child_exit(APEXIT_CHILDFATAL);
       }
   #endif
   
  @@ -3823,7 +3823,18 @@
   	     * extra child
   	     */
   	    if (pid >= 0) {
  -		/* Child died... note that it's gone in the scoreboard. */
  +	        /* Child died... if it died due to a fatal error,
  +		 * we should simply bail out.
  +		 */
  +		if ((WIFEXITED(status)) &&
  +		   WEXITSTATUS(status) == APEXIT_CHILDFATAL) {
  +		    ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
  +				 "Child %d returned a Fatal error... \n"
  +				 "Apache is exiting!",
  +				 pid);
  +		    exit(APEXIT_CHILDFATAL);
  +		}
  +		/* non-fatal death... note that it's gone in the scoreboard. */
   		ap_sync_scoreboard_image();
   		child_slot = find_child_by_pid(pid);
   		Explain2("Reaping child %d slot %d", pid, child_slot);