On Sun, Dec 8, 2013 at 8:56 AM, Jeff Trawick <trawick@gmail.com> wrote:
On Tue, Nov 26, 2013 at 4:01 PM, Rainer Jung <rainer.jung@kippdata.de> wrote:
On 26.11.2013 15:58, olli hauer wrote:
> On 2013-11-25 23:25, Jeff Trawick wrote:

>> See if this brings any happiness:
>>
>> Index: network_io/unix/sockets.c
>> ===================================================================
>> --- network_io/unix/sockets.c (revision 1545394)
>> +++ network_io/unix/sockets.c (working copy)
>> @@ -273,7 +273,7 @@
>>  #endif /* TCP_NODELAY_INHERITED */
>>  #if APR_O_NONBLOCK_INHERITED
>>      if (apr_is_option_set(sock, APR_SO_NONBLOCK) == 1) {
>> -        apr_set_option(*new, APR_SO_NONBLOCK, 1);
>> +        /* apr_set_option(*new, APR_SO_NONBLOCK, 1); */
>>      }
>>  #endif /* APR_O_NONBLOCK_INHERITED */
>
>
> I can confirm after removing the line in apr-1.5.0 apache24 no longer hangs.
> (tested with apache-2.4.6 / 2.4.7)
>
> I seen now why this is triggered by comparing apr.h after `./configure',
>
>> grep APR_O_NONBLOCK_INHERITED work/apr-1.4.8/include/apr.h
> ./work/apr-1.4.8/include/apr.h:#define APR_O_NONBLOCK_INHERITED 0
>
>> grep APR_O_NONBLOCK_INHERITED work/apr-1.5.0/include/apr.h
> work/apr-1.5.0/include/apr.h:#define APR_O_NONBLOCK_INHERITED 1
>
>
>> There are some APR 1.5 autoconf changes to consider at
>> http://svn.apache.org/viewvc/apr/apr/branches/1.5.x/build/apr_network.m4?view=log
>
> OK, backing out the changes from r1502805 seems to do the trick on 10b3
> http://svn.apache.org/viewvc?view=revision&revision=1502805
>
>> grep APR_O_NONBLOCK_INHERITED work/apr-1.5.0/include/apr.h
> work/apr-1.5.0/include/apr.h:#define APR_O_NONBLOCK_INHERITED 0

But acking out that change simply breaks the configure test on any
platform, because the resulting detection program no longer compiles.

So the real culprit, is that the detection isn't doing the right thing.

The test was changed before the compilation fix in the following revision:

http://svn.apache.org/viewvc/apr/apr/branches/1.5.x/build/apr_network.m4?r1=887002&r2=1449569&pathrev=1502805&diff_format=h

That was due to the fact that I saw the test providing unreliable
results on a busy machine.

So the question to me is: is the O_NONBLOCK setting inherited from a
listening socket on FreeBSD 10 - that's what the test tries to detect -
and how can we fix this feature test?

O_NONBLOCK is inherited from either an IPv6 listener or IPv4 listener in the obvious case on FreeBSD (9 and 10 tested), where "obvious" = V6ONLY in default setting (clearly ON), IPv6 client socket used to connect to IPv6 server socket, IPv4 client socket used to connect to IPv4 server socket.  If I set V6ONLY to OFF, I still see O_NONBLOCK inherited.

This is with a pure sockets program, ruling out APR.
 

Or: is the test correct, but it previously failed for systems, where the
Apache or APR code does not do the right thing if the test would have
succeeded.

I guess something about the real world scenario in httpd (combination of other settings on the socket or presence of another listener on the port or something else unexpected) is breaking this.  But I suppose there is other code that could be broken and needs to be tested for completeness, such as failing to set non-blocking in the listener but managing to set the flag in the APR socket.

I forgot that FreeBSD is a real OS (has source code for kernel installed) :)

To make a long story short, FreeBSD 10 introduces accept4().  APR uses accept4() where it can find it.  accept4() on Linux and FreeBSD 10 both have a SOCK_NONBLOCK flag, but on FreeBSD 10 the SOCK_NONBLOCK is the sole determiner of whether or not the connected socket is non-blocking.

(Recall that my binaries built on FreeBSD 9 worked fine.)

So APR's use of accept4() was broken w.r.t. inherited non-blocking on FreeBSD 10 but for a while we still worked because the configure-time check didn't work right with clang (the normal compiler on FreeBSD 10).

Once the clang issue was resolved, we hit the bad use of accept4()-on-FreeBSD 10.

I guess when calling accept4() and SOCK_NONBLOCK is defined we need to set the SOCK_NONBLOCK flag if the listen socket is non-blocking, and not worry about the more detailed semantics of accept4().

(untested as of yet, though I'm sure that will change in the next couple of days)

--/--

This is separate from the httpd issue -- fixing the FreeBSD version check for --{enable|disable}-v6mapped, for which there is a patch earlier in this thread.
 

 

Regards,

Rainer



--
Born in Roswell... married an alien...
http://emptyhammock.com/



--
Born in Roswell... married an alien...
http://emptyhammock.com/