Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Jan 2014 18:14:16 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r260520 - stable/9/sbin/devd
Message-ID:  <201401101814.s0AIEGYC025081@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Fri Jan 10 18:14:15 2014
New Revision: 260520
URL: http://svnweb.freebsd.org/changeset/base/260520

Log:
  MFC 259339
        sbin/devd/devd.cc
            Increase the size of devd's client socket's send buffer from the
            default (8k) to 128k.  This prevents clients from getting
            POLLHUPped during event storms.  For example, during zpool creation,
            the kernel emits a resource.fs.zfs.statechange event for every vdev
            in the pool.  A 128k buffer is large enough to hold the statechange
            events for a pool with nearly 800 drives.

Modified:
  stable/9/sbin/devd/devd.cc
Directory Properties:
  stable/9/   (props changed)
  stable/9/sbin/   (props changed)
  stable/9/sbin/devd/   (props changed)

Modified: stable/9/sbin/devd/devd.cc
==============================================================================
--- stable/9/sbin/devd/devd.cc	Fri Jan 10 17:56:23 2014	(r260519)
+++ stable/9/sbin/devd/devd.cc	Fri Jan 10 18:14:15 2014	(r260520)
@@ -101,6 +101,19 @@ __FBSDID("$FreeBSD$");
 #define CF "/etc/devd.conf"
 #define SYSCTL "hw.bus.devctl_disable"
 
+/*
+ * Since the client socket is nonblocking, we must increase its send buffer to
+ * handle brief event storms.  On FreeBSD, AF_UNIX sockets don't have a receive
+ * buffer, so the client can't increate the buffersize by itself.
+ *
+ * For example, when creating a ZFS pool, devd emits one 165 character
+ * resource.fs.zfs.statechange message for each vdev in the pool.  A 64k
+ * buffer has enough space for almost 400 drives, which would be very large but
+ * not impossibly large pool.  A 128k buffer has enough space for 794 drives,
+ * which is more than can fit in a rack with modern technology.
+ */
+#define CLIENT_BUFSIZE 131072
+
 using namespace std;
 
 extern FILE *yyin;
@@ -880,6 +893,7 @@ void
 new_client(int fd)
 {
 	int s;
+	int sndbuf_size;
 
 	/*
 	 * First go reap any zombie clients, then accept the connection, and
@@ -889,10 +903,15 @@ new_client(int fd)
 	check_clients();
 	s = accept(fd, NULL, NULL);
 	if (s != -1) {
+		sndbuf_size = CLIENT_BUFSIZE;
+		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf_size,
+		    sizeof(sndbuf_size)))
+			err(1, "setsockopt");
 		shutdown(s, SHUT_RD);
 		clients.push_back(s);
 		++num_clients;
-	}
+	} else
+		err(1, "accept");
 }
 
 static void



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