Browse code

Add workaround for a bug found in BSD kernels, which causes bogus error 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.

Maxim Sobolev authored on 10/01/2005 17:31:19
Showing 2 changed files
... ...
@@ -839,7 +839,7 @@ endif
839 839
 
840 840
 ifeq ($(OS), freebsd)
841 841
 	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
842
-		-DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL
842
+		-DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
843 843
 	ifneq ($(found_lock_method), yes)
844 844
 		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
845 845
 		found_lock_method=yes
... ...
@@ -852,7 +852,7 @@ endif
852 852
 
853 853
 ifeq ($(OS), openbsd)
854 854
 	DEFS+=-DHAVE_SOCKADDR_SA_LEN  -DHAVE_GETHOSTBYNAME2 \
855
-		-DHAVE_UNION_SEMUN -DHAVE_MSGHDR_MSG_CONTROL
855
+		-DHAVE_UNION_SEMUN -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
856 856
 	ifneq ($(found_lock_method), yes)
857 857
 		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
858 858
 		found_lock_method=yes
... ...
@@ -881,7 +881,7 @@ endif   # if opensd
881 881
 	
882 882
 ifeq ($(OS), netbsd)
883 883
 	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 \
884
-		-DHAVE_MSGHDR_MSG_CONTROL
884
+		-DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG
885 885
 	ifneq ($(found_lock_method), yes)
886 886
 		DEFS+= -DUSE_SYSV_SEM  # try pthread sems
887 887
 		found_lock_method=yes
... ...
@@ -895,7 +895,7 @@ ifeq ($(OS), darwin)
895 895
 	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
896 896
 		-DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL \
897 897
 		-DUSE_ANON_MMAP \
898
-		-DNDEBUG
898
+		-DNDEBUG -DHAVE_CONNECT_ECONNRESET_BUG
899 899
 	# -DNDEBUG used to turn off assert (assert wants to call
900 900
 	# eprintf which doesn't seem to be defined in any shared lib
901 901
 	ifneq ($(found_lock_method), yes)
... ...
@@ -898,7 +898,7 @@ error:
898 898
 
899 899
 static int write_to_unixsock(char* sockname, int cnt)
900 900
 {
901
-	int len;
901
+	int len, e;
902 902
 	struct sockaddr_un dest;
903 903
 
904 904
 	if (!sockname) {
... ...
@@ -921,12 +921,23 @@ static int write_to_unixsock(char* sockname, int cnt)
921 921
 #ifdef HAVE_SOCKADDR_SA_LEN
922 922
 	dest.sun_len = len;
923 923
 #endif
924
-	
925
-	if (connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest)) == -1) {
924
+
925
+	e = connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest));
926
+#ifdef HAVE_CONNECT_ECONNRESET_BUG
927
+	/*
928
+	 * Workaround for a nasty bug in BSD kernels dated back
929
+	 * to the Berkeley days, so that can be found in many modern
930
+	 * BSD-derived kernels. Workaround should be pretty harmless since
931
+	 * in normal conditions connect(2) can never return ECONNRESET.
932
+	 */
933
+	if ((e == -1) && (errno == ECONNRESET))
934
+		e = 0;
935
+#endif
936
+	if (e == -1) {
926 937
 		LOG(L_ERR, "write_to_unixsock: Error in connect: %s\n", strerror(errno));
927 938
 		return -1;
928 939
 	}
929
-	
940
+
930 941
 	if (tsend_dgram_ev(sock, (struct iovec*)lines_eol, 2 * cnt, tm_unix_tx_timeout * 1000) < 0) {
931 942
 		LOG(L_ERR, "write_to_unixsock: writev failed: %s\n", strerror(errno));
932 943
 		return -1;