]> err.no Git - varnish/commitdiff
First part of major backend overhaul.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 6 Feb 2008 15:19:49 +0000 (15:19 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 6 Feb 2008 15:19:49 +0000 (15:19 +0000)
*** Please do not use -trunk in production until I say so again ***

I have not entirely decided in the precise terminology, so the following
may sound a lot more complicated than it really is:

In VCL we can now have "backends" and "directors" both of which we
treat as a "backend".

When we define backends and directors in VCL, they refer to "backend
hosts" which is just another way to say "hostname+portname" but later
these will grow other parameters (max connections etc).

A director is a piece of code that selects a "backend host" somehow,
"random" and "round-robin" are the first algorithms.  A backend
can still be specified directly of course, that's the "simple director"
that always return the same "backend host".

This is probably where an example is in order:

/* A backend as we know it */
backend b1 {
.host = "fs";
.port = "80";
}

/* A director */
director b2 random {
{
/* We can refer to named backends */
.backend        = b1;
.weight         = 7;
}
{
/* Or define them inline */
.backend        = {
.host = "fs2";
}
.weight         = 3;
}
}

sub vcl_recv {
if (req.url ~ "\[[a-z]]") {
set req.backend = b2;
} else {
set req.backend = b1;
}
}

This results in quite a lot of changes in the C code, VRT API and
VCL compiler, the major thrust being:

Directors like "simple" and "random" will not have to think about
the actual connections to the backends, but just concentrate on
selecting which backend should be used.

When a new VCL is loaded, it will instantiate all directors, but
try to reuse any preexisting "backend hosts" (which we still
call "backend" in the C code).

This is simple for a backend like "b1" in the example above, but
sligthly more complex for the backend inlined in b2.  The VCL
compiler solves this, by qualifying the ident string for the inlined
backend host with the prefix "b2 random :: 2 :: ", so that a reload
of the same director with the same (unchanged) inline backend host
will match, but none other will.

One implication of instantiating all directors for every VCL load,
is that private statistics cannot be reused, but stats on the
backend host can.  This is likely a very fine point of no consequence.

Once the backend is selected by the director, the generic code in
cache_backend.c will cope with reusing the connection pool,
establishing connections and all that, moving most of the nastyness
out of directors, leaving cache_dir_simple.c with only 96 lines of
code, of which the license is a large fraction.

Until now, we have done automatic DNS re-lookups, but they seem to
cause more grief than advantage (I suspect some of the DNS lookups
to be resposible for long timeouts), so that will be dropped, and
instead we might add an explicit CLI command for this later.

The code as here committed can handle a couple of simple requests,
but there are a large number of INCOMPL()'s that need to be resolved
before this is ready for prime time again.

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

21 files changed:
varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_backend_random.c
varnish-cache/bin/varnishd/cache_backend_simple.c
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_dir_simple.c [new file with mode: 0644]
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cache_panic.c
varnish-cache/bin/varnishd/cache_vcl.c
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/include/vcl.h
varnish-cache/include/vrt.h
varnish-cache/include/vrt_obj.h
varnish-cache/lib/libvcl/vcc_backend.c
varnish-cache/lib/libvcl/vcc_compile.c
varnish-cache/lib/libvcl/vcc_fixed_token.c
varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl
varnish-cache/lib/libvcl/vcc_gen_obj.tcl

index e152b0f80c7fdf1d08c753417b4f234ce796e2cb..7303da0f8123d9814d67d8f2eaa944836ff48873 100644 (file)
@@ -18,6 +18,7 @@ varnishd_SOURCES = \
        cache_ban.c \
        cache_center.c \
        cache_cli.c \
+       cache_dir_simple.c \
        cache_expire.c \
        cache_fetch.c \
        cache_hash.c \
index c23693349bf487f711a549c547b799d79f1de801..7a404b7408d9f8f23b3224dcae1a7b7fdbd69f0b 100644 (file)
@@ -76,6 +76,7 @@ struct objhead;
 struct workreq;
 struct addrinfo;
 struct esi_bit;
+struct vrt_backend;
 
 /*--------------------------------------------------------------------*/
 
@@ -345,6 +346,7 @@ struct sess {
 
        VTAILQ_ENTRY(sess)      list;
 
+       struct director         *director;
        struct backend          *backend;
        struct bereq            *bereq;
        struct object           *obj;
@@ -364,6 +366,23 @@ struct sess {
        const char              **hashptr;
 };
 
+/* -------------------------------------------------------------------
+ * A director is a piece of code which selects one of possibly multiple
+ * backends to use.
+ */
+
+typedef struct backend *vdi_choose_f(struct sess *sp);
+typedef void vdi_fini_f(struct director *d);
+
+struct director {
+       unsigned                magic;
+#define DIRECTOR_MAGIC         0x3336351d
+       const char              *name;
+       vdi_choose_f            *choose;
+       vdi_fini_f              *fini;
+       void                    *priv;
+};
+
 /* -------------------------------------------------------------------*/
 
 /* Backend connection */
@@ -376,46 +395,6 @@ struct vbe_conn {
        void                    *priv;
 };
 
-
-/* Backend method */
-typedef struct vbe_conn *vbe_getfd_f(const 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(const struct backend *);
-typedef void vbe_cleanup_f(const struct backend *);
-typedef void vbe_updatehealth_f(const struct sess *sp, const struct vbe_conn *vc, int);
-
-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_updatehealth_f      *updatehealth;
-       vbe_init_f              *init;
-};
-
-/* Backend indstance */
-struct backend {
-       unsigned                magic;
-#define BACKEND_MAGIC          0x64c4c7c6
-       char                    *vcl_name;
-
-       VTAILQ_ENTRY(backend)   list;
-       int                     refcount;
-       pthread_mutex_t         mtx;
-
-       struct backend_method   *method;
-       const char              *ident;
-       void                    *priv;
-
-       int                     health;
-       double                  last_check;
-       int                     minute_limit;
-};
-
 /*
  * NB: This list is not locked, it is only ever manipulated from the
  * cachers CLI thread.
@@ -435,7 +414,7 @@ extern int vca_pipes[2];
 /* cache_backend.c */
 
 void VBE_Init(void);
-struct vbe_conn *VBE_GetFd(const struct sess *sp);
+struct vbe_conn *VBE_GetFd(struct sess *sp);
 void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc);
 void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc);
 struct bereq * VBE_new_bereq(void);
@@ -443,7 +422,7 @@ void VBE_free_bereq(struct bereq *bereq);
 extern struct backendlist backendlist;
 void VBE_DropRef(struct backend *);
 void VBE_DropRefLocked(struct backend *);
