]> err.no Git - varnish/commitdiff
Privatize the "simple" aspect of the simple backend.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 12:45:58 +0000 (12:45 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 12:45:58 +0000 (12:45 +0000)
Move the VRT initializer for simple backends home.

Add a backend method to get hostname.  This may be a hack.

Move fields private to "simple" to its private structure.

Add cleanup method to backend, so we can collect the garbage.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1895 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_backend_simple.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_vrt.c

index d6895b19f4868cb31d94a99e65435962a22d4046..21c74f0130c2448275ce36f4b9fb88411a55dce3 100644 (file)
@@ -334,12 +334,16 @@ typedef struct vbe_conn *vbe_getfd_f(struct sess *sp);
 typedef void vbe_close_f(struct worker *w, struct vbe_conn *vc);
 typedef void vbe_recycle_f(struct worker *w, struct vbe_conn *vc);
 typedef void vbe_init_f(void);
+typedef const char *vbe_gethostname_f(struct backend *);
+typedef void vbe_cleanup_f(struct backend *);
 
 struct backend_method {
        const char              *name;
        vbe_getfd_f             *getfd;
        vbe_close_f             *close;
        vbe_recycle_f           *recycle;
+       vbe_cleanup_f           *cleanup;
+       vbe_gethostname_f       *gethostname;
        vbe_init_f              *init;
 };
 
@@ -353,29 +357,11 @@ struct backend {
        int                     refcount;
 
        struct backend_method   *method;
-
-       char                    *hostname;
-       char                    *portname;
-
-       struct addrinfo         *addr;
-       struct addrinfo         *last_addr;
-
-       TAILQ_HEAD(,vbe_conn)   connlist;
-
-       double                  dnsttl;
-       double                  dnstime;
+       void                    *priv;
 
        int                     health;
        double                  last_check;
        int                     minute_limit;
-       
-#if 0
-       double                  responsetime;
-       double                  timeout;
-       double                  bandwidth;
-       int                     down;
-#endif
-
 };
 
 /*
index 1d1bad190daa9057e7fcc2f0e03e1d07f09c7846..8d392c16b69f72278c2a464ad5181e3c67244403 100644 (file)
@@ -98,9 +98,10 @@ VBE_NewBackend(struct backend_method *method)
        b = calloc(sizeof *b, 1);
        XXXAN(b);
        b->magic = BACKEND_MAGIC;
-       TAILQ_INIT(&b->connlist);
        b->method = method;
        b->refcount = 1;
+       b->last_check = TIM_mono();
+       b->minute_limit = 1;
        TAILQ_INSERT_TAIL(&backendlist, b, list);
        return (b);
 }
@@ -117,9 +118,8 @@ VBE_DropRef(struct backend *b)
        if (b->refcount > 0)
                return;
        TAILQ_REMOVE(&backendlist, b, list);
+       b->method->cleanup(b);
        free(b->vcl_name);
-       free(b->portname);
-       free(b->hostname);
        free(b);
 }
 
index d36272a23582112a5601d92f8f92ea996d30aa3c..53623cfa68a89b75132c4f1a9ed1386f76f8d72b 100644 (file)
 
 #include "shmlog.h"
 #include "cache.h"
+#include "vrt.h"
 
 static TAILQ_HEAD(,vbe_conn) vbe_head = TAILQ_HEAD_INITIALIZER(vbe_head);
 
 static MTX besmtx;
 
+struct bes {
+       unsigned                magic;
+#define BES_MAGIC              0x015e17ac
+       char                    *hostname;
+       char                    *portname;
+       struct addrinfo         *addr;
+       struct addrinfo         *last_addr;
+       double                  dnsttl;
+       double                  dnstime;
+       TAILQ_HEAD(, vbe_conn)  connlist;
+};
+
 /*--------------------------------------------------------------------*/
 
 static struct vbe_conn *
@@ -81,24 +94,27 @@ bes_lookup(struct backend *bp)
 {
        struct addrinfo *res, hint, *old;
        int error;
+       struct bes *bes;
+
+       CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
 
        memset(&hint, 0, sizeof hint);
        hint.ai_family = PF_UNSPEC;
        hint.ai_socktype = SOCK_STREAM;
        res = NULL;
-       error = getaddrinfo(bp->hostname,
-           bp->portname == NULL ? "http" : bp->portname,
+       error = getaddrinfo(bes->hostname,
+           bes->portname == NULL ? "http" : bes->portname,
            &hint, &res);
-       bp->dnstime = TIM_mono();
+       bes->dnstime = TIM_mono();
        if (error) {
                if (res != NULL)
                        freeaddrinfo(res);
                printf("getaddrinfo: %s\n", gai_strerror(error)); /* XXX */
                return;
        }
-       old = bp->addr;
-       bp->last_addr = res;
-       bp->addr = res;
+       old = bes->addr;
+       bes->last_addr = res;
+       bes->addr = res;
        if (old != NULL)
                freeaddrinfo(old);
 }
@@ -125,38 +141,41 @@ bes_conn_try(struct backend *bp, struct addrinfo **pai)
 {
        struct addrinfo *ai;
        int s;
+       struct bes *bes;
+
+       CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
 
        /* First try the cached good address, and any following it */
-       for (ai = bp->last_addr; ai != NULL; ai = ai->ai_next) {
+       for (ai = bes->last_addr; ai != NULL; ai = ai->ai_next) {
                s = bes_sock_conn(ai);
                if (s >= 0) {
-                       bp->last_addr = ai;
+                       bes->last_addr = ai;
                        *pai = ai;
                        return (s);
                }
        }
 
        /* Then try the list until the cached last good address */
-       for (ai = bp->addr; ai != bp->last_addr; ai = ai->ai_next) {
+       for (ai = bes->addr; ai != bes->last_addr; ai = ai->ai_next) {
                s = bes_sock_conn(ai);
                if (s >= 0) {
-                       bp->last_addr = ai;
+                       bes->last_addr = ai;
                        *pai = ai;
                        return (s);
                }
        }
 
-       if (bp->dnstime + bp->dnsttl >= TIM_mono())
+       if (bes->dnstime + bes->dnsttl >= TIM_mono())
                return (-1);
 
        /* Then do another lookup to catch DNS changes */
        bes_lookup(bp);
 
        /* And try the entire list */
-       for (ai = bp->addr; ai != NULL; ai = ai->ai_next) {
+       for (ai = bes->addr; ai != NULL; ai = ai->ai_next) {
                s = bes_sock_conn(ai);
                if (s >= 0) {
-                       bp->last_addr = ai;
+                       bes->last_addr = ai;
                        *pai = ai;
                        return (s);
                }
@@ -172,9 +191,12 @@ bes_connect(struct sess *sp, struct backend *bp)
        char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
        char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
        struct addrinfo *ai;
+       struct bes *bes;
+
 
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
-       AN(bp->hostname);
+       CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
+       AN(bes->hostname);
 
        s = bes_conn_try(bp, &ai);
        if (s < 0)
@@ -205,18 +227,20 @@ bes_nextfd(struct sess *sp)
        struct pollfd pfd;
        struct backend *bp;
        int reuse = 0;
+       struct bes *bes;
 
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
        bp = sp->backend;
        CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+       CAST_OBJ_NOTNULL(bes, bp->priv, BES_MAGIC);
        vc2 = NULL;
        while (1) {
                LOCK(&besmtx);
-               vc = TAILQ_FIRST(&bp->connlist);
+               vc = TAILQ_FIRST(&bes->connlist);
                if (vc != NULL) {
                        assert(vc->backend == bp);
                        assert(vc->fd >= 0);
-                       TAILQ_REMOVE(&bp->connlist, vc, list);
+                       TAILQ_REMOVE(&bes->connlist, vc, list);
                } else {
                        vc2 = TAILQ_FIRST(&vbe_head);
                        if (vc2 != NULL) {
@@ -319,34 +343,126 @@ bes_ClosedFd(struct worker *w, struct vbe_conn *vc)
 static void
 bes_RecycleFd(struct worker *w, struct vbe_conn *vc)
 {
+       struct bes *bes;
 
        CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC);
+       CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
+       CAST_OBJ_NOTNULL(bes, vc->backend->priv, BES_MAGIC);
+
        assert(vc->fd >= 0);
        AN(vc->backend);
        WSL(w, SLT_BackendReuse, vc->fd, "%s", vc->backend->vcl_name);
        LOCK(&besmtx);
        VSL_stats->backend_recycle++;
-       TAILQ_INSERT_HEAD(&vc->backend->connlist, vc, list);
+       TAILQ_INSERT_HEAD(&bes->connlist, vc, list);
        UNLOCK(&besmtx);
 }
 
 /*--------------------------------------------------------------------*/
 
 static void
-bes_Init(void)
+bes_Cleanup(struct backend *b)
 {
+       struct bes *bes;
+       struct vbe_conn *vbe;
 
-       MTX_INIT(&besmtx);
+       CAST_OBJ_NOTNULL(bes, b->priv, BES_MAGIC);
+       free(bes->portname);
+       free(bes->hostname);
+       freeaddrinfo(bes->addr);
+       while (1) {
+               vbe = TAILQ_FIRST(&bes->connlist);
+               if (vbe == NULL)
+                       break;
+               TAILQ_REMOVE(&bes->connlist, vbe, list);
+               if (vbe->fd >= 0)
+                       close(vbe->fd);
+               free(vbe);
+       }
+       free(bes);
 }
 
+/*--------------------------------------------------------------------*/
+
+static const char *
+bes_GetHostname(struct backend *b)
+{
+       struct bes *bes;
+
+       CHECK_OBJ_NOTNULL(b, SESS_MAGIC);
+       CAST_OBJ_NOTNULL(bes, b->priv, BES_MAGIC);
+       return (bes->hostname);
+}
 
 /*--------------------------------------------------------------------*/
 
+static void
+bes_Init(void)
+{
+
+       MTX_INIT(&besmtx);
+}
+
+/*--------------------------------------------------------------------*/
 
 struct backend_method backend_method_simple = {
        .name =                 "simple",
        .getfd =                bes_GetFd,
        .close =                bes_ClosedFd,
        .recycle =              bes_RecycleFd,
+       .gethostname =          bes_GetHostname,
+       .cleanup =              bes_Cleanup,
        .init =                 bes_Init
 };
+
+/*--------------------------------------------------------------------*/
+
+void
+VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
+{
+       struct backend *b;
+       struct bes *bes;
+       
+       /*
+        * Scan existing backends to see if we can recycle one of them.
+        */
+       TAILQ_FOREACH(b, &backendlist, list) {
+               CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+               if (b->method != &backend_method_simple)
+                       continue;
+               if (strcmp(b->vcl_name, t->name))
+                       continue;
+               CAST_OBJ_NOTNULL(bes, b->priv, BES_MAGIC);
+               if (strcmp(bes->portname, t->port))
+                       continue;
+               if (strcmp(bes->hostname, t->host))
+                       continue;
+               b->refcount++;
+               *bp = b;
+               return;
+       }
+
+       b = VBE_NewBackend(&backend_method_simple);
+
+       bes = calloc(sizeof *bes, 1);
+       XXXAN(bes);
+       bes->magic = BES_MAGIC;
+
+       b->priv = bes;
+
+       bes->dnsttl = 300;
+
+       AN(t->name);
+       b->vcl_name = strdup(t->name);
+       XXXAN(b->vcl_name);
+
+       AN(t->port);
+       bes->portname = strdup(t->port);
+       XXXAN(bes->portname);
+
+       AN(t->host);
+       bes->hostname = strdup(t->host);
+       XXXAN(bes->hostname);
+
+       *bp = b;
+}
index 8834437e526d4c258cd5b445c40814614d9c67f8..50609e1e5bfe1f926d728a3f65765f933f1b9d6f 100644 (file)
@@ -800,9 +800,11 @@ http_FilterHeader(struct sess *sp, unsigned how)
        http_PrintfHeader(sp->wrk, sp->fd, hp, "X-Varnish: %u", sp->xid);
        http_PrintfHeader(sp->wrk, sp->fd, hp,
            "X-Forwarded-for: %s", sp->addr);
+
+       /* XXX: This really ought to go into the default VCL */
        if (!http_GetHdr(hp, H_Host, &b)) {
                http_PrintfHeader(sp->wrk, sp->fd, hp, "Host: %s",
-                   sp->backend->hostname);
+                   sp->backend->method->gethostname(sp->backend));
        }
        sp->bereq = bereq;
 }
index 6ccfaacdbf6dd2ee5d3929dcbccbd6b4c3947a14..d04295877341b77acab9758235646eebfdd30cc4 100644 (file)
@@ -513,51 +513,8 @@ VRT_strcmp(const char *s1, const char *s2)
 
 
 /*--------------------------------------------------------------------
- * Backend stuff, should probably move to its own file eventually
+ * Backend stuff
  */
-void
-VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
-{
-       struct backend *b;
-       
-       /*
-        * Scan existing backends to see if we can recycle one of them.
-        */
-       TAILQ_FOREACH(b, &backendlist, list) {
-               CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
-               if (b->method != &backend_method_simple)
-                       continue;
-               if (strcmp(b->vcl_name, t->name))
-                       continue;
-               if (strcmp(b->portname, t->port))
-                       continue;
-               if (strcmp(b->hostname, t->host))
-                       continue;
-               b->refcount++;
-               *bp = b;
-               return;
-       }
-
-       b = VBE_NewBackend(&backend_method_simple);
-
-       b->dnsttl = 300;
-       b->last_check = TIM_mono();
-       b->minute_limit = 1;
-
-       AN(t->name);
-       b->vcl_name = strdup(t->name);
-       XXXAN(b->vcl_name);
-
-       AN(t->port);
-       b->portname = strdup(t->port);
-       XXXAN(b->portname);
-
-       AN(t->host);
-       b->hostname = strdup(t->host);
-       XXXAN(b->hostname);
-
-       *bp = b;
-}
 
 void
 VRT_fini_backend(struct backend *b)