Browse Source

[mod_fastcgi] detect child exit, restart proactively

(instead of detecting upon a subsequent HTTP request)

(for backends spawned by mod_fastcgi)
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
64df38aad8
  1. 43
      src/mod_fastcgi.c
  2. 2
      tests/fcgi-responder.c
  3. 14
      tests/mod-fastcgi.t

43
src/mod_fastcgi.c

@ -3550,6 +3550,49 @@ TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
host = ex->hosts[n];
for (proc = host->first; proc; proc = proc->next) {
int status;
if (proc->pid == 0) continue;
switch (waitpid(proc->pid, &status, WNOHANG)) {
case 0:
/* child still running after timeout, good */
break;
case -1:
if (errno != EINTR) {
/* no PID found ? should never happen */
log_error_write(srv, __FILE__, __LINE__, "sddss",
"pid ", proc->pid, proc->state,
"not found:", strerror(errno));
}
break;
default:
/* the child should not terminate at all */
if (WIFEXITED(status)) {
if (proc->state != PROC_STATE_KILLED) {
log_error_write(srv, __FILE__, __LINE__, "sdb",
"child exited:",
WEXITSTATUS(status), proc->connection_name);
}
} else if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGTERM) {
log_error_write(srv, __FILE__, __LINE__, "sd",
"child signaled:",
WTERMSIG(status));
}
} else {
log_error_write(srv, __FILE__, __LINE__, "sd",
"child died somehow:",
status);
}
proc->pid = 0;
if (proc->state == PROC_STATE_RUNNING) host->active_procs--;
proc->state = PROC_STATE_DIED;
host->max_id--;
}
}
fcgi_restart_dead_procs(srv, p, host);
for (proc = host->unused_procs; proc; proc = proc->next) {

2
tests/fcgi-responder.c

@ -11,7 +11,7 @@
#include <string.h>
int main (void) {
int num_requests = 2;
int num_requests = 1;
while (num_requests > 0 &&
FCGI_Accept() >= 0) {

14
tests/mod-fastcgi.t

@ -7,7 +7,7 @@ BEGIN {
}
use strict;
use Test::More tests => 60;
use Test::More tests => 59;
use LightyTest;
my $tf = LightyTest->new();
@ -409,17 +409,7 @@ EOF
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
ok($tf->handle_http($t) == 0, 'killing fastcgi and wait for restart');
select(undef, undef, undef, .2);
$t->{REQUEST} = ( <<EOF
GET /index.fcgi?die-at-end HTTP/1.0
Host: www.example.org
EOF
);
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
ok($tf->handle_http($t) == 0, 'killing fastcgi and wait for restart');
select(undef, undef, undef, .2);
select(undef, undef, undef, .1) while (!$tf->listening_on(10000));
$t->{REQUEST} = ( <<EOF
GET /index.fcgi?crlf HTTP/1.0
Host: www.example.org

Loading…
Cancel
Save