Bug #76930 [NEW]: SIGQUIT with process_control_timeout doesn't properly kill idle children
| From: | giovanni at giacobbi dot net | Date: | Mon, 24 Sep 2018 21:06:35 +0000 |
| Subject: | Bug #76930 [NEW]: SIGQUIT with process_control_timeout doesn't properly kill idle children | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-217223@lists.php.net to get a copy of this message | ||
From: giovanni at giacobbi dot net
Operating system: Linux
PHP version: 7.2.10
Package: FPM related
Bug Type: Bug
Bug description:SIGQUIT with process_control_timeout doesn't properly kill idle children
Description:
------------
php-fpm spawns a series of workers, these workers can be gracefully
stopped by enabling "process_control_timeout", which grants a grace
period when SIGQUIT is received to complete the ongoing task before
terminating the process.
Unfortunately, there are a series of bug which cause a freshly started
daemon to needlessly hang until the timeout expires.
First problem: SA_RESTART flag causes SIGQUIT to be ignored until first
request
The master process sets up signal handling in function
fpm_signals_init_child(), setting the SA_RESTART flag.
The SIGQUIT handler causes a flag (in_shutdown) inside fastcgi.c, but
this flag is not checked if the worker is blocked inside the accept()
syscall.
This problem is solved by removing the following line from
fpm_signals.c:
act.sa_flags |= SA_RESTART;
Second problem: (bug-in-a-bug) php_request_shutdown() doesn't properly
restore the initial worker process state
The "First problem" occurs only before the worker executed any PHP
script, because after that the call to php_request_startup() causes
signals handlers to be redefined inside the Zend engine (zend_signal.c),
which define them WITHOUT the SA_RESTART flag.
I believe that for consistency the dual function php_request_shutdown()
should restore the signal handlers as they were before the execution of
the PHP script, to "return" to the original state.
Third problem: Idle clients prevent the worker from gracefully
terminate
If a worker is holding an open FCGI socket with a worker, this worker
won't gracefull terminate even though it is not executing any PHP
script.
This behaviour is unneeded and an idle client can be safely dropped.
If you are interested in solving the three problems above I can provide
a pull request, I might need some help with the second point to avoid
breaking other SAPIs while modifying the zend internal behaviour.
Test script:
---------------
1) Freshly start php-fpm with some workers with process_control_timeout
eg. 60s
2) Issue a SIGQUIT to the parent process when all workers are idle (and
before they handled any request)
Expected result:
----------------
All FPM processes should terminate immediately (since they are idle)
Actual result:
--------------
Processes wait until process_control_timeout to terminate
--
Edit bug report at https://bugs.php.net/bug.php?id=76930&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=76930&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=76930&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=76930&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=76930&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=76930&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=76930&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=76930&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=76930&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=76930&r=support
Expected behavior: https://bugs.php.net/fix.php?id=76930&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=76930&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=76930&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=76930&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76930&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=76930&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=76930&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=76930&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=76930&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=76930&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=76930&r=mysqlcfg