Mailing List Archive

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
- <Pine.LNX.3.96dg4.980413204700.6322R-100000@twinlark.arctic.org>
- [PATCH] <199805022019.QAA01941@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);