r1964 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Thu Sep 20 10:16:02 CEST 2007


Author: phk
Date: 2007-09-20 10:16:01 +0200 (Thu, 20 Sep 2007)
New Revision: 1964

Modified:
   trunk/varnish-cache/bin/varnishd/cache_backend_simple.c
Log:
Go over the simple backend and make it more readable.


Modified: trunk/varnish-cache/bin/varnishd/cache_backend_simple.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend_simple.c	2007-09-20 08:14:40 UTC (rev 1963)
+++ trunk/varnish-cache/bin/varnishd/cache_backend_simple.c	2007-09-20 08:16:01 UTC (rev 1964)
@@ -28,10 +28,6 @@
  *
  * $Id$
  *
- *
- * XXX: When we switch VCL we can have vbe_conn's dangling from
- * XXX: the backends no longer used.  When the VCL's refcount
- * XXX: drops to zero we should zap them.
  */
 
 #include <sys/types.h>
@@ -62,75 +58,106 @@
 	TAILQ_HEAD(, vbe_conn)	connlist;
 };
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Try to get a socket connected to one of the addresses on the list.
+ * We start from the cached "last good" address and try all items on
+ * the list exactly once.
+ * If a new DNS lookup is made while we try, we start over and try the
+ * new list exactly once.
+ */
 
-
 static int
 bes_conn_try_list(struct sess *sp, struct bes *bes)
 {
 	struct addrinfo *ai, *from;
-	struct sockaddr_storage ss;
-	int fam, sockt, proto;
-	socklen_t alen;
 	int s, loops;
-	char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
-	char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
 	unsigned myseq;
 
+	CHECK_OBJ_NOTNULL(bes, BES_MAGIC);
+	if (bes->addr == NULL)
+		return (-1);
+	AN(bes->last_addr);
+
 	/* Called with lock held */
 	myseq = bes->dnsseq;
 	loops = 0;
-	from = bes->last_addr;
-	for (ai = from; ai != NULL && (loops != 1 || ai != from);) {
-		fam = ai->ai_family;
-		sockt = ai->ai_socktype;
-		proto = ai->ai_protocol;
-		alen = ai->ai_addrlen;
-		assert(alen <= sizeof ss);
-		memcpy(&ss, ai->ai_addr, alen);
-		UNLOCK(&sp->backend->mtx);
-		s = socket(fam, sockt, proto);
-		if (s >= 0 && connect(s, (void *)&ss, alen)) {
-			AZ(close(s));
-			s = -1;
-		}
-		if (s >= 0) {
-			TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
-			TCP_name((void*)&ss, alen,
-			    abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
-			WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s",
-			    sp->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
-		}
-		LOCK(&sp->backend->mtx);
-		if (s >= 0) {
+	ai = from = bes->last_addr;
+	while (1) {
+
+		/* NB: releases/acquires lock */
+		s = VBE_TryConnect(sp, ai);
+
+		if (s >= 0) { 
+			/* Update cached "last good" if still valid */
 			if (myseq == bes->dnsseq)
 				bes->last_addr = ai;
 			return (s);
 		}
+
 		if (myseq != bes->dnsseq) {
+			/* A DNS-lookup happended, try again from start */
 			loops = 0;
 			from = bes->last_addr;
 			ai = from;
 		} else {
+			/* Try next one */
 			ai = ai->ai_next;
 			if (ai == NULL) {
 				loops++;
 				ai = bes->addr;
 			}
 		}
+		if (loops == 1 && ai == from)
+			return (-1);
 	}
-	return (-1);
 }
 
 /*--------------------------------------------------------------------*/
 
+static const char *
+bes_dns_lookup(struct backend *bp)
+{
+	struct addrinfo *res, hint, *old;
+	struct bes *bes;
+	int error;
+
+	CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+	CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
+
+	bes->dnstime = TIM_mono();
+
+	/* Let go of lock while we do sleepable stuff */
+	UNLOCK(&bp->mtx);
+
+	memset(&hint, 0, sizeof hint);
+	hint.ai_family = PF_UNSPEC;
+	hint.ai_socktype = SOCK_STREAM;
+	res = NULL;
+	error = getaddrinfo(bes->hostname,
+	    bes->portname == NULL ? "http" : bes->portname,
+	    &hint, &res);
+	LOCK(&bp->mtx);
+	if (error) {
+		if (res != NULL)
+			freeaddrinfo(res);
+		return(gai_strerror(error));
+	} 
+	bes->dnsseq++;
+	old = bes->addr;
+	bes->last_addr = res;
+	bes->addr = res;
+	if (old != NULL)
+		freeaddrinfo(old);
+	return (NULL);
+}
+
+/*--------------------------------------------------------------------*/
+
 static int
 bes_conn_try(struct sess *sp, struct backend *bp)
 {
 	int s;
 	struct bes *bes;
-	struct addrinfo *res, hint, *old;
-	int error;
 
 	CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
 
@@ -148,32 +175,8 @@
 		return (-1);
 	}
 
-	/* Then do another lookup to catch DNS changes */
-	bes->dnstime = TIM_mono();
-	UNLOCK(&bp->mtx);
+	(void)bes_dns_lookup(bp);
 
-	memset(&hint, 0, sizeof hint);
-	hint.ai_family = PF_UNSPEC;
-	hint.ai_socktype = SOCK_STREAM;
-	res = NULL;
-	error = getaddrinfo(bes->hostname,
-	    bes->portname == NULL ? "http" : bes->portname,
-	    &hint, &res);
-	if (error) {
-		if (res != NULL)
-			freeaddrinfo(res);
-		printf("getaddrinfo: %s\n", gai_strerror(error)); /* XXX */
-		LOCK(&bp->mtx);
-	} else {
-		LOCK(&bp->mtx);
-		bes->dnsseq++;
-		old = bes->addr;
-		bes->last_addr = res;
-		bes->addr = res;
-		if (old != NULL)
-			freeaddrinfo(old);
-	}
-
 	/* And try the entire list */
 	s = bes_conn_try_list(sp, bes);
 	if (s >= 0) {
@@ -363,6 +366,7 @@
 {
 	struct backend *b;
 	struct bes *bes;
+	const char *p;
 	
 	/*
 	 * Scan existing backends to see if we can recycle one of them.
@@ -402,5 +406,16 @@
 	AN(t->host);
 	REPLACE(bes->hostname, t->host);
 
+	/*
+	 * The VCL compiler already did a lookup, but we'll do another one
+	 * here, just in case...
+	 */
+	LOCK(&b->mtx);
+	p = bes_dns_lookup(b);
+	UNLOCK(&b->mtx);
+	if (p != NULL)
+		printf("Warning: could not lookup backend %s (%s:%s): %s",
+		    t->name, t->host, t->port, p);
+
 	*bp = b;
 }




More information about the varnish-commit mailing list