-int VBE_AddBackend(struct backend_method *method, const char *ident, struct backend **be);
+struct backend *VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb);
 struct vbe_conn *VBE_NewConn(void);
 void VBE_ReleaseConn(struct vbe_conn *);
 void VBE_UpdateHealth(const struct sess *sp, const struct vbe_conn *, int);
@@ -452,11 +431,6 @@ void VBE_UpdateHealth(const struct sess *sp, const struct vbe_conn *, int);
 int VBE_TryConnect(const struct sess *sp, const struct addrinfo *ai);
 int VBE_CheckFd(int fd);
 
-/* cache_backend_simple.c */
-extern struct backend_method   backend_method_simple;
-extern struct backend_method   backend_method_random;
-extern struct backend_method   backend_method_round_robin;
-
 /* cache_ban.c */
 void AddBan(const char *, int hash);
 void BAN_Init(void);
index 68450b6e35309317e783bec653c3f09aefd6d322..efd809dedccfb5bef93fcb27b49958d9749ef993 100644 (file)
@@ -32,6 +32,7 @@
  *
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include "heritage.h"
 #include "shmlog.h"
 #include "cache.h"
+#include "vrt.h"
+#include "cli_priv.h"
+
+/* Backend indstance */
+struct backend {
+       unsigned                magic;
+#define BACKEND_MAGIC          0x64c4c7c6
+       char                    *vcl_name;
+
+       struct vrt_backend      vrt[1];
+
+       VTAILQ_ENTRY(backend)   list;
+       int                     refcount;
+       pthread_mutex_t         mtx;
+
+       const char              *ident;
+       struct addrinfo         *ai;
+       struct addrinfo         *last_ai;
+
+       VTAILQ_HEAD(, vbe_conn) connlist;
+
+       int                     health;
+       double                  last_check;
+};
 
 static VTAILQ_HEAD(,bereq) bereq_head = VTAILQ_HEAD_INITIALIZER(bereq_head);
 static VTAILQ_HEAD(,vbe_conn) vbe_head = VTAILQ_HEAD_INITIALIZER(vbe_head);
@@ -217,20 +242,27 @@ void
 VBE_DropRefLocked(struct backend *b)
 {
        int i;
+       struct vbe_conn *vbe, *vbe2;
 
        CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
 
        i = --b->refcount;
-       if (i == 0) {
-               ASSERT_CLI();   /* XXX: ?? */
-               VTAILQ_REMOVE(&backendlist, b, list);
-       }
        UNLOCK(&b->mtx);
        if (i)
                return;
+
+       ASSERT_CLI();   /* XXX: ?? */
+       VTAILQ_REMOVE(&backendlist, b, list);
+       VTAILQ_FOREACH_SAFE(vbe, &b->connlist, list, vbe2) {
+               VTAILQ_REMOVE(&b->connlist, vbe, list);
+               if (vbe->fd >= 0)
+                       AZ(close(vbe->fd));
+               FREE_OBJ(vbe);
+       }
+       free(TRUST_ME(b->vrt->ident));
+       free(TRUST_ME(b->vrt->hostname));
+       free(TRUST_ME(b->vrt->portname));
        b->magic = 0;
-       b->method->cleanup(b);
-       free(b->vcl_name);
        free(b);
 }
 
@@ -244,17 +276,116 @@ VBE_DropRef(struct backend *b)
        VBE_DropRefLocked(b);
 }
 
+/*--------------------------------------------------------------------
+ * 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(const struct sess *sp, struct backend *bp)
+{
+       struct addrinfo *ai, *from;
+       int s, loops;
+
+       CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+       if (bp->last_ai == NULL)
+               return (-1);
+       AN(bp->ai);
+
+       /* Called with lock held */
+       loops = 0;
+       ai = from = bp->last_ai;
+       while (1) {
+
+               /* NB: releases/acquires backend lock */
+               s = VBE_TryConnect(sp, ai);
+
+               if (s >= 0) { 
+                       bp->last_ai = ai;
+                       return (s);
+               }
+
+               /* Try next one */
+               ai = ai->ai_next;
+               if (ai == NULL) {
+                       loops++;
+                       ai = bp->ai;
+               }
+               if (loops == 1 && ai == from)
+                       return (-1);
+       }
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static int
+bes_conn_try(const struct sess *sp, struct backend *bp)
+{
+       int s;
+
+       LOCK(&bp->mtx);
+
+       s = bes_conn_try_list(sp, bp);
+       if (s >= 0) {
+               bp->refcount++;
+               UNLOCK(&bp->mtx);
+               return (s);
+       }
+       UNLOCK(&bp->mtx);
+       return (-1);
+}
+
 /*--------------------------------------------------------------------*/
 
 struct vbe_conn *
-VBE_GetFd(const struct sess *sp)
+VBE_GetFd(struct sess *sp)
 {
+       struct backend *bp;
+       struct vbe_conn *vc;
 
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
-       AN(sp->backend->method);
-       AN(sp->backend->method->getfd);
-       return(sp->backend->method->getfd(sp));
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+       bp = sp->director->choose(sp);
+       CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+       sp->backend = bp;
+
+       while (1) {
+               LOCK(&bp->mtx);
+               vc = VTAILQ_FIRST(&bp->connlist);
+               if (vc != NULL) {
+                       bp->refcount++;
+                       assert(vc->backend == bp);
+                       assert(vc->fd >= 0);
+                       VTAILQ_REMOVE(&bp->connlist, vc, list);
+               }
+               UNLOCK(&bp->mtx);
+               if (vc == NULL)
+                       break;
+               if (VBE_CheckFd(vc->fd)) {
+                       /* XXX locking of stats */
+                       VSL_stats->backend_reuse += 1;
+                       VSL_stats->backend_conn++;
+                       return (vc);
+               }
+               VBE_ClosedFd(sp->wrk, vc);
+       }
+
+       vc = VBE_NewConn();
+       assert(vc->fd == -1);
+       AZ(vc->backend);
+       vc->fd = bes_conn_try(sp, bp);
+       if (vc->fd < 0) {
+               VBE_ReleaseConn(vc);
+               VSL_stats->backend_fail++;
+               return (NULL);
+       }
+       vc->backend = bp;
+       VSL_stats->backend_conn++;
+       return (vc);
 }
 
 /* Close a connection ------------------------------------------------*/
@@ -263,13 +394,19 @@ void
 VBE_ClosedFd(struct worker *w, struct vbe_conn *vc)
 {
        struct backend *b;
+       int i;
 
        CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC);
        CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
        b = vc->backend;
