All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN
@ 2009-09-29  7:53 Matthieu Nottale
  2009-10-01  7:11 ` Jan Kiszka
  0 siblings, 1 reply; 5+ messages in thread
From: Matthieu Nottale @ 2009-09-29  7:53 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 1075 bytes --]

Hi,

I believe I found a bug in the Xenomai Posix skin while trying to use 
boost::asio: The accept() call in asychronous mode
fails with ENOPEM instead of EAGAIN. Other than that, the call 'works' 
in the sense that calling it again after a connection is established 
returns a new file descriptor.

I'm running xenomai rev 50ee47db78117e8711d4d2f5310dff262a425eb7 with 
kernel 2.6.31 i686.

Xenomai is built with no option (other than --enable-shared 
--disable-static) to configure.

I'm joining a simple C file to reproduce the problem.

Its output when built 'natively', and running "nc localhost 12345" after 
some time is:

-1 11
accept: Resource temporarily unavailable
-1 11
accept: Resource temporarily unavailable
<...>
OK 4

Its output when built using the posix skin and run as root is:
-1 1
accept: Operation not permitted
-1 1
accept: Operation not permitted
<...>
OK 4

The consequence of this bug is that all applications doing asynchronous 
accept() calls will fail to work, as they will incorrectly believe the 
operation failed.


Regards,

    Matthieu


[-- Attachment #2: testxeno.c --]
[-- Type: text/x-csrc, Size: 974 bytes --]

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
  int s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  int t = 1;
  int res;
  struct sockaddr_in sa;
  mlockall(MCL_PRESENT | MCL_FUTURE);
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
    perror("setsockopt");
  memset(&sa, 0, sizeof (sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(12345);
  sa.sin_addr.s_addr = INADDR_ANY;
  
  if (bind(s, (struct sockaddr *)&sa, sizeof(sa)))
    perror("bind");
  if (listen(s, 128))
    perror("listen");
  t = 1;
  if (ioctl(s, FIONBIO, &t))
    perror("ioctl");
  do {
    res = accept(s, 0, 0);
    printf("%d %d\n", (int)res, (int)errno);
    perror("accept");
    usleep(500000);
  } while(res==-1);
  printf("OK %d\n", (int)res);
  return 0;
}

[-- Attachment #3: config-2.6.31-xenomai.gz --]
[-- Type: application/x-gzip, Size: 15615 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN
  2009-09-29  7:53 [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN Matthieu Nottale
@ 2009-10-01  7:11 ` Jan Kiszka
  2009-10-01  7:20   ` Gilles Chanteperdrix
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2009-10-01  7:11 UTC (permalink / raw)
  To: Matthieu Nottale; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1811 bytes --]

Matthieu Nottale wrote:
> Hi,
> 
> I believe I found a bug in the Xenomai Posix skin while trying to use
> boost::asio: The accept() call in asychronous mode
> fails with ENOPEM instead of EAGAIN. Other than that, the call 'works'
> in the sense that calling it again after a connection is established
> returns a new file descriptor.

On what kind of file descriptor descriping what kind of socket are you
calling accept()? So far I'm not aware of any RTDM driver providing the
corresponding service - well, at least not a public one (our RT-TCP
stack is yet to be released). Or is it intended to pass the call to
plain Linux, switching the caller into secondary more?

Jan

> 
> I'm running xenomai rev 50ee47db78117e8711d4d2f5310dff262a425eb7 with
> kernel 2.6.31 i686.
> 
> Xenomai is built with no option (other than --enable-shared
> --disable-static) to configure.
> 
> I'm joining a simple C file to reproduce the problem.
> 
> Its output when built 'natively', and running "nc localhost 12345" after
> some time is:
> 
> -1 11
> accept: Resource temporarily unavailable
> -1 11
> accept: Resource temporarily unavailable
> <...>
> OK 4
> 
> Its output when built using the posix skin and run as root is:
> -1 1
> accept: Operation not permitted
> -1 1
> accept: Operation not permitted
> <...>
> OK 4
> 
> The consequence of this bug is that all applications doing asynchronous
> accept() calls will fail to work, as they will incorrectly believe the
> operation failed.
> 
> 
> Regards,
> 
>    Matthieu
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-core mailing list
> Xenomai-core@domain.hid
> https://mail.gna.org/listinfo/xenomai-core



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN
  2009-10-01  7:11 ` Jan Kiszka
@ 2009-10-01  7:20   ` Gilles Chanteperdrix
  2009-10-01  7:41     ` Jan Kiszka
  0 siblings, 1 reply; 5+ messages in thread
From: Gilles Chanteperdrix @ 2009-10-01  7:20 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

Jan Kiszka wrote:
> Matthieu Nottale wrote:
>> Hi,
>>
>> I believe I found a bug in the Xenomai Posix skin while trying to use
>> boost::asio: The accept() call in asychronous mode
>> fails with ENOPEM instead of EAGAIN. Other than that, the call 'works'
>> in the sense that calling it again after a connection is established
>> returns a new file descriptor.
> 
> On what kind of file descriptor descriping what kind of socket are you
> calling accept()? So far I'm not aware of any RTDM driver providing the
> corresponding service - well, at least not a public one (our RT-TCP
> stack is yet to be released). Or is it intended to pass the call to
> plain Linux, switching the caller into secondary more?

