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>