Author: pjd
Date: Sat Apr  2 09:31:02 2011
New Revision: 220273
URL: http://svn.freebsd.org/changeset/base/220273

Log:
  Handle ENOBUFS on send(2) by retrying for a while and logging the problem.
  
  MFC after:    1 week

Modified:
  head/sbin/hastd/proto_common.c

Modified: head/sbin/hastd/proto_common.c
==============================================================================
--- head/sbin/hastd/proto_common.c      Sat Apr  2 09:29:53 2011        
(r220272)
+++ head/sbin/hastd/proto_common.c      Sat Apr  2 09:31:02 2011        
(r220273)
@@ -94,6 +94,7 @@ proto_common_send(int sock, const unsign
 {
        ssize_t done;
        size_t sendsize;
+       int errcount = 0;
 
        PJDLOG_ASSERT(sock >= 0);
 
@@ -118,6 +119,23 @@ proto_common_send(int sock, const unsign
                } else if (done < 0) {
                        if (errno == EINTR)
                                continue;
+                       if (errno == ENOBUFS) {
+                               /*
+                                * If there are no buffers we retry.
+                                * After each try we increase delay before the
+                                * next one and we give up after fifteen times.
+                                * This gives 11s of total wait time.
+                                */
+                               if (errcount == 15) {
+                                       pjdlog_warning("Getting ENOBUFS errors 
for 11s on send(), giving up.");
+                               } else {
+                                       if (errcount == 0)
+                                               pjdlog_warning("Got ENOBUFS 
error on send(), retrying for a bit.");
+                                       errcount++;
+                                       usleep(100000 * errcount);
+                                       continue;
+                               }
+                       }
                        /*
                         * If this is blocking socket and we got EAGAIN, this
                         * means the request timed out. Translate errno to
@@ -131,6 +149,10 @@ proto_common_send(int sock, const unsign
                data += done;
                size -= done;
        } while (size > 0);
+       if (errcount > 0) {
+               pjdlog_info("Data sent successfully after %d ENOBUFS error%s.",
+                   errcount, errcount == 1 ? "" : "s");
+       }
 
        if (fd == -1)
                return (0);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to