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