You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Marc Slemko <ma...@znep.com> on 1997/02/14 08:19:20 UTC
[PATCH] revised death wish on HUP patch
Happy with this one?
I'm not happy about the unconditional sleep(2), but the only other option
is to block until the child exits but that is what we are trying to avoid.
A timeout in the waitpid() would be better, but I don't think it is
practical right now.
I have tested this patch, but not on a server that has the problem. I
will probably do that tomorrow.
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.118
diff -c -r1.118 http_main.c
*** http_main.c 1997/02/10 21:22:20 1.118
--- http_main.c 1997/02/14 07:12:16
***************
*** 1011,1025 ****
void reclaim_child_processes ()
{
! int i, status;
int my_pid = getpid();
sync_scoreboard_image();
- for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
- int pid = scoreboard_image->servers[i].pid;
! if (pid != my_pid && pid != 0)
! waitpid (scoreboard_image->servers[i].pid, &status, 0);
}
}
--- 1011,1081 ----
void reclaim_child_processes ()
{
! int i, status, childhung = 1, tries = 0;
int my_pid = getpid();
+ int waitret;
sync_scoreboard_image();
! /* need short pause to have some hope that the child processes
! * have had a chance to exit. Unfortunate because it slows
! * down all HUPs a small bit, but while blocking while waiting
! * for the child to die avoids this, it can cause hangs.
! */
! sleep(2);
!
! /* sometimes child processes don't get the SIGHUP. We need to be
! * sure that we don't block waiting for the child to die of
! * natural causes; first try nicely to kill it, then get
! * nasty and do everything we can to make it die.
! */
! while (childhung && tries <=4) {
! childhung = 0;
! for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
! int pid = scoreboard_image->servers[i].pid;
!
! if (pid != my_pid && pid != 0) {
! waitret = waitpid(pid, &status, WNOHANG);
! if (waitret == 0) {
! childhung++;
! switch (tries) {
! case 0:
! /* first time through, we assume it is just slow */
! log_printf(server_conf, "child process %d did not exit (just slow?), will try again", pid);
! break;
! case 1:
! /* perhaps it missed the SIGHUP, lets try again */
! log_printf(server_conf, "child process %d did not exit, sending another SIGHUP", pid);
! kill(pid, SIGHUP);
! break;
! case 2:
! /* ok, now it's being annoying */
! log_printf(server_conf, "child process %d still did not exit, sending a SIGTERM", pid);
! kill(pid, SIGTERM);
! break;
! case 3:
! /* die child scum */
! log_printf(server_conf, "child process %d still did not exit, sending a SIGKILL", pid);
! kill(pid, SIGKILL);
! break;
! case 4:
! /* gave it our best shot, but alas... If this really
! * is a child we are trying to kill and it really hasn't
! * exited, we will likely fail to bind to the port
! * after the restart.
! */
! log_printf(server_conf, "could not make child process %d exit, attempting to continue anyway", pid);
! break;
! }
! } else {
! /* child gone, delete from scoreboard so
! * we don't worry about it any more */
! update_child_status(i,SERVER_DEAD,NULL);
! }
! }
! }
! if (childhung) sleep(3);
! tries++;
}
}
Re: [PATCH] revised death wish on HUP patch
Posted by Marc Slemko <ma...@znep.com>.
On Fri, 14 Feb 1997, Chuck Murcko wrote:
> Marc Slemko wrote:
> >
> > Happy with this one?
> >
> > I'm not happy about the unconditional sleep(2), but the only other option
> > is to block until the child exits but that is what we are trying to avoid.
> > A timeout in the waitpid() would be better, but I don't think it is
> > practical right now.
> >
> > I have tested this patch, but not on a server that has the problem. I
> > will probably do that tomorrow.
> >
> -1. Sleep(2)?
I welcome any other options but I don't see any; if we don't sleep a
little bit before starting to kill, we will be almost always logging
errors that a child didn't exit.
We can not block on kill because that does cause hangs. I'm not sure that
a timeout is overly nice to implement at this stage.
Re: [PATCH] revised death wish on HUP patch
Posted by Chuck Murcko <ch...@topsail.org>.
Marc Slemko wrote:
>
> Happy with this one?
>
> I'm not happy about the unconditional sleep(2), but the only other option
> is to block until the child exits but that is what we are trying to avoid.
> A timeout in the waitpid() would be better, but I don't think it is
> practical right now.
>
> I have tested this patch, but not on a server that has the problem. I
> will probably do that tomorrow.
>
-1. Sleep(2)?
--
chuck
Chuck Murcko
The Topsail Group, West Chester PA USA
chuck@topsail.org
Re: [PATCH] revised death wish on HUP patch
Posted by Paul Richards <p....@elsevier.co.uk>.
Paul Sutton <pa...@ukweb.com> writes:
> On 14 Feb 1997, Paul Richards wrote:
> > When I looked at the problem with signal handling a few months ago I
> > thought I commented on the fact that the children are *not* passed a
> > signal at all. They are allowed to die naturally when they finish
> > processing the request. Are we changing that model? I've been trying to
> > catch up on two weeks mail (annual accounts audit and Phd viva both the
> > same week!) so I've skimmed quite a lot recently and might not be up to
> > speed on the problem. Someone want to give me a quick summary?
>
> Erm, I thought Apache had always sent the children HUPs to kill em
> immediately, which was the reason why graceful restarts are needed -- to
> let transfers in progress finish.
I was confused. It was SIGUSR1 that I was looking at a few months ago
not SIGHUP.
--
Dr Paul Richards. Originative Solutions Ltd. (Netcraft Ltd. contractor)
Elsevier Science TIS online journal project.
Email: p.richards@elsevier.co.uk
Phone: 0370 462071 (Mobile), +44 (0)1865 843155
Re: [PATCH] revised death wish on HUP patch
Posted by Paul Sutton <pa...@ukweb.com>.
On 14 Feb 1997, Paul Richards wrote:
> When I looked at the problem with signal handling a few months ago I
> thought I commented on the fact that the children are *not* passed a
> signal at all. They are allowed to die naturally when they finish
> processing the request. Are we changing that model? I've been trying to
> catch up on two weeks mail (annual accounts audit and Phd viva both the
> same week!) so I've skimmed quite a lot recently and might not be up to
> speed on the problem. Someone want to give me a quick summary?
Erm, I thought Apache had always sent the children HUPs to kill em
immediately, which was the reason why graceful restarts are needed -- to
let transfers in progress finish.
At the moment the parent
1 Sends a -HUP to the children (in the process group)
2 Closes the bound sockets
3 Opens the bound sockets
4 Re-makes the children
The problem is that if a child doesn't die before 3, the bind fails and
Apache dies (no children). Not good. This patch tries harder to kill the
children, by extending part 1:
1a Send -HUP to children in process group
1b Send a -HUP to any children still alive, and wait 3 seconds
1c Send a -TERM to any children still alive, and wait 3 seconds
1d Send a -KILL to any children skill alive, and wait 3 seconds
Parts 1b, 1c and 1d are only done if there are still children hanging
around.
This reduces the change of Apache-death during a routine HUP, which
is a good thing.
//pcs
Re: [PATCH] revised death wish on HUP patch
Posted by Marc Slemko <ma...@znep.com>.
On 14 Feb 1997, Paul Richards wrote:
> Marc Slemko <ma...@znep.com> writes:
>
> >
> > Happy with this one?
>
> When I looked at the problem with signal handling a few months ago I
> thought I commented on the fact that the children are *not* passed a
> signal at all. They are allowed to die naturally when they finish
> processing the request. Are we changing that model? I've been trying to
> catch up on two weeks mail (annual accounts audit and Phd viva both the
> same week!) so I've skimmed quite a lot recently and might not be up to
> speed on the problem. Someone want to give me a quick summary?
Incorrect. If they were allowed to die naturally, they would not do so
until they reached their limit on requests served per child. The process
group is sent a HUP. Sometimes that is lost or blocked for whatever
reason. When that happens, in moderate load environments (normally see it
when I start getting about a hundred and mumble children) the server
essentially hangs until the child that didn't get the HUP finishes
processing its maxrequests; the parent will block forever on the child
process. This just avoids that; normally no more signals should be sent,
but if the child doesn't exit within an arbitrary time limit then we get
nasty.
Re: [PATCH] revised death wish on HUP patch
Posted by Paul Richards <p....@elsevier.co.uk>.
Marc Slemko <ma...@znep.com> writes:
>
> Happy with this one?
When I looked at the problem with signal handling a few months ago I
thought I commented on the fact that the children are *not* passed a
signal at all. They are allowed to die naturally when they finish
processing the request. Are we changing that model? I've been trying to
catch up on two weeks mail (annual accounts audit and Phd viva both the
same week!) so I've skimmed quite a lot recently and might not be up to
speed on the problem. Someone want to give me a quick summary?
--
Dr Paul Richards. Originative Solutions Ltd. (Netcraft Ltd. contractor)
Elsevier Science TIS online journal project.
Email: p.richards@elsevier.co.uk
Phone: 0370 462071 (Mobile), +44 (0)1865 843155