You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Vladislav Malyshkin <ma...@mail1.nai.net> on 2000/04/08 03:30:01 UTC
Re: mod_jserv/5755: mod_jserv and httpd -HUP restarting problem
The following reply was made to PR mod_jserv/5755; it has been noted by GNATS.
From: Vladislav Malyshkin <ma...@mail1.nai.net>
To: Neil_Mckee@inmon.com, apbugs@apache.org, ed@cloudfactory.org
Cc:
Subject: Re: mod_jserv/5755: mod_jserv and httpd -HUP restarting problem
Date: Fri, 07 Apr 2000 21:23:32 -0400
>
> We were seeing the same problem - where multiple SIGHUPs
> cause mod_jserv to lose track. I tried changing
> /etc/logrotate.d/apache to use "kill -HUP `cat /var/run/httpd.pid`"
> instead of "killall -HUP httpd" but that only seems
> to work if only one log is being rotated.
>
It also fails to rotate if you send several
kill -HUP `cat /var/run/httpd.pid`
(when you send next -HUP while the server is processing previos -HUP)
This is precisely what happenes when you rotate sevaral apache logs.
For each log roateted logrotate send a -HUP signal.
And while apache processes -HUP sent after access_log was rotated
it receives -HUP caused by error_log rotation.
This kills the watchdog of JVM and you get a runaway JVM.
This is the patch I use to fix this problem.
It fixes this runaway problem.
Also, even if you have a runaway JVM this
modification of watchdog will send an EXIT command to it,
so it will not be a problem even in this case.
Vladislav
The patch is:
--- ApacheJServ-1.1/src/c/jserv_wrapper_unix.c.orig Mon Feb 14 16:16:11 2000
+++ ApacheJServ-1.1/src/c/jserv_wrapper_unix.c Tue Mar 7 13:54:28 2000
@@ -84,6 +84,10 @@
/* Signal handler for SIGTERM (standalone wrapper), and for Apache 1.2, for
* when the parent Apache process dies. JServ should kill the JVM. */
void wrapper_shutdown(int x) {
+ signal(SIGTERM, wrapper_shutdown);
+ signal(SIGHUP, wrapper_shutdown);
+ signal(SIGALRM, wrapper_shutdown);
+
jserv_error(JSERV_LOG_INFO, wrapper_data->config,
"Wrapper: Shutting down JServ (PID=%d) (sig %d)",getpid(), x);
/* Cleanup this thing */
@@ -98,10 +102,12 @@
/* this is also used from the loop to kill JVM */
void kill_hung_jvm(int signum) {
int counter = 0;
-
+ const int jvm_pid_local=jvm_pid;
+
/* Is jvm is really started? If not - do nothing */
- if( jvm_pid == 0)
+ if( jvm_pid_local == 0)
return;
+ jvm_pid=0;
if( signum == 0) {
jserv_error(JSERV_LOG_INFO, wrapper_data->config,
@@ -112,18 +118,17 @@
}
/* IF JVM is not responding to connections, we can't do *
* anything but kill it. */
- kill(jvm_pid, SIGTERM);
+ kill(jvm_pid_local, SIGTERM);
/* give the VM as long as five seconds to die gracefully */
while (counter++ < 5) {
- if (waitpid(jvm_pid, NULL, WNOHANG) > 0)
+ if (waitpid(jvm_pid_local, NULL, WNOHANG) > 0)
break;
sleep(1);
}
- if( waitpid(jvm_pid,NULL,WNOHANG)==0 ) {
- kill(jvm_pid, SIGKILL);
+ if( waitpid(jvm_pid_local,NULL,WNOHANG)==0 ) {
+ kill(jvm_pid_local, SIGKILL);
}
- jvm_pid=0;
}
@@ -193,12 +198,13 @@
if (proc!=0) return proc;
/* Sleep two seconds waiting for first init to finish and to kill this
- * process - TODO remove this and find a nicer soulution to doublestart */
- sleep(3);
-
/* If we get a TERM signal, shut down the JVM nicely, then exit.
*/
signal(SIGTERM, wrapper_shutdown);
+ signal(SIGHUP, wrapper_shutdown);
+
+ /* process - TODO remove this and find a nicer soulution to doublestart */
+ sleep(3);
x = 5;
while (binparams != NULL) {
@@ -340,10 +346,11 @@
/* Check every second */
while (1) {
sighandler_t old_handler;
+ int ping_result;
#ifndef JSERV_STANDALONE
/* did parent httpd die? */
- if(getppid() == 1) {
+ if(getppid() <=1 ) {
jserv_error(JSERV_LOG_INFO,wrapper_data->config,
"wrapper: Apache exited, cleaning up (PID=%d)",
getpid());
@@ -373,19 +380,32 @@
in many places.
*/
alarm(wrapper_data->config->vmtimeout);
-
- /* check if we can communicate to JVM */
- if( jvm_pid != 0 && jserv_protocol_function(wrapper_data->config->protocol,wrapper_data->config,
- JSERV_PING,NULL) == JSERV_FUNC_COMMERROR) {
-
- /* Note that it's harmless that this function is called twice
- in case of timeout
- */
- kill_hung_jvm(0);
-
- }
+ ping_result=jserv_protocol_function(
+ wrapper_data->config->protocol,wrapper_data->config,
+ JSERV_PING,NULL);
+
+ if(ping_result==JSERV_FUNC_COMMERROR)
+ {
+ if(jvm_pid != 0)
+ {
+ /* Note that it's harmless that this function is called twice
+ in case of timeout
+ */
+ kill_hung_jvm(0);
+ }
+ }
+ else if(jvm_pid == 0)
+ {
+
+ signal( SIGALRM, kill_hung_jvm);
+ /* Send shutdown function to a runaway JVM. */
+ jserv_protocol_function(
+ wrapper_data->config->protocol,wrapper_data->config,
+ JSERV_SHUTDOWN,NULL);
+ }
+
/* Remove the signal, no matter if it was used or not */
alarm(0);
@@ -477,30 +497,33 @@
/* ========================================================================= */
/* This does the actual cleanup */
int wrapper_shutdown_core(wrapper_config *cfg) {
- if (jvm_pid != 0) {
+
+ const int jvm_pid_local=jvm_pid;
+ if (jvm_pid_local != 0) {
int counter = 0;
+ jvm_pid=0;
jserv_error(JSERV_LOG_INFO,wrapper_data->config,
"wrapper: Terminating JServ (PID=%d, VM PID=%d)",
- getpid(), jvm_pid);
+ getpid(), jvm_pid_local);
/* Send shutdown function */
jserv_protocol_function(cfg->config->protocol,cfg->config,
JSERV_SHUTDOWN,NULL);
/* Wait for child to go down */
- while (waitpid(jvm_pid,NULL,WNOHANG)==0) {
+ while (waitpid(jvm_pid_local,NULL,WNOHANG)==0) {
/* give it a little while to shut down gracefully. Then kill it. */
if (++counter > cfg->config->vmtimeout) {
jserv_error(JSERV_LOG_EMERG, wrapper_data->config,
"wrapper: JServ (%d) didn't die nicely, killing it",
- jvm_pid);
- kill(jvm_pid, SIGTERM); /* give the process a chance to die */
+ jvm_pid_local);
+ kill(jvm_pid_local, SIGTERM); /* give the process a chance to die */
counter = 0;
while (counter++ < 3) {
- if (waitpid(jvm_pid, NULL, WNOHANG) > 0)
+ if (waitpid(jvm_pid_local, NULL, WNOHANG) > 0)
return 0;
sleep(1);
}
- if( waitpid(jvm_pid,NULL,WNOHANG)==0 ) {
- kill(jvm_pid, SIGKILL);
+ if( waitpid(jvm_pid_local,NULL,WNOHANG)==0 ) {
+ kill(jvm_pid_local, SIGKILL);
}
}
sleep(1);
>
>