-       AN(b->method);
-       AN(b->method->close);
-       b->method->close(w, vc);
+       assert(vc->fd >= 0);
+       WSL(w, SLT_BackendClose, vc->fd, "%s", vc->backend->vcl_name);
+       i = close(vc->fd);
+       assert(i == 0 || errno == ECONNRESET || errno == ENOTCONN);
+       vc->fd = -1;
+       VBE_DropRef(vc->backend);
+       vc->backend = NULL;
+       VBE_ReleaseConn(vc);
        CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
 }
 
@@ -278,15 +415,18 @@ VBE_ClosedFd(struct worker *w, struct vbe_conn *vc)
 void
 VBE_RecycleFd(struct worker *w, struct vbe_conn *vc)
 {
-       struct backend *b;
+       struct backend *bp;
 
        CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC);
        CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
-       b = vc->backend;
-       AN(b->method);
-       AN(b->method->recycle);
-       b->method->recycle(w, vc);
-       CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+       assert(vc->fd >= 0);
+       bp = vc->backend;
+       WSL(w, SLT_BackendReuse, vc->fd, "%s", vc->backend->vcl_name);
+       LOCK(&vc->backend->mtx);
+       VSL_stats->backend_recycle++;
+       VTAILQ_INSERT_HEAD(&bp->connlist, vc, list);
+       VBE_DropRefLocked(vc->backend);
+       CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
 }
 
 /* Update health ----------------------------------------------------*/
