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