Bug #65774 [Asn->Opn]: no max file descriptor check for events.mechanism = /dev/poll
Edit report at https://bugs.php.net/bug.php?id=65774&edit=1
ID: 65774
Updated by: kalle@php.net
Reported by: aglarond at gmail dot com
Summary: no max file descriptor check for events.mechanism =
/dev/poll
-Status: Assigned
+Status: Open
Type: Bug
Package: FPM related
Operating System: SmartOS, possibly others
PHP Version: Irrelevant
-Assigned To: fat
+Assigned To:
Block user comment: N
Private report: N
Previous Comments:
------------------------------------------------------------------------
[2013-09-27 16:00:13] aglarond at gmail dot com
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 this bug report at https://bugs.php.net/bug.php?id=65774&edit=1
Thread (4 messages)