From: aglarond at gmail dot com
Operating system: SmartOS, possibly others
PHP version: Irrelevant
Package: FPM related
Bug Type: Bug
Bug description:no max file descriptor check for events.mechanism = /dev/poll
Description:
------------
When using PHP-FPM with 'events.mechanism = /dev/poll' and 'pm = dynamic',
we noticed that the log would fill with lines like the following:
WARNING: pid 61603, fpm_event_devpoll_wait(), line 166: /dev/poll: ioctl()
returns 22
The line referenced refers to sapi/fpm/fpm/events/devpoll.c:
159 /* wait for inconming event or timeout */
160 ret = ioctl(dpfd, DP_POLL, &dopoll);
161
162 if (ret < 0) {
163
164 /* trigger error unless signal interrupt */
165 if (errno != EINTR) {
166 zlog(ZLOG_WARNING, "/dev/poll: ioctl() returns
%d", errno);
167 return -1;
168 }
169 }
Unfortunately, these log entries didn't help us to solve the problem. They
only served to fill the disk, as they were written as quickly as the I/O
subsystem allowed.
What did help narrow down the problem was seeing the following entry:
DEBUG: pid 61603, fpm_event_init_main(), line 333: event module is
/dev/poll and 1061 fds have been reserved
It seemed we had reached a watermark, as the default maximum number of file
descriptors on this system is 1024:
NAME PRIVILEGE VALUE FLAG ACTION
RECIPIENT
process.max-file-descriptor
basic 1.02K - deny
57203
privileged 65.5K - deny
-
system 2.15G max deny
-
Increasing the number of file descriptors makes the log entries go away:
NAME PRIVILEGE VALUE FLAG ACTION
RECIPIENT
process.max-file-descriptor
basic 65.5K - deny
70867
privileged 65.5K - deny
-
system 2.15G max deny
-
I propose prefacing the errno check (line 165) with one for EBADF. I don't
have time to write and test a patch right now, to verify that errno is
indeed EBADF in this case (error number 22 is EINVAL, but I suspect this is
getting passed from the device driver). The patch should make this check
and then probably end the main process.
An alternative is to change fpm_event_init_main in
sapi/fpm/fpm/fpm_events.c to end the main process at file descriptor
reservation time:
323 /* count the max number of necessary fds for polling */
324 max = 1; /* only one FD is necessary at startup for the master
process signal pipe */
325 for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
326 if (!wp->config) continue;
327 if (wp->config->catch_workers_output &&
wp->config->pm_max_children > 0) {
328 max += (wp->config->pm_max_children * 2);
329 }
330 }
331
332 if (module->init(max) < 0) {
333 zlog(ZLOG_ERROR, "Unable to initialize the event module
%s", module->name);
334 return -1;
335 }
336
337 zlog(ZLOG_DEBUG, "event module is %s and %d fds have been
reserved", module->name, max);
338
Briefly looking at devpool's init function shows checks for allocating
enough memory, but doesn't seem to check if the max file descriptors can
actually be allocated. Ideally, a check should be made at this point to
see if an OS limit will be hit before even initializing the module. I
don't know if there are any module-specific semantics that would need to be
taken into account and preclude a general check in fpm_event_init_main.
The relevant code paths are unchanged for 5.3.27, 5.4.20, 5.5.4, so marking
this as version Irrelevant.
--
Edit bug report at https://bugs.php.net/bug.php?id=65774&edit=1
--
Try a snapshot (PHP 5.4):
https://bugs.php.net/fix.php?id=65774&r=trysnapshot54
Try a snapshot (PHP 5.3):
https://bugs.php.net/fix.php?id=65774&r=trysnapshot53
Try a snapshot (trunk):
https://bugs.php.net/fix.php?id=65774&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=65774&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=65774&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=65774&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=65774&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=65774&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=65774&r=support
Expected behavior: https://bugs.php.net/fix.php?id=65774&r=notwrong
Not enough info:
https://bugs.php.net/fix.php?id=65774&r=notenoughinfo
Submitted twice:
https://bugs.php.net/fix.php?id=65774&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=65774&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=65774&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=65774&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=65774&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=65774&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=65774&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=65774&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=65774&r=mysqlcfg