Add workaround for a bug found in BSD kernels, which causes bogus error
authorMaxim Sobolev <sobomax@sippysoft.com>
Mon, 10 Jan 2005 17:31:19 +0000 (17:31 +0000)
committerMaxim Sobolev <sobomax@sippysoft.com>
Mon, 10 Jan 2005 17:31:19 +0000 (17:31 +0000)
returned by the connect(2) system call in some rare conditions, resulting
in inability to restart SEMS without restarting SER.

Should be no-op on !BSD systems.

Makefile.defs
modules/tm/t_fifo.c

index 0e10d07..33cf81b 100644 (file)
@@ -839,7 +839,7 @@ endif
 
 ifeq ($(OS), freebsd)
        DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
-               -DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL
+               -DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
        ifneq ($(found_lock_method), yes)
                DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
                found_lock_method=yes
@@ -852,7 +852,7 @@ endif
 
 ifeq ($(OS), openbsd)
        DEFS+=-DHAVE_SOCKADDR_SA_LEN  -DHAVE_GETHOSTBYNAME2 \
-               -DHAVE_UNION_SEMUN -DHAVE_MSGHDR_MSG_CONTROL
+               -DHAVE_UNION_SEMUN -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
        ifneq ($(found_lock_method), yes)
                DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
                found_lock_method=yes
@@ -881,7 +881,7 @@ endif   # if opensd
        
 ifeq ($(OS), netbsd)
        DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 \
-               -DHAVE_MSGHDR_MSG_CONTROL
+               -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
        ifneq ($(found_lock_method), yes)
                DEFS+= -DUSE_SYSV_SEM  # try pthread sems
                found_lock_method=yes
@@ -895,7 +895,7 @@ ifeq ($(OS), darwin)
        DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
                -DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL \
                -DUSE_ANON_MMAP \
-               -DNDEBUG
+               -DNDEBUG -DHAVE_CONNECT_ECONNRESET_BUG
        # -DNDEBUG used to turn off assert (assert wants to call
        # eprintf which doesn't seem to be defined in any shared lib
        ifneq ($(found_lock_method), yes)
index 444f018..24f052a 100644 (file)
@@ -898,7 +898,7 @@ error:
 
 static int write_to_unixsock(char* sockname, int cnt)
 {
-       int len;
+       int len, e;
        struct sockaddr_un dest;
 
        if (!sockname) {
@@ -921,12 +921,23 @@ static int write_to_unixsock(char* sockname, int cnt)
 #ifdef HAVE_SOCKADDR_SA_LEN
        dest.sun_len = len;
 #endif
-       
-       if (connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest)) == -1) {
+
+       e = connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest));
+#ifdef HAVE_CONNECT_ECONNRESET_BUG
+       /*
+        * Workaround for a nasty bug in BSD kernels dated back
+        * to the Berkeley days, so that can be found in many modern
+        * BSD-derived kernels. Workaround should be pretty harmless since
+        * in normal conditions connect(2) can never return ECONNRESET.
+        */
+       if ((e == -1) && (errno == ECONNRESET))
+               e = 0;
+#endif
+       if (e == -1) {
                LOG(L_ERR, "write_to_unixsock: Error in connect: %s\n", strerror(errno));
                return -1;
        }
-       
+
        if (tsend_dgram_ev(sock, (struct iovec*)lines_eol, 2 * cnt, tm_unix_tx_timeout * 1000) < 0) {
                LOG(L_ERR, "write_to_unixsock: writev failed: %s\n", strerror(errno));
                return -1;