Edit report at https://bugs.php.net/bug.php?id=65774&edit=1
ID: 65774 Updated by: fel...@php.net Reported by: aglarond at gmail dot com Summary: no max file descriptor check for events.mechanism = /dev/poll -Status: Open +Status: Assigned Type: Bug Package: FPM related Operating System: SmartOS, possibly others PHP Version: Irrelevant -Assigned To: +Assigned To: fat 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