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

Reply via email to