-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Block signals during fpm master initialization #4471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,6 +109,10 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS; | |
#include "fpm_log.h" | ||
#include "zlog.h" | ||
|
||
#if HAVE_SIGNAL_H | ||
# include "fpm_signals.h" | ||
#endif | ||
|
||
#ifndef PHP_WIN32 | ||
/* XXX this will need to change later when threaded fastcgi is implemented. shane */ | ||
struct sigaction act, old_term, old_quit, old_int; | ||
|
@@ -1604,6 +1608,15 @@ int main(int argc, char *argv[]) | |
closes it. in apache|apxs mode apache | ||
does that for us! [email protected] | ||
20000419 */ | ||
|
||
/* Subset of signals from fpm_signals_init_main() to avoid unexpected death during early init | ||
or during reload just after execvp() or fork */ | ||
int init_signal_array[] = { SIGUSR1, SIGUSR2, SIGCHLD }; | ||
if (0 > fpm_signals_init_mask(init_signal_array, sizeof(init_signal_array)/sizeof(init_signal_array[0])) || | ||
0 > fpm_signals_block()) { | ||
zlog(ZLOG_WARNING, "Could die in the case of too early reload signal"); | ||
} | ||
zlog(ZLOG_DEBUG, "Blocked some signals"); | ||
#endif | ||
#endif | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--TEST-- | ||
Concurrent reload signals should not kill PHP-FPM master process. (Bug: #74083) | ||
--SKIPIF-- | ||
<?php | ||
include "skipif.inc"; | ||
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); | ||
?> | ||
--FILE-- | ||
<?php | ||
|
||
require_once "tester.inc"; | ||
|
||
$cfg = <<<EOT | ||
[global] | ||
error_log = {{FILE:LOG}} | ||
pid = {{FILE:PID}} | ||
process_control_timeout=1 | ||
[unconfined] | ||
listen = {{ADDR}} | ||
ping.path = /ping | ||
ping.response = pong | ||
pm = dynamic | ||
pm.max_children = 5 | ||
pm.start_servers = 1 | ||
pm.min_spare_servers = 1 | ||
pm.max_spare_servers = 1 | ||
EOT; | ||
|
||
$code = <<<EOT | ||
<?php | ||
/* empty */ | ||
EOT; | ||
|
||
$tester = new FPM\Tester($cfg, $code); | ||
$tester->start(); | ||
$tester->expectLogStartNotices(); | ||
$tester->ping('{{ADDR}}'); | ||
|
||
/* Vary interval between concurrent reload requests | ||
since performance of test instance is not known in advance */ | ||
$max_interval = 25000; | ||
$step = 1000; | ||
$pid = $tester->getPid(); | ||
for ($interval = 0; $interval < $max_interval; $interval += $step) { | ||
exec("kill -USR2 $pid", $out, $killExitCode); | ||
if ($killExitCode) { | ||
echo "ERROR: master process is dead\n"; | ||
break; | ||
} | ||
usleep($interval); | ||
} | ||
echo "Reached interval $interval us with $step us steps\n"; | ||
$tester->expectLogNotice('Reloading in progress ...'); | ||
/* Consume mix of 'Reloading in progress ...' and 'reloading: .*' */ | ||
$tester->getLogLines(2000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test spends 2 seconds here due to timeout. Test will be unreliable with exact number of lines since number of actual reloads may vary. Reload may be interrupted issued only a part of logs. More careful analysis of output requires reimplementation of functions like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I will try to find some time to take a look on this so we can remove the slow test flag... |
||
|
||
$tester->signal('USR2'); | ||
$tester->expectLogNotice('Reloading in progress ...'); | ||
$tester->expectLogNotice('reloading: .*'); | ||
$tester->expectLogNotice('using inherited socket fd=\d+, "127.0.0.1:\d+"'); | ||
$tester->expectLogStartNotices(); | ||
$tester->ping('{{ADDR}}'); | ||
|
||
$tester->terminate(); | ||
$tester->expectLogTerminatingNotices(); | ||
$tester->close(); | ||
|
||
?> | ||
Done | ||
--EXPECT-- | ||
Reached interval 25000 us with 1000 us steps | ||
Done | ||
--CLEAN-- | ||
<?php | ||
require_once "tester.inc"; | ||
FPM\Tester::clean(); | ||
?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice that
HAVE_SIGNAL_H
has been removed in 7.4 5f89157There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in the rebase...