summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorasomers <asomers@FreeBSD.org>2013-12-13 21:49:41 +0000
committerasomers <asomers@FreeBSD.org>2013-12-13 21:49:41 +0000
commite12149b5f4f1a59a8e4fbd2bfb8b3b9befa9b06d (patch)
tree85f53f6937317e10021c1cfcf9ee5b849da714f6 /sbin
parentdacce6c2376e2bbb76481ed2ce7e66d191cc2daf (diff)
downloadFreeBSD-src-e12149b5f4f1a59a8e4fbd2bfb8b3b9befa9b06d.zip
FreeBSD-src-e12149b5f4f1a59a8e4fbd2bfb8b3b9befa9b06d.tar.gz
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. Reviewed by: ian, imp Approved by: ken (mentor) Sponsored by: Spectra Logic Corp MFC after: 4 weeks
Diffstat (limited to 'sbin')
-rw-r--r--sbin/devd/devd.cc21
1 files changed, 20 insertions, 1 deletions
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index 21816e5..b64c459 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -104,6 +104,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;
@@ -892,6 +905,7 @@ void
new_client(int fd)
{
int s;
+ int sndbuf_size;
/*
* First go reap any zombie clients, then accept the connection, and
@@ -901,10 +915,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
OpenPOWER on IntegriCloud