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

Reply via email to