Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Apr 2011 09:29:53 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220272 - head/sbin/hastd
Message-ID:  <201104020929.p329TrRC077084@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Sat Apr  2 09:29:53 2011
New Revision: 220272
URL: http://svn.freebsd.org/changeset/base/220272

Log:
  When we are operating on blocking socket and get EAGAIN on send(2) or recv(2)
  this means that request timed out. Translate the meaningless EAGAIN to
  ETIMEDOUT to give administrator a hint that he might need to increase timeout
  in configuration file.
  
  MFC after:	1 month

Modified:
  head/sbin/hastd/proto_common.c

Modified: head/sbin/hastd/proto_common.c
==============================================================================
--- head/sbin/hastd/proto_common.c	Sat Apr  2 09:25:13 2011	(r220271)
+++ head/sbin/hastd/proto_common.c	Sat Apr  2 09:29:53 2011	(r220272)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2009-2010 The FreeBSD Foundation
+ * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>
  * All rights reserved.
  *
  * This software was developed by Pawel Jakub Dawidek under sponsorship from
@@ -34,8 +35,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 
 #include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <strings.h>
+#include <unistd.h>
 
 #include "pjdlog.h"
 #include "proto_impl.h"
@@ -45,6 +49,16 @@ __FBSDID("$FreeBSD$");
 #define	MAX_SEND_SIZE	32768
 #endif
 
+static bool
+blocking_socket(int sock)
+{
+	int flags;
+
+	flags = fcntl(sock, F_GETFL);
+	PJDLOG_ASSERT(flags >= 0);
+	return ((flags & O_NONBLOCK) == 0);
+}
+
 static int
 proto_descriptor_send(int sock, int fd)
 {
@@ -99,11 +113,19 @@ proto_common_send(int sock, const unsign
 	do {
 		sendsize = size < MAX_SEND_SIZE ? size : MAX_SEND_SIZE;
 		done = send(sock, data, sendsize, MSG_NOSIGNAL);
-		if (done == 0)
+		if (done == 0) {
 			return (ENOTCONN);
-		else if (done < 0) {
+		} else if (done < 0) {
 			if (errno == EINTR)
 				continue;
+			/*
+			 * If this is blocking socket and we got EAGAIN, this
+			 * means the request timed out. Translate errno to
+			 * ETIMEDOUT, to give administrator a hint to
+			 * eventually increase timeout.
+			 */
+			if (errno == EAGAIN && blocking_socket(sock))
+				errno = ETIMEDOUT;
 			return (errno);
 		}
 		data += done;
@@ -169,10 +191,19 @@ proto_common_recv(int sock, unsigned cha
 	do {
 		done = recv(sock, data, size, MSG_WAITALL);
 	} while (done == -1 && errno == EINTR);
-	if (done == 0)
+	if (done == 0) {
 		return (ENOTCONN);
-	else if (done < 0)
+	} else if (done < 0) {
+		/*
+		 * If this is blocking socket and we got EAGAIN, this
+		 * means the request timed out. Translate errno to
+		 * ETIMEDOUT, to give administrator a hint to
+		 * eventually increase timeout.
+		 */
+		if (errno == EAGAIN && blocking_socket(sock))
+			errno = ETIMEDOUT;
 		return (errno);
+	}
 	if (fdp == NULL)
 		return (0);
 	return (proto_descriptor_recv(sock, fdp));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104020929.p329TrRC077084>