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