unix socket: race on close?
Mikolaj Golub
to.my.trociny at gmail.com
Thu Feb 18 14:46:30 UTC 2010
On Thu, 18 Feb 2010 11:59:40 +0000 (GMT) Robert Watson wrote:
> On Thu, 18 Feb 2010, Mikolaj Golub wrote:
>
>> Below is a simple test code with unix sockets: the client does
>> connect()/close() in loop and the server -- accept()/close().
>>
>> Sometimes close() fails with 'Socket is not connected' error:
>
> Hi Mikolaj:
>
> Thanks for this report, and sorry about not spotting your earlier post
> to freebsd-net. I've been fairly preoccupied the last month and not
> keeping up with the mailing lists. Could I ask you to file a PR on
> this, and forward me the PR number so I can claim ownership? This
> should prevent it from getting lost while I catch up.
kern/144061
> In short, your evaluation seems reasonable to me -- have you tried
> tweaking soclose() to ignore ENOTCONN from sodisconnect() to confirm
> this diagnosis fixes all the instances you've been seeing?
I just have done this:
1) add logging the error when sodisconnect() returns error:
--- uipc_socket.c.orig 2010-02-18 14:25:25.000000000 +0200
+++ uipc_socket.c 2010-02-18 14:55:26.000000000 +0200
@@ -120,6 +120,7 @@ __FBSDID("$FreeBSD: src/sys/kern/uipc_so
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
+#include <sys/syslog.h>
#include <sys/socketvar.h>
#include <sys/resourcevar.h>
#include <net/route.h>
@@ -136,6 +137,7 @@ __FBSDID("$FreeBSD: src/sys/kern/uipc_so
#include <vm/uma.h>
+
#ifdef COMPAT_IA32
#include <sys/mount.h>
#include <sys/sysent.h>
@@ -657,7 +659,7 @@ soclose(struct socket *so)
if ((so->so_state & SS_ISDISCONNECTING) == 0) {
error = sodisconnect(so);
if (error)
- goto drop;
+ log(LOG_INFO, "soclose: sodisconnect error: %d\n", error);
}
if (so->so_options & SO_LINGER) {
if ((so->so_state & SS_ISDISCONNECTING) &&
Then on every error exit of the test application, like this
a.out: parent: close error: 57
I have in the message log:
Feb 18 15:35:32 zhuzha kernel: soclose: sodisconnect error: 57
2) add logging the error when sodisconnect() returns error and ignore the error:
--- uipc_socket.c.orig 2010-02-18 14:25:25.000000000 +0200
+++ uipc_socket.c 2010-02-18 15:41:07.000000000 +0200
@@ -120,6 +120,7 @@ __FBSDID("$FreeBSD: src/sys/kern/uipc_so
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
+#include <sys/syslog.h>
#include <sys/socketvar.h>
#include <sys/resourcevar.h>
#include <net/route.h>
@@ -136,6 +137,7 @@ __FBSDID("$FreeBSD: src/sys/kern/uipc_so
#include <vm/uma.h>
+
#ifdef COMPAT_IA32
#include <sys/mount.h>
#include <sys/sysent.h>
@@ -656,8 +658,11 @@ soclose(struct socket *so)
if (so->so_state & SS_ISCONNECTED) {
if ((so->so_state & SS_ISDISCONNECTING) == 0) {
error = sodisconnect(so);
- if (error)
- goto drop;
+ if (error) {
+ log(LOG_INFO, "soclose: sodisconnect error: %d\n", error);
+ if (error == ENOTCONN)
+ error = 0;
+ }
}
if (so->so_options & SO_LINGER) {
if ((so->so_state & SS_ISDISCONNECTING) &&
After this the test application does not exits and I see in the message log:
Feb 18 16:02:37 zhuzha kernel: soclose: sodisconnect error: 57
Feb 18 16:03:31 zhuzha kernel: soclose: sodisconnect error: 57
Feb 18 16:05:49 zhuzha last message repeated 4 times
Feb 18 16:15:50 zhuzha last message repeated 13 times
--
Mikolaj Golub
More information about the freebsd-hackers
mailing list