Apache, CGI, PHP, open file descriptors, and Linux vs. BSDI

Apache, CGI, PHP, open file descriptors, and Linux vs. BSDI

Post by Tim Smit » Fri, 08 Nov 2002 06:01:33



I'm very puzzled by something.  We recently had a problem where Apache would
start getting EAGAIN errors on accept() calls, and generally things would go
to hell from that point.  This was with Apache 1.3.2x on BSDI.

I investigated, and determined that this was the problem: we had a php page,
and the php code invoked a third-party program via system().  One of the
things that program was doing was basically this:

    for ( int i = 3; i < something; ++i )
    {
        int flags = fcntl( i, F_GETFL );
        if ( flags != -1 )
            fcntl( i, F_SETFL, flags | O_NONBLOCK );
    }

It turns out that, with Apache 1.3.2x, the php page, and the program it
invokes with system(), is called with several file descriptors of Apache's.
In particular, it has the socket Apache is listening on, and Apache does not
appreciate having the O_NONBLOCK flag set on that socket.

Programs invoked via CGI do not have those file descriptors.  They only get
stdin, stdout, and stderr.

So, first question: why does doesn't Apache close all file descriptors > 2
before invoking php?

I tried this on Linux, and that leads to the second puzzle.  On Linux,
Apache isn't bothered by having its listen socket's mode changed to
non-blocking.  (And I verified that it is really getting changed).  So,
second question: can anyone explain offhand why Apache on BSDI gets upset in
this situation, and Apache on Linux does not?  (Same version of Apache in
both cases.  I downloaded and compiled the same tarball on both).

Finally, I grabbed Apache 2.something, and tried that.  It seemed to me that
php scripts getting all file descriptors, instead of just std{in|out|error}
was a bug, and so I wanted to see if that was fixed.  Well, not only do php
scripts still get all of Apache's file descriptors, CGI gets them all, too,
unlike in 1.3.2x!

So, third and final question: for CGI and php scripts, what file descriptors
actually *should* be left open after Apache forks, and which should it
close?  (I'm not sure exactly how php works in Apache.  If the php module is
actually running the php interpreter, than I guess it makes sense to not
close things...but I can't think of a justification for CGI getting
everything).

--Tim Smith

 
 
 

Apache, CGI, PHP, open file descriptors, and Linux vs. BSDI

Post by John Murtar » Sat, 09 Nov 2002 03:09:39



> I'm very puzzled by something.  We recently had a problem where Apache would
> start getting EAGAIN errors on accept() calls, and generally things would go
> to hell from that point.  This was with Apache 1.3.2x on BSDI.

> I investigated, and determined that this was the problem: we had a php page,
> and the php code invoked a third-party program via system().  One of the
> things that program was doing was basically this:

>     for ( int i = 3; i < something; ++i )
>     {
>         int flags = fcntl( i, F_GETFL );
>         if ( flags != -1 )
>             fcntl( i, F_SETFL, flags | O_NONBLOCK );
>     }

> It turns out that, with Apache 1.3.2x, the php page, and the program it
> invokes with system(), is called with several file descriptors of Apache's.
> In particular, it has the socket Apache is listening on, and Apache does not
> appreciate having the O_NONBLOCK flag set on that socket.

> Programs invoked via CGI do not have those file descriptors.  They only get
> stdin, stdout, and stderr.

> So, first question: why does doesn't Apache close all file descriptors > 2
> before invoking php?

> I tried this on Linux, and that leads to the second puzzle.  On Linux,
> Apache isn't bothered by having its listen socket's mode changed to
> non-blocking.  (And I verified that it is really getting changed).  So,
> second question: can anyone explain offhand why Apache on BSDI gets upset in
> this situation, and Apache on Linux does not?  (Same version of Apache in
> both cases.  I downloaded and compiled the same tarball on both).

> Finally, I grabbed Apache 2.something, and tried that.  It seemed to me that
> php scripts getting all file descriptors, instead of just std{in|out|error}
> was a bug, and so I wanted to see if that was fixed.  Well, not only do php
> scripts still get all of Apache's file descriptors, CGI gets them all, too,
> unlike in 1.3.2x!

> So, third and final question: for CGI and php scripts, what file descriptors
> actually *should* be left open after Apache forks, and which should it
> close?  (I'm not sure exactly how php works in Apache.  If the php module is
> actually running the php interpreter, than I guess it makes sense to not
> close things...but I can't think of a justification for CGI getting
> everything).

I think part of the answer involves the fact that PHP is an apache module (not
a separate CGI process created by fork/exec).  You are executing within the
context of the apache server process (that is part of the reason for the
better speed, less startup overhead).  I know you would like to separate the
two, but part of the problem is that you are within the context of one process.

Hope this helps.
--
                                          John
___________________________________________________________________
John Murtari                              Software Workshop Inc.

http://www.thebook.com/

 
 
 

1. Apache 1.3.3 log file rotation leaves open file descriptors

In Apache 1.3.3 (Solaris) we are using the USR1 signal (or HUP) to rotate the
log files daily.

Our rotation strategy is:
1) rename log file
2) issue USR1

What appears to be happening though, is that Apache is not closing the file
descriptors for the old log files. (We eventually run out of file descriptors -
in just over a month)  and lsof shows that Apache still has all the old log
files open.

Anyone else noticed this behaviour?

Thanks,
Mark Hume

2. IBM has released DB2 v8.1 for AIX

3. php vs cgi performance on apache

4. hacmp install -- compiler

5. Apache: (24)Too many open files: inc # of descriptors??

6. installing sony 33a w/ lilo

7. Apache w/ PHP and SSL: w/ PHP OK - w/out PHP NOK

8. Tracing a particular process...

9. Apache, BSDI, CGI, and SSI question

10. Apache 1.0.0 on BSDI 2.1 and cgi scripts

11. open files/per-process file descriptor

12. rm-ing files with open file descriptors

13. Forms Processing: PHP vs. CGI.pm