@@ -296,6 +436,11 @@ VBE_RecycleFd(struct worker *w, struct vbe_conn *vc)
 void
 VBE_UpdateHealth(const struct sess *sp, const struct vbe_conn *vc, int a)
 {
+       (void)sp;
+       (void)vc;
+       (void)a;
+#if 0
+       INCOMPL();
        struct backend *b;
 
        if (vc != NULL) {
@@ -312,16 +457,47 @@ VBE_UpdateHealth(const struct sess *sp, const struct vbe_conn *vc, int a)
        if(b->method->updatehealth != NULL)
                b->method->updatehealth(sp, vc, a);
        CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+#endif
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * DNS lookup of backend host/port
+ */
 
 static void
-VBE_AddBackendMethod(const struct backend_method *bem)
+vbe_dns_lookup(struct cli *cli, struct backend *bp)
 {
-
-       if (bem->init != NULL)
-               bem->init();
+       int error;
+       struct addrinfo *res, hint, *old;
+
+       CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+
+       memset(&hint, 0, sizeof hint);
+       hint.ai_family = PF_UNSPEC;
+       hint.ai_socktype = SOCK_STREAM;
+       res = NULL;
+       error = getaddrinfo(bp->vrt->hostname, bp->vrt->portname,
+           &hint, &res);
+       if (error) {
+               if (res != NULL)
+                       freeaddrinfo(res);
+               /*
+                * We cannot point to the source code any more, it may
+                * be long gone from memory.   We already checked over in
+                * the VCL compiler, so this is only relevant for refreshes.
+                * XXX: which we do when exactly ?
+                */
+               cli_out(cli, "DNS(/hosts) lookup failed for (%s/%s): %s",
+                   bp->vrt->hostname, bp->vrt->portname, gai_strerror(error));
+               return;
+       }
+       LOCK(&bp->mtx);
+       old = bp->ai;
+       bp->ai = res;
+       bp->last_ai = res;
+       UNLOCK(&bp->mtx);
+       if (old != NULL)
+               freeaddrinfo(old);
 }
 
 /*--------------------------------------------------------------------
@@ -331,51 +507,74 @@ VBE_AddBackendMethod(const struct backend_method *bem)
  * and return zero.
  */
 
-int
-VBE_AddBackend(struct backend_method *method, const char *ident, struct backend **be)
+struct backend *
+VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
 {
        struct backend *b;
 
+       AN(vb->hostname);
+       AN(vb->portname);
+       AN(vb->ident);
+       (void)cli;
        ASSERT_CLI();
        VTAILQ_FOREACH(b, &backendlist, list) {
                CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
-               if (b->method != method)
-                       continue;
-               if (strcmp(b->ident, ident))
+               if (strcmp(b->ident, vb->ident))
                        continue;
                b->refcount++;
-               *be = b;
-               return (1);
+               return (b);
        }
 
        b = calloc(sizeof *b, 1);
        XXXAN(b);
        b->magic = BACKEND_MAGIC;
-       b->method = method;
-       b->ident = strdup(ident);
-       XXXAN(b->ident);
+       VTAILQ_INIT(&b->connlist);
+
+       memcpy(b->vrt, vb, sizeof *vb);
+       /*
+        * This backend may live longer than the VCL that instantiated it
+        * so we cannot simply reference the VCL's copy of the strings.
+        */
+       b->vrt->ident = strdup(vb->ident);
+       XXXAN(b->vrt->ident);
+       b->vrt->hostname = strdup(vb->hostname);
+       XXXAN(b->vrt->hostname);
+       b->vrt->portname = strdup(vb->portname);
+       XXXAN(b->vrt->portname);
 
        MTX_INIT(&b->mtx);
        b->refcount = 1;
 
+       vbe_dns_lookup(cli, b);
+
        b->last_check = TIM_mono();
-       b->minute_limit = 1;
+
+       vbe_dns_lookup(cli, b);
 
        VTAILQ_INSERT_TAIL(&backendlist, b, list);
-       *be = b;
-       return (0);
+       return (b);
 }
 
+
 /*--------------------------------------------------------------------*/
 
 void
-VBE_Init(void)
+VRT_fini_dir(struct cli *cli, struct director *b)
 {
 
-       MTX_INIT(&VBE_mtx);
-       VBE_AddBackendMethod(&backend_method_simple);
-       VBE_AddBackendMethod(&backend_method_random);
+       ASSERT_CLI();
 #if 0
-       VBE_AddBackendMethod(&backend_method_round_robin);
+       VBE_DropRef(b); 
+#else
+       (void)b;
+       (void)cli;
 #endif
 }
+/*--------------------------------------------------------------------*/
+
+void
+VBE_Init(void)
+{
+
+       MTX_INIT(&VBE_mtx);
+}
index f1889133233d8530966fb85c950d767bc224a083..c4586e58641ccb584628a6a518ed14ea57d1742a 100644 (file)
@@ -45,6 +45,7 @@
 #include "vrt.h"
 
 
+#if 0
 struct ber {
        unsigned                magic;
 #define BER_MAGIC              0x645b03f4
@@ -434,22 +435,27 @@ struct backend_method backend_method_random = {
        .cleanup =              ber_Cleanup,
 };
 
+#endif
+
 /*--------------------------------------------------------------------*/
 
 void
-VRT_init_random_backend(struct backend **bp, const struct vrt_dir_random *t)
+VRT_init_dir_random(struct cli *cli, struct director **bp, const struct vrt_dir_random *t)
 {
-       struct backend *b;
+       (void)cli;
        (void)bp;
        (void)t;
+       
+
+#if 0
+       struct backend *b;
 
        if (VBE_AddBackend(&backend_method_random, t->ident, bp))
                return;         /* reuse existing backend */
 
-       b = *bp;
+       bp = *bp;
        AN(t->name);
        REPLACE(b->vcl_name, t->name);
-#if 0
        struct backend *b;
        struct ber *ber;
        struct vrt_backend_entry *be;
index 3fcf56bbc8c99d44d04696ed88231d96ee0aaef4..60a6a83c6c69b2b8a90325f9ecfeb6c42e4add84 100644 (file)
@@ -44,6 +44,8 @@
 #include "cache.h"
 #include "vrt.h"
 
+#if 0
+
 struct bes {
        unsigned                magic;
 #define BES_MAGIC              0x015e17ac
@@ -343,55 +345,5 @@ bes_GetHostname(const struct backend *b)
        return (bes->hostname);
 }
 
-/*--------------------------------------------------------------------*/
 
-struct backend_method backend_method_simple = {
-       .name =                 "simple",
-       .getfd =                bes_GetFd,
-       .close =                bes_ClosedFd,
-       .recycle =              bes_RecycleFd,
-       .gethostname =          bes_GetHostname,
-       .cleanup =              bes_Cleanup,
-};
-
-/*--------------------------------------------------------------------*/
-
-void
-VRT_init_simple_backend(struct backend **bp, const struct vrt_simple_backend *t)
-{
-       struct backend *b;
-       struct bes *bes;
-       const char *p;
-       
-       if (VBE_AddBackend(&backend_method_simple, t->ident, bp))
-               return;         /* ref to existing backend */
-
-       b = *bp;
-       AN(t->name);
-       REPLACE(b->vcl_name, t->name);
-
-       bes = calloc(sizeof *bes, 1);
-       XXXAN(bes);
-       bes->magic = BES_MAGIC;
-
-       b->priv = bes;
-
-       bes->dnsttl = 300;
-
-       AN(t->host->portname);
-       REPLACE(bes->portname, t->host->portname);
-
-       AN(t->host->hostname);
-       REPLACE(bes->hostname, t->host->hostname);
-
-       /*
-        * 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",
-                   b->vcl_name, bes->hostname, bes->portname, p);
-}
+#endif
index de5693d641f8def745149527fa093266793742ce..8a1929a1ea1b2f940348b7bc8b83a7642c9fcd2e 100644 (file)
@@ -195,7 +195,12 @@ cnt_done(struct sess *sp)
 
        AZ(sp->obj);
        AZ(sp->bereq);
-       sp->backend = NULL;
+       sp->director = NULL;
+       sp->backend = NULL;             /*
+                                        * XXX: we may want to leave this
+                                        * behind to hint directors ?
+                                        */
+                                       
        if (sp->vcl != NULL) {
                if (sp->wrk->vcl != NULL)
                        VCL_Rel(&sp->wrk->vcl);
@@ -320,9 +325,9 @@ cnt_fetch(struct sess *sp)
        CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
 
        AN(sp->bereq);
-       CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
        i = Fetch(sp);
-       CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
 
        if (!i)
                RFC2616_cache_policy(sp, sp->obj->http);        /* XXX -> VCL */
@@ -841,9 +846,9 @@ cnt_start(struct sess *sp)
        sp->doclose = http_DoConnection(sp->http);
 
        /* By default we use the first backend */
-       AZ(sp->backend);
-       sp->backend = sp->vcl->backend[0];
-       CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
+       AZ(sp->director);
+       sp->director = sp->vcl->director[0];
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
 
        /* XXX: Handle TRACE & OPTIONS of Max-Forwards = 0 */
 
@@ -879,7 +884,7 @@ CNT_Session(struct sess *sp)
                CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
                CHECK_OBJ_ORNULL(w->nobj, OBJECT_MAGIC);
                CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC);
-               CHECK_OBJ_ORNULL(sp->backend, BACKEND_MAGIC);
+               CHECK_OBJ_ORNULL(sp->director, DIRECTOR_MAGIC);
 
                switch (sp->step) {
 #ifdef DIAGNOSTICS
diff --git a/varnish-cache/bin/varnishd/cache_dir_simple.c b/varnish-cache/bin/varnishd/cache_dir_simple.c
new file mode 100644 (file)
index 0000000..227f7cd
--- /dev/null
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2008 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "cache.h"
+#include "vrt.h"
+
+/*--------------------------------------------------------------------*/
+
+struct vdi_simple {
+       unsigned                magic;
+#define VDI_SIMPLE_MAGIC       0x476d25b7
+       struct director         dir;
+       struct backend          *backend;
+};
+
+static struct backend *
+vdi_simple_choose(struct sess *sp)
+{
+       struct vdi_simple *vs;
+
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+       CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_SIMPLE_MAGIC);
+       return (vs->backend);
+}
+
+static void
+vdi_simple_fini(struct director *d)
+{
+       struct vdi_simple *vs;
+
+       CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+       CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
+       
+       VBE_DropRef(vs->backend);
+       free(vs);
+}
+
+void
+VRT_init_dir_simple(struct cli *cli, struct director **bp, const struct vrt_dir_simple *t)
+{
+       struct vdi_simple *vs;
+       
+       (void)cli;
+
+       vs = calloc(sizeof *vs, 1);
+       XXXAN(vs);
+       vs->magic = VDI_SIMPLE_MAGIC;
+       vs->dir.magic = DIRECTOR_MAGIC;
+       vs->dir.priv = vs;
+       vs->dir.name = "simple";
+       vs->dir.choose = vdi_simple_choose;
+       vs->dir.fini = vdi_simple_fini;
+
+       vs->backend = VBE_AddBackend(cli, t->host);
+
+       *bp = &vs->dir;
+}
index 40b247725d0d00fde8389f8a6eebcbf5f3fc450e..929fe773fef75c5a9c8b812df11e66701eea03c7 100644 (file)
@@ -309,7 +309,7 @@ Fetch(struct sess *sp)
        CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
        CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
        CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC);
-       CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
        assert(sp->obj->busy != 0);
        w = sp->wrk;
        bereq = sp->bereq;
index 334eca68dedf444b2533442298f0e5b78cf63a94..78c260857a400ef8744d4171eb5d7c2d6df660c8 100644 (file)
@@ -649,8 +649,11 @@ http_FilterHeader(struct sess *sp, unsigned how)
 
        /* XXX: This really ought to go into the default VCL */
        if (!http_GetHdr(hp, H_Host, &b)) {
+#if 0
                http_PrintfHeader(sp->wrk, sp->fd, hp, "Host: %s",
                    sp->backend->method->gethostname(sp->backend));
+#endif
+               INCOMPL();
        }
        sp->bereq = bereq;
 }
index 1e85a45367ef240b278169cd1fff6c9df395a21b..b3cb169465d01b177faa171e13b6e489a2280291 100644 (file)
@@ -83,7 +83,6 @@ child_main(void)
        SZOF(struct objhead);
        SZOF(struct sess);
        SZOF(struct vbe_conn);
-       SZOF(struct backend);
 
 
        CNT_Init();
index 2ff64151a91a40503366e843ccbbcb2713457390..83d10bb52b8df2dc931e3c193575075a043a6ea2 100644 (file)
@@ -131,6 +131,7 @@ dump_object(const struct object *o)
        fp("  },\n");
 }
 
+#if 0
 /* dump a struct backend */
 static void
 dump_backend(const struct backend *be)
@@ -141,12 +142,15 @@ dump_backend(const struct backend *be)
            be->vcl_name ? be->vcl_name : "(null)");
        fp("  },\n");
 }
