[3.0] e15fcc9 Set the waiter pipe as non-blocking and record overflows

Tollef Fog Heen tfheen at varnish-cache.org
Tue May 7 10:21:09 CEST 2013


commit e15fcc9c207a56f270b449d2e35208e1bc7768cf
Author: Tollef Fog Heen <tfheen at varnish-software.com>
Date:   Tue Apr 9 08:25:26 2013 +0200

    Set the waiter pipe as non-blocking and record overflows
    
    Fixes #1285

diff --git a/bin/varnishd/cache_acceptor.c b/bin/varnishd/cache_acceptor.c
index 5108a55..790ed62 100644
--- a/bin/varnishd/cache_acceptor.c
+++ b/bin/varnishd/cache_acceptor.c
@@ -394,6 +394,7 @@ vca_close_session(struct sess *sp, const char *why)
 void
 vca_return_session(struct sess *sp)
 {
+	int written = 0;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	AZ(sp->obj);
@@ -406,8 +407,16 @@ vca_return_session(struct sess *sp)
 	if (VTCP_nonblocking(sp->fd)) {
 		vca_close_session(sp, "remote closed");
 		SES_Delete(sp);
-	} else if (vca_act->pass == NULL)
-		assert(sizeof sp == write(vca_pipes[1], &sp, sizeof sp));
+	} else if (vca_act->pass == NULL) {
+		written = write(vca_pipes[1], &sp, sizeof sp);
+		if (written != sizeof sp && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+			VSC_C_main->sess_pipe_overflow++;
+			vca_close_session(sp, "session pipe overflow");
+			SES_Delete(sp);
+			return;
+		}
+		assert (written == sizeof sp);
+	}
 	else
 		vca_act->pass(sp);
 }
diff --git a/bin/varnishd/cache_waiter_epoll.c b/bin/varnishd/cache_waiter_epoll.c
index fe64961..108e48d 100644
--- a/bin/varnishd/cache_waiter_epoll.c
+++ b/bin/varnishd/cache_waiter_epoll.c
@@ -38,7 +38,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -224,20 +223,11 @@ vca_sess_timeout_ticker(void *arg)
 static void
 vca_epoll_init(void)
 {
-	int i;
-
-	i = fcntl(vca_pipes[0], F_GETFL);
-	assert(i != -1);
-	i |= O_NONBLOCK;
-	i = fcntl(vca_pipes[0], F_SETFL, i);
-	assert(i != -1);
-
 	AZ(pipe(dotimer_pipe));
-	i = fcntl(dotimer_pipe[0], F_GETFL);
-	assert(i != -1);
-	i |= O_NONBLOCK;
-	i = fcntl(dotimer_pipe[0], F_SETFL, i);
-	assert(i != -1);
+
+	AZ(vnonblocking(vca_pipes[0]));
+	AZ(vnonblocking(vca_pipes[1]));
+	AZ(vnonblocking(dotimer_pipe[0]));
 
 	AZ(pthread_create(&vca_epoll_timeout_thread,
 	    NULL, vca_sess_timeout_ticker, NULL));
diff --git a/bin/varnishd/cache_waiter_kqueue.c b/bin/varnishd/cache_waiter_kqueue.c
index ea0e2fc..48fad20 100644
--- a/bin/varnishd/cache_waiter_kqueue.c
+++ b/bin/varnishd/cache_waiter_kqueue.c
@@ -38,7 +38,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -208,11 +207,8 @@ vca_kqueue_init(void)
 {
 	int i;
 
-	i = fcntl(vca_pipes[0], F_GETFL);
-	assert(i != -1);
-	i |= O_NONBLOCK;
-	i = fcntl(vca_pipes[0], F_SETFL, i);
-	assert(i != -1);
+	AZ(vnonblocking(vca_pipes[0]));
+	AZ(vnonblocking(vca_pipes[1]));
 
 	AZ(pthread_create(&vca_kqueue_thread, NULL, vca_kqueue_main, NULL));
 }
diff --git a/bin/varnishd/cache_waiter_poll.c b/bin/varnishd/cache_waiter_poll.c
index b9ad213..13120dd 100644
--- a/bin/varnishd/cache_waiter_poll.c
+++ b/bin/varnishd/cache_waiter_poll.c
@@ -199,6 +199,7 @@ vca_poll_init(void)
 {
 
 	vca_pollspace(256);
+	AZ(vnonblocking(vca_pipes[1]));
 	AZ(pthread_create(&vca_poll_thread, NULL, vca_main, NULL));
 }
 
diff --git a/bin/varnishd/cache_waiter_ports.c b/bin/varnishd/cache_waiter_ports.c
index 364dd2c..6973080 100644
--- a/bin/varnishd/cache_waiter_ports.c
+++ b/bin/varnishd/cache_waiter_ports.c
@@ -250,9 +250,14 @@ static void
 vca_ports_pass(struct sess *sp)
 {
 	int r;
-	while((r = port_send(solaris_dport, 0, sp)) == -1 &&
-		errno == EAGAIN);
-	AZ(r);
+       r = port_send(vws->dport, 0, TRUST_ME(sp));
+       if (r == -1 && errno == EAGAIN) {
+	       VSC_C_main->sess_pipe_overflow++;
+	       vca_close_session(sp, "session pipe overflow");
+	       SES_Delete(sp);
+	       return;
+       }
+       AZ(r);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/include/libvarnish.h b/include/libvarnish.h
index b457d02..d7ae763 100644
--- a/include/libvarnish.h
+++ b/include/libvarnish.h
@@ -112,6 +112,7 @@ int seed_random(void);
 int vtmpfile(char *);
 char *vreadfile(const char *pfx, const char *fn, ssize_t *sz);
 char *vreadfd(int fd, ssize_t *sz);
+int vnonblocking(int fd);
 
 /* Safe printf into a fixed-size buffer */
 #define bprintf(buf, fmt, ...)						\
diff --git a/include/vsc_fields.h b/include/vsc_fields.h
index dddb235..592d236 100644
--- a/include/vsc_fields.h
+++ b/include/vsc_fields.h
@@ -167,6 +167,8 @@ VSC_F(vmods,		uint64_t, 0, 'i', "Loaded VMODs", "")
 VSC_F(n_gzip,			uint64_t, 0, 'a', "Gzip operations", "")
 VSC_F(n_gunzip,			uint64_t, 0, 'a', "Gunzip operations", "")
 
+VSC_F(sess_pipe_overflow,		uint64_t, 0, 'c', "Dropped sessions due to session pipe overflow", "")
+
 #endif
 
 /**********************************************************************/
diff --git a/lib/libvarnish/vtmpfile.c b/lib/libvarnish/vtmpfile.c
index 327790a..b51c29c 100644
--- a/lib/libvarnish/vtmpfile.c
+++ b/lib/libvarnish/vtmpfile.c
@@ -140,3 +140,16 @@ vreadfile(const char *pfx, const char *fn, ssize_t *sz)
 	errno = err;
 	return (r);
 }
+
+int
+vnonblocking(int fd)
+{
+	int i;
+
+	i = fcntl(fd, F_GETFL);
+	assert(i != -1);
+	i |= O_NONBLOCK;
+	i = fcntl(fd, F_SETFL, i);
+	assert(i != -1);
+	return (i);
+}



More information about the varnish-commit mailing list