There's a sample attached. Yes, it is a TCP stream. Howeve accept is
wrapped, so it may happen that EPERM is the result of the wrapping.

-- 
					    Gilles.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN
  2009-10-01  7:20   ` Gilles Chanteperdrix
@ 2009-10-01  7:41     ` Jan Kiszka
  2009-10-01  8:09       ` Matthieu Nottale
  0 siblings, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2009-10-01  7:41 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1711 bytes --]

Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>> Matthieu Nottale wrote:
>>> Hi,
>>>
>>> I believe I found a bug in the Xenomai Posix skin while trying to use
>>> boost::asio: The accept() call in asychronous mode
>>> fails with ENOPEM instead of EAGAIN. Other than that, the call 'works'
>>> in the sense that calling it again after a connection is established
>>> returns a new file descriptor.
>> On what kind of file descriptor descriping what kind of socket are you
>> calling accept()? So far I'm not aware of any RTDM driver providing the
>> corresponding service - well, at least not a public one (our RT-TCP
>> stack is yet to be released). Or is it intended to pass the call to
>> plain Linux, switching the caller into secondary more?
> 
> There's a sample attached. Yes, it is a TCP stream. Howeve accept is
> wrapped, so it may happen that EPERM is the result of the wrapping.
> 

Oops, missed that. Indeed, patch below should fix it.

Jan

diff --git a/src/skins/posix/rtdm.c b/src/skins/posix/rtdm.c
index 6e347fb..4e6685f 100644
--- a/src/skins/posix/rtdm.c
+++ b/src/skins/posix/rtdm.c
@@ -404,18 +404,21 @@ int __wrap_accept(int fd, struct sockaddr *addr, socklen_t * addrlen)
 
 		pthread_setcanceltype(oldtype, NULL);
 
-		if (fd >= 0)
-			fd += __rtdm_fd_start;
+		if (fd < 0)
+			return set_errno(fd);
+
+		return fd + __rtdm_fd_start;
 	} else {
 		fd = __real_accept(fd, addr, addrlen);
 
 		if (fd >= __rtdm_fd_start) {
 			__real_close(fd);
-			fd = -EMFILE;
+			errno = EMFILE;
+			fd = -1;
 		}
-	}
 
-	return set_errno(fd);
+		return fd;
+	}
 }
 
 int __wrap_getsockname(int fd, struct sockaddr *name, socklen_t * namelen)


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN
  2009-10-01  7:41     ` Jan Kiszka
@ 2009-10-01  8:09       ` Matthieu Nottale
  0 siblings, 0 replies; 5+ messages in thread
From: Matthieu Nottale @ 2009-10-01  8:09 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

Jan Kiszka wrote:
> Gilles Chanteperdrix wrote:
>   
>> Jan Kiszka wrote:
>>     
>>> Matthieu Nottale wrote:
>>>       
>>>> Hi,
>>>>
>>>> I believe I found a bug in the Xenomai Posix skin while trying to use
>>>> boost::asio: The accept() call in asychronous mode
>>>> fails with ENOPEM instead of EAGAIN. Other than that, the call 'works'
>>>> in the sense that calling it again after a connection is established
>>>> returns a new file descriptor.
>>>>         
>>> On what kind of file descriptor descriping what kind of socket are you
>>> calling accept()? So far I'm not aware of any RTDM driver providing the
>>> corresponding service - well, at least not a public one (our RT-TCP
>>> stack is yet to be released). Or is it intended to pass the call to
>>> plain Linux, switching the caller into secondary more?
>>>       
>> There's a sample attached. Yes, it is a TCP stream. Howeve accept is
>> wrapped, so it may happen that EPERM is the result of the wrapping.
>>
>>     
>
> Oops, missed that. Indeed, patch below should fix it.
>
> Jan
>
> diff --git a/src/skins/posix/rtdm.c b/src/skins/posix/rtdm.c
> index 6e347fb..4e6685f 100644
> --- a/src/skins/posix/rtdm.c
> +++ b/src/skins/posix/rtdm.c
> @@ -404,18 +404,21 @@ int __wrap_accept(int fd, struct sockaddr *addr, socklen_t * addrlen)
>  
>  		pthread_setcanceltype(oldtype, NULL);
>  
> -		if (fd >= 0)
> -			fd += __rtdm_fd_start;
> +		if (fd < 0)
> +			return set_errno(fd);
> +
> +		return fd + __rtdm_fd_start;
>  	} else {
>  		fd = __real_accept(fd, addr, addrlen);
>  
>  		if (fd >= __rtdm_fd_start) {
>  			__real_close(fd);
> -			fd = -EMFILE;
> +			errno = EMFILE;
> +			fd = -1;
>  		}
> -	}
>  
> -	return set_errno(fd);
> +		return fd;
> +	}
>  }
>  
>  int __wrap_getsockname(int fd, struct sockaddr *name, socklen_t * namelen)
>
>   
Thank you very much for this quick correction, without much knowledge of 
xenomai I was afraid the fix would be much more complicated.


Best regards,

    Matthieu


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-10-01  8:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-29  7:53 [Xenomai-core] [bug] accept() in non-blocking mode fails with EPERM instead of EAGAIN Matthieu Nottale
2009-10-01  7:11 ` Jan Kiszka
2009-10-01  7:20   ` Gilles Chanteperdrix
2009-10-01  7:41     ` Jan Kiszka
2009-10-01  8:09       ` Matthieu Nottale

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.