+#endif
 
 /* dump a struct sess */
 static void
 dump_sess(const struct sess *sp)
 {
+#if 0
        const struct backend *be = sp->backend;
+#endif
        const struct object *obj = sp->obj;
 
        fp("sp = %p {\n", sp);
@@ -162,8 +166,11 @@ dump_sess(const struct sess *sp)
                fp("  err_code = %d, err_reason = %s,\n", sp->err_code,
                    sp->err_reason ? sp->err_reason : "(null)");
 
+#if 0
        if (VALID_OBJ(be, BACKEND_MAGIC))
                dump_backend(be);
+       INCOMPL():
+#endif
 
        if (VALID_OBJ(obj, OBJECT_MAGIC))
                dump_object(obj);
index eb563874edb550fba8ed70f1e0f0d5868a4b412d..a2ae4b9d4a02be1a643fcde2d3f6653082be0323 100644 (file)
@@ -168,7 +168,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
                vcl_active = vcl;
        UNLOCK(&vcl_mtx);
        cli_out(cli, "Loaded \"%s\" as \"%s\"\n", fn , name);
-       vcl->conf->init_func();
+       vcl->conf->init_func(cli);
        return (0);
 }
 
@@ -186,7 +186,7 @@ VCL_Nuke(struct vcls *vcl)
        assert(vcl->conf->discard);
        assert(vcl->conf->busy == 0);
        VTAILQ_REMOVE(&vcl_head, vcl, list);
-       vcl->conf->fini_func();
+       vcl->conf->fini_func(NULL);
        free(vcl->name);
        free(vcl);
 }
index d4e8d1389296f62e60f9cefa31f3da332f93dc48..503b7a788f14dfdd974b1dfdf609001c3fc53fa6 100644 (file)
@@ -391,17 +391,17 @@ VOBJ(unsigned, cacheable, cacheable)
 /*--------------------------------------------------------------------*/
 
 void
-VRT_l_req_backend(struct sess *sp, struct backend *be)
+VRT_l_req_backend(struct sess *sp, struct director *be)
 {
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       sp->backend = be;
+       sp->director = be;
 }
 
-struct backend *
+struct director *
 VRT_r_req_backend(struct sess *sp)
 {
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-       return (sp->backend);
+       return (sp->director);
 }
 
 /*--------------------------------------------------------------------*/
@@ -543,10 +543,14 @@ VRT_r_obj_lastuse(const struct sess *sp)
 int
 VRT_r_backend_health(const struct sess *sp)
 {
-       
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+#if 0  
        CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
        return (sp->backend->health);
+#else
+       INCOMPL();
+       return (0);
+#endif
 }
 
 /*--------------------------------------------------------------------*/
@@ -621,15 +625,3 @@ VRT_strcmp(const char *s1, const char *s2)
        return (strcmp(s1, s2));
 }
 
-
-/*--------------------------------------------------------------------
- * Backend stuff
- */
-
-void
-VRT_fini_backend(struct backend *b)
-{
-
-       ASSERT_CLI();
-       VBE_DropRef(b); 
-}
index 98c5424be1559a1758784933e23ceee4818610d5..18d0479a6e86505423c63467ed391d897b0dde08 100644 (file)
@@ -7,17 +7,18 @@
  */
 
 struct sess;
+struct cli;
 
-typedef void vcl_init_f(void);
-typedef void vcl_fini_f(void);
+typedef void vcl_init_f(struct cli *);
+typedef void vcl_fini_f(struct cli *);
 typedef int vcl_func_f(struct sess *sp);
 
 struct VCL_conf {
        unsigned        magic;
 #define VCL_CONF_MAGIC  0x7406c509      /* from /dev/random */
 
-        struct backend  **backend;
-        unsigned        nbackend;
+        struct director  **director;
+        unsigned        ndirector;
         struct vrt_ref  *ref;
         unsigned        nref;
         unsigned        busy;
index 1c6e06f4b8a9768fad256f98e9896fc6329e5b1c..e6e4eabdf3dfcd17154a1f5792b1b57a0e010b6c 100644 (file)
 
 struct sess;
 struct vsb;
-struct backend;
+struct cli;
+struct director;
 struct VCL_conf;
 struct sockaddr;
 
-struct vrt_backend_host {
+/*
+ * A backend is a host+port somewhere on the network
+ */
+struct vrt_backend {
        const char      *portname;
        const char      *hostname;
        const char      *ident;
 };
 
-struct vrt_simple_backend {
-       const char                      *ident;
-       const char                      *name;
-       const struct vrt_backend_host   *host;
-};
+/*
+ * A director with a predictable reply
+ */
 
-struct vrt_backend_entry {
-       const char      *port;
-       const char      *host;
-       double          weight;
-       struct vrt_backend_entry *next;
+struct vrt_dir_simple {
+       const char                              *ident;
+       const char                              *name;
+       const struct vrt_backend                *host;
 };
 
-struct vrt_round_robin_backend {
-       const char      *name;
-       unsigned        count;
-       struct vrt_backend_entry *bentry;
-};
+/*
+ * A director with an unpredictable reply
+ */
 
 struct vrt_dir_random_entry {
-       const struct vrt_backend_host   *host;
-       double                          weight;
+       const struct vrt_backend                *host;
+       double                                  weight;
 };
 
 struct vrt_dir_random {
-       const char                      *ident;
-       const char                      *name;
-       unsigned                        nmember;
+       const char                              *ident;
+       const char                              *name;
+       unsigned                                nmember;
        const struct vrt_dir_random_entry       *members;
 };
 
-struct vrt_random_backend {
-       const char      *name;
-       unsigned        weighted;
-       unsigned        count;
-       struct vrt_backend_entry *bentry;
-};
-
+/*
+ * other stuff.
+ * XXX: document when bored
+ */
 
 struct vrt_ref {
        unsigned        source;
@@ -134,10 +130,9 @@ void VRT_ESI(struct sess *sp);
 void VRT_Rollback(struct sess *sp);
 
 /* Backend related */
-void VRT_init_simple_backend(struct backend **, const struct vrt_simple_backend *);
-void VRT_init_round_robin_backend(struct backend **, const struct vrt_round_robin_backend *);
-void VRT_init_random_backend(struct backend **, const struct vrt_dir_random *);
-void VRT_fini_backend(struct backend *);
+void VRT_init_dir_simple(struct cli *, struct director **, const struct vrt_dir_simple *);
+void VRT_init_dir_random(struct cli *, struct director **, const struct vrt_dir_random *);
+void VRT_fini_dir(struct cli *, struct director *);
 
 char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa);
 char *VRT_int_string(const struct sess *sp, int);
index d3aa010b89eadea99f4a1a747c88c0f1127a697f..ba294512c19031b7a541cb8c7ebc33a2ff1ae2eb 100644 (file)
@@ -15,8 +15,8 @@ void VRT_l_req_url(const struct sess *, const char *, ...);
 const char * VRT_r_req_proto(const struct sess *);
 void VRT_l_req_proto(const struct sess *, const char *, ...);
 void VRT_l_req_hash(struct sess *, const char *);
-struct backend * VRT_r_req_backend(struct sess *);
-void VRT_l_req_backend(struct sess *, struct backend *);
+struct director * VRT_r_req_backend(struct sess *);
+void VRT_l_req_backend(struct sess *, struct director *);
 int VRT_r_req_restarts(const struct sess *);
 double VRT_r_req_grace(struct sess *);
 void VRT_l_req_grace(struct sess *, double);
index 49f2a61304d1b9ff6a62bbbb6d3eb2062ae1ff6f..afeb9383125b7214ba4d2f2a9ae0fa16ff3859cc 100644 (file)
@@ -70,10 +70,16 @@ CheckHostPort(const char *host, const char *port)
  */
 
 static void
-vcc_EmitBeIdent(struct vsb *v, const struct token *first, const struct token *last)
+vcc_EmitBeIdent(struct vsb *v, const struct token *qual, int serial, const struct token *first, const struct token *last)
 {
 
        vsb_printf(v, "\t.ident =");
+       if (qual != NULL) {
+               vsb_printf(v, "\n\t    \"%.*s \"", PF(qual));
+               qual = VTAILQ_NEXT(qual, list);
+               vsb_printf(v, "\n\t    \"%.*s \"", PF(qual));
+               vsb_printf(v, "\n\t    \":: %d :: \"", serial);
+       }
        while (first != last) {
                if (first->dec != NULL)
                        vsb_printf(v, "\n\t    \"\\\"\" %.*s \"\\\" \"",
@@ -201,11 +207,11 @@ vcc_FieldsOk(struct tokenlist *tl, const struct fld_spec *fs)
  * be_element:
  *     '.' name '=' value ';'
  *
- * The struct vrt_backend_host is emitted to Fh().
+ * The struct vrt_backend is emitted to Fh().
  */
 
 static void
-vcc_ParseBackendHost(struct tokenlist *tl, int *nbh)
+vcc_ParseBackendHost(struct tokenlist *tl, int *nbh, const struct token *qual, int serial)
 {
        struct token *t_field;
        struct token *t_first;
@@ -240,7 +246,7 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh)
        vcc_NextToken(tl);
 
        *nbh = tl->nbackend_host++;
-       Fh(tl, 0, "\nstatic const struct vrt_backend_host bh_%d = {\n", *nbh);
+       Fh(tl, 0, "\nstatic const struct vrt_backend bh_%d = {\n", *nbh);
 
        /* Check for old syntax */
        if (tl->t->tok == ID && vcc_IdIs(tl->t, "set")) {
@@ -298,7 +304,7 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh)
        EncToken(tl->fh, t_host);
        Fh(tl, 0, ",\n");
 
-       /* Check that the hostname makes sense */
+       /* Check that the portname makes sense */
        if (t_port != NULL) {
                ep = CheckHostPort(t_host->dec, t_port->dec);
                if (ep != NULL) {
@@ -310,10 +316,12 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh)
                Fh(tl, 0, "\t.portname = ");
                EncToken(tl->fh, t_port);
                Fh(tl, 0, ",\n");
+       } else {
+               Fh(tl, 0, "\t.portname = \"80\",\n");
        }
 
        ExpectErr(tl, '}');
-       vcc_EmitBeIdent(tl->fh, t_first, tl->t);
+       vcc_EmitBeIdent(tl->fh, qual, serial, t_first, tl->t);
        Fh(tl, 0, "};\n");
        vcc_NextToken(tl);
 }
@@ -338,27 +346,28 @@ vcc_ParseBackend(struct tokenlist *tl)
        h->name = tl->t;
        vcc_NextToken(tl);
 
-       vcc_ParseBackendHost(tl, &nbh);
+       vcc_ParseBackendHost(tl, &nbh, NULL, 0);
        ERRCHK(tl);
 
        h->hnum = nbh;
        VTAILQ_INSERT_TAIL(&tl->hosts, h, list);
 
        /* In the compiled vcl we use these macros to refer to backends */
-       Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.backend[%d])\n",
+       Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n",
            PF(h->name), tl->nbackend);
 
        vcc_AddDef(tl, h->name, R_BACKEND);
 
-       Fi(tl, 0, "\tVRT_init_simple_backend(&VGC_backend_%.*s , &sbe_%.*s);\n",
+       Fi(tl, 0,
+           "\tVRT_init_dir_simple(cli, &VGC_backend_%.*s , &sbe_%.*s);\n",
            PF(h->name), PF(h->name));
-       Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%.*s);\n", PF(h->name));
+       Ff(tl, 0, "\tVRT_fini_dir(cli, VGC_backend_%.*s);\n", PF(h->name));
 
-       Fc(tl, 0, "\nstatic const struct vrt_simple_backend sbe_%.*s = {\n",
+       Fc(tl, 0, "\nstatic const struct vrt_dir_simple sbe_%.*s = {\n",
            PF(h->name));
        Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(h->name));
        Fc(tl, 0, "\t.host = &bh_%d,\n", nbh);
-       vcc_EmitBeIdent(tl->fc, t_first, tl->t);
+       vcc_EmitBeIdent(tl->fc, NULL, 0, t_first, tl->t);
        Fc(tl, 0, "};\n");
 
        tl->nbackend++;
@@ -375,7 +384,7 @@ vcc_ParseRandomDirector(struct tokenlist *tl, const struct token *t_first, struc
        int nbh, nelem;
        struct fld_spec *fs;
 
-       Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.backend[%d])\n",
+       Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n",
            PF(t_dir), tl->nbackend);
        vcc_AddDef(tl, t_dir, R_BACKEND);
 
@@ -402,7 +411,7 @@ vcc_ParseRandomDirector(struct tokenlist *tl, const struct token *t_first, struc
                        vcc_IsField(tl, &t_field, fs);
                        ERRCHK(tl);
                        if (vcc_IdIs(t_field, "backend")) {
-                               vcc_ParseBackendHost(tl, &nbh);
+                               vcc_ParseBackendHost(tl, &nbh, t_dir, nelem);
                                Fc(tl, 0, " .host = &bh_%d,", nbh);
                                ERRCHK(tl);
                        } else if (vcc_IdIs(t_field, "weight")) {
@@ -428,12 +437,13 @@ vcc_ParseRandomDirector(struct tokenlist *tl, const struct token *t_first, struc
        Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_dir));
        Fc(tl, 0, "\t.nmember = %d,\n", nelem);
        Fc(tl, 0, "\t.members = vdre_%.*s,\n", PF(t_dir));
-       vcc_EmitBeIdent(tl->fc, t_first, tl->t);
+       vcc_EmitBeIdent(tl->fc, NULL, 0, t_first, tl->t);
        Fc(tl, 0, "};\n");
        vcc_NextToken(tl);
-       Fi(tl, 0, "\tVRT_init_random_backend(&VGC_backend_%.*s , &vdr_%.*s);\n",
+       Fi(tl, 0,
+           "\tVRT_init_dir_random(cli, &VGC_backend_%.*s , &vdr_%.*s);\n",
            PF(t_dir), PF(t_dir));
-       Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%.*s);\n", PF(t_dir));
+       Ff(tl, 0, "\tVRT_fini_dir(cli, VGC_backend_%.*s);\n", PF(t_dir));
 }
 
 /*--------------------------------------------------------------------
index cf34db361110963a140e2c56914c17da4d8403e9..9416452c90b4134d6671c17a93aea4f6a8166c63 100644 (file)
@@ -295,7 +295,7 @@ static void
 EmitInitFunc(const struct tokenlist *tl)
 {
 
-       Fc(tl, 0, "\nstatic void\nVGC_Init(void)\n{\n\n");
+       Fc(tl, 0, "\nstatic void\nVGC_Init(struct cli *cli)\n{\n\n");
        vsb_finish(tl->fi);
        /* XXX: check vsb_overflowed ? */
        vsb_cat(tl->fc, vsb_data(tl->fi));
@@ -306,7 +306,7 @@ static void
 EmitFiniFunc(const struct tokenlist *tl)
 {
 
-       Fc(tl, 0, "\nstatic void\nVGC_Fini(void)\n{\n\n");
+       Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
        vsb_finish(tl->ff);
        /* XXX: check vsb_overflowed ? */
        vsb_cat(tl->fc, vsb_data(tl->ff));
@@ -339,14 +339,14 @@ EmitStruct(const struct tokenlist *tl)
        }
        Fc(tl, 0, "};\n");
 
-       Fc(tl, 0, "\nstatic struct backend\t*backends[%d];\n", tl->nbackend);
+       Fc(tl, 0, "\nstatic struct director\t*directors[%d];\n", tl->nbackend);
 
        Fc(tl, 0, "\nconst struct VCL_conf VCL_conf = {\n");
        Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
        Fc(tl, 0, "\t.init_func = VGC_Init,\n");
        Fc(tl, 0, "\t.fini_func = VGC_Fini,\n");
-       Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend);
-       Fc(tl, 0, "\t.backend = backends,\n");
+       Fc(tl, 0, "\t.ndirector = %d,\n", tl->nbackend);
+       Fc(tl, 0, "\t.director = directors,\n");
        Fc(tl, 0, "\t.ref = VGC_ref,\n");
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
        Fc(tl, 0, "\t.nsrc = %u,\n", tl->nsources);
index 65ab9e21ed7dd75f08e84368224b220c47ef3b4e..19f976e939e1d79a243a90220bc176698697cf22 100644 (file)
@@ -311,17 +311,18 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, " */\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct sess;\n");
+       vsb_cat(sb, "struct cli;\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "typedef void vcl_init_f(void);\n");
-       vsb_cat(sb, "typedef void vcl_fini_f(void);\n");
+       vsb_cat(sb, "typedef void vcl_init_f(struct cli *);\n");
+       vsb_cat(sb, "typedef void vcl_fini_f(struct cli *);\n");
        vsb_cat(sb, "typedef int vcl_func_f(struct sess *sp);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct VCL_conf {\n");
        vsb_cat(sb, "   unsigned        magic;\n");
        vsb_cat(sb, "#define VCL_CONF_MAGIC  0x7406c509      /* from /dev/random */\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "        struct backend  **backend;\n");
-       vsb_cat(sb, "        unsigned        nbackend;\n");
+       vsb_cat(sb, "        struct director  **director;\n");
+       vsb_cat(sb, "        unsigned        ndirector;\n");
        vsb_cat(sb, "        struct vrt_ref  *ref;\n");
        vsb_cat(sb, "        unsigned        nref;\n");
        vsb_cat(sb, "        unsigned        busy;\n");
@@ -388,54 +389,50 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct sess;\n");
        vsb_cat(sb, "struct vsb;\n");
-       vsb_cat(sb, "struct backend;\n");
+       vsb_cat(sb, "struct cli;\n");
+       vsb_cat(sb, "struct director;\n");
        vsb_cat(sb, "struct VCL_conf;\n");
        vsb_cat(sb, "struct sockaddr;\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "struct vrt_backend_host {\n");
+       vsb_cat(sb, "/*\n");
+       vsb_cat(sb, " * A backend is a host+port somewhere on the network\n");
+       vsb_cat(sb, " */\n");
+       vsb_cat(sb, "struct vrt_backend {\n");
        vsb_cat(sb, "   const char      *portname;\n");
        vsb_cat(sb, "   const char      *hostname;\n");
        vsb_cat(sb, "   const char      *ident;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "struct vrt_simple_backend {\n");
-       vsb_cat(sb, "   const char                      *ident;\n");
-       vsb_cat(sb, "   const char                      *name;\n");
-       vsb_cat(sb, "   const struct vrt_backend_host   *host;\n");
-       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "/*\n");
+       vsb_cat(sb, " * A director with a predictable reply\n");
+       vsb_cat(sb, " */\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "struct vrt_backend_entry {\n");
-       vsb_cat(sb, "   const char      *port;\n");
-       vsb_cat(sb, "   const char      *host;\n");
-       vsb_cat(sb, "   double          weight;\n");
-       vsb_cat(sb, "   struct vrt_backend_entry *next;\n");
+       vsb_cat(sb, "struct vrt_dir_simple {\n");
+       vsb_cat(sb, "   const char                              *ident;\n");
+       vsb_cat(sb, "   const char                              *name;\n");
+       vsb_cat(sb, "   const struct vrt_backend                *host;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "struct vrt_round_robin_backend {\n");
-       vsb_cat(sb, "   const char      *name;\n");
-       vsb_cat(sb, "   unsigned        count;\n");
-       vsb_cat(sb, "   struct vrt_backend_entry *bentry;\n");
-       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "/*\n");
+       vsb_cat(sb, " * A director with an unpredictable reply\n");
+       vsb_cat(sb, " */\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_dir_random_entry {\n");
-       vsb_cat(sb, "   const struct vrt_backend_host   *host;\n");
-       vsb_cat(sb, "   double                          weight;\n");
+       vsb_cat(sb, "   const struct vrt_backend                *host;\n");
+       vsb_cat(sb, "   double                                  weight;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_dir_random {\n");
-       vsb_cat(sb, "   const char                      *ident;\n");
-       vsb_cat(sb, "   const char                      *name;\n");
-       vsb_cat(sb, "   unsigned                        nmember;\n");
+       vsb_cat(sb, "   const char                              *ident;\n");
+       vsb_cat(sb, "   const char                              *name;\n");
+       vsb_cat(sb, "   unsigned                                nmember;\n");
        vsb_cat(sb, "   const struct vrt_dir_random_entry       *members;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
-       vsb_cat(sb, "struct vrt_random_backend {\n");
-       vsb_cat(sb, "   const char      *name;\n");
-       vsb_cat(sb, "   unsigned        weighted;\n");
-       vsb_cat(sb, "   unsigned        count;\n");
-       vsb_cat(sb, "   struct vrt_backend_entry *bentry;\n");
-       vsb_cat(sb, "};\n");
-       vsb_cat(sb, "\n");
+       vsb_cat(sb, "/*\n");
+       vsb_cat(sb, " * other stuff.\n");
+       vsb_cat(sb, " * XXX: document when bored\n");
+       vsb_cat(sb, " */\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_ref {\n");
        vsb_cat(sb, "   unsigned        source;\n");
@@ -486,10 +483,9 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "void VRT_Rollback(struct sess *sp);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "/* Backend related */\n");
-       vsb_cat(sb, "void VRT_init_simple_backend(struct backend **, const struct vrt_simple_backend *);\n");
-       vsb_cat(sb, "void VRT_init_round_robin_backend(struct backend **, const struct vrt_round_robin_backend *);\n");
-       vsb_cat(sb, "void VRT_init_random_backend(struct backend **, const struct vrt_dir_random *);\n");
-       vsb_cat(sb, "void VRT_fini_backend(struct backend *);\n");
+       vsb_cat(sb, "void VRT_init_dir_simple(struct cli *, struct director **, const struct vrt_dir_simple *);\n");
+       vsb_cat(sb, "void VRT_init_dir_random(struct cli *, struct director **, const struct vrt_dir_random *);\n");
+       vsb_cat(sb, "void VRT_fini_dir(struct cli *, struct director *);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa);\n");
        vsb_cat(sb, "char *VRT_int_string(const struct sess *sp, int);\n");
@@ -516,8 +512,8 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "const char * VRT_r_req_proto(const struct sess *);\n");
        vsb_cat(sb, "void VRT_l_req_proto(const struct sess *, const char *, ...);\n");
        vsb_cat(sb, "void VRT_l_req_hash(struct sess *, const char *);\n");
-       vsb_cat(sb, "struct backend * VRT_r_req_backend(struct sess *);\n");
-       vsb_cat(sb, "void VRT_l_req_backend(struct sess *, struct backend *);\n");
+       vsb_cat(sb, "struct director * VRT_r_req_backend(struct sess *);\n");
+       vsb_cat(sb, "void VRT_l_req_backend(struct sess *, struct director *);\n");
        vsb_cat(sb, "int VRT_r_req_restarts(const struct sess *);\n");
        vsb_cat(sb, "double VRT_r_req_grace(struct sess *);\n");
        vsb_cat(sb, "void VRT_l_req_grace(struct sess *, double);\n");
index 20c20d115ec534a00c035f756c1112460edc4a59..43b181404bc6417c507eda86026448ed85f6adcf 100755 (executable)
@@ -123,17 +123,18 @@ proc warns {fd} {
 set fo [open ../../include/vcl.h w]
 warns $fo
 puts $fo {struct sess;
+struct cli;
 
-typedef void vcl_init_f(void);
-typedef void vcl_fini_f(void);
+typedef void vcl_init_f(struct cli *);
+typedef void vcl_fini_f(struct cli *);
 typedef int vcl_func_f(struct sess *sp);
 }
 puts $fo "struct VCL_conf {"
 puts $fo {     unsigned        magic;
 #define VCL_CONF_MAGIC  0x7406c509      /* from /dev/random */
 
-        struct backend  **backend;
-        unsigned        nbackend;
+        struct director  **director;
+        unsigned        ndirector;
         struct vrt_ref  *ref;
         unsigned        nref;
         unsigned        busy;
index 3c7a9c253a32c74436b8a5a63f9f1fc0a5f2d85a..45c8d4eee3275ca26a2f325baba6ea28768a6ae7 100755 (executable)
@@ -211,7 +211,7 @@ set spobj {
 set tt(IP)             "struct sockaddr *"
 set tt(STRING)         "const char *"
 set tt(BOOL)           "unsigned"
-set tt(BACKEND)                "struct backend *"
+set tt(BACKEND)                "struct director *"
 set tt(TIME)           "double"
 set tt(RTIME)          "double"
 set tt(INT)            "int"