Commit 994c5972 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

More polishing of backend compilation.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2889 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent be36e530
......@@ -2,6 +2,20 @@
test "VCL: test syntax/semantic checks on backend decls."
# Missing backend
varnish v1 -badvcl {
}
# Reference to non-existent backend
varnish v1 -badvcl {
backend b1 {
.host = "localhost";
}
sub vcl_recv {
set req.backend = b2;
}
}
# Missing .host
varnish v1 -badvcl {
backend b1 {
......@@ -44,3 +58,23 @@ varnish v1 -badvcl {
{ .weight = 1; .backend = 3745; } // Brownie points for getting the joke
}
}
# Check backend reference by name
varnish v1 -badvcl {
backend b1 { .host = "127.0.0.2"; }
backend b2 b1;
}
# Check backend reference by non-C-compat name
varnish v1 -badvcl {
backend b-1 { .host = "127.0.0.2"; }
}
# Assign backend by non-C-compat name
# Check backend reference by non-C-compat name
varnish v1 -badvcl {
backend b1 { .host = "127.0.0.2"; }
sub vcl_recv {
set req.backend = b-1;
}
}
......@@ -221,6 +221,8 @@ parse_set(struct tokenlist *tl)
return;
}
vcc_NextToken(tl);
vcc_ExpectCid(tl);
ERRCHK(tl);
vcc_AddRef(tl, tl->t, R_BACKEND);
Fb(tl, 0, "VGC_backend_%.*s", PF(tl->t));
vcc_NextToken(tl);
......
......@@ -27,6 +27,27 @@
* SUCH DAMAGE.
*
* $Id$
*
* A necessary explanation of a convoluted policy:
*
* In VCL we have backends and directors.
*
* In VRT we have directors which reference (a number of) backend hosts.
*
* A VCL backend therefore has an implicit director of type "simple" created
* by the compiler, but not visible in VCL.
*
* A VCL backend is a "named host", these can be referenced by name form
* VCL directors, but not from VCL backends.
*
* The reason for this quasimadness is that we want to collect statistics
* for each actual kickable hardware backend machine, but we want to be
* able to refer to them multiple times in different directors.
*
* At the same time, we do not want to force users to declare each backend
* host with a name, if all they want to do is put it into a director, so
* backend hosts can be declared inline in the director, in which case
* its identity is the director and its numerical index therein.
*/
#include "config.h"
......@@ -45,6 +66,13 @@
#include "vcc_compile.h"
#include "libvarnish.h"
struct host {
VTAILQ_ENTRY(host) list;
int hnum;
struct token *name;
};
static const char *
CheckHostPort(const char *host, const char *port)
{
......@@ -365,25 +393,24 @@ void
vcc_ParseBackend(struct tokenlist *tl)
{
struct host *h;
int nbh;
h = TlAlloc(tl, sizeof *h);
vcc_NextToken(tl);
ExpectErr(tl, ID); /* name */
vcc_ExpectCid(tl); /* ID: name */
ERRCHK(tl);
h->name = tl->t;
vcc_NextToken(tl);
vcc_ParseHostDef(tl, &nbh, h->name, "backend", 0);
vcc_ParseHostDef(tl, &h->hnum, h->name, "backend", 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.director[%d])\n",
PF(h->name), tl->nbackend);
PF(h->name), tl->ndirector);
vcc_AddDef(tl, h->name, R_BACKEND);
......@@ -395,10 +422,10 @@ vcc_ParseBackend(struct tokenlist *tl)
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);
Fc(tl, 0, "\t.host = &bh_%d,\n", h->hnum);
Fc(tl, 0, "};\n");
tl->nbackend++;
tl->ndirector++;
}
/*--------------------------------------------------------------------
......@@ -413,7 +440,8 @@ vcc_ParseDirector(struct tokenlist *tl)
t_first = tl->t;
vcc_NextToken(tl); /* ID: director */
ExpectErr(tl, ID); /* ID: name */
vcc_ExpectCid(tl); /* ID: name */
ERRCHK(tl);
t_dir = tl->t;
vcc_NextToken(tl);
......@@ -434,5 +462,5 @@ vcc_ParseDirector(struct tokenlist *tl)
vcc_ErrWhere(tl, t_first);
return;
}
tl->nbackend++;
tl->ndirector++;
}
......@@ -341,13 +341,14 @@ EmitStruct(const struct tokenlist *tl)
}
Fc(tl, 0, "};\n");
Fc(tl, 0, "\nstatic struct director\t*directors[%d];\n", tl->nbackend);
Fc(tl, 0, "\nstatic struct director\t*directors[%d];\n",
tl->ndirector);
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.ndirector = %d,\n", tl->nbackend);
Fc(tl, 0, "\t.ndirector = %d,\n", tl->ndirector);
Fc(tl, 0, "\t.director = directors,\n");
Fc(tl, 0, "\t.ref = VGC_ref,\n");
Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
......@@ -596,9 +597,10 @@ vcc_CompileSource(struct vsb *sb, struct source *sp)
return (vcc_DestroyTokenList(tl, NULL));
/* Check if we have any backends at all */
if (tl->nbackend == 0) {
if (tl->ndirector == 0) {
vsb_printf(tl->sb,
"No backends in VCL program, at least one is necessary.\n");
"No backends or directors found in VCL program, "
"at least one is necessary.\n");
tl->err = 1;
return (vcc_DestroyTokenList(tl, NULL));
}
......
......@@ -59,12 +59,6 @@ struct token {
char *dec;
};
struct host {
VTAILQ_ENTRY(host) list;
unsigned hnum;
struct token *name;
};
VTAILQ_HEAD(tokenhead, token);
struct tokenlist {
......@@ -86,7 +80,7 @@ struct tokenlist {
struct vsb *sb;
int err;
int nbackend_host;
int nbackend;
int ndirector;
VTAILQ_HEAD(, proc) procs;
struct proc *curproc;
struct proc *mprocs[N_METHODS];
......@@ -205,6 +199,8 @@ void vcc_ErrWhere(struct tokenlist *tl, const struct token *t);
void vcc__Expect(struct tokenlist *tl, unsigned tok, int line);
int vcc_Teq(const struct token *t1, const struct token *t2);
int vcc_IdIs(const struct token *t, const char *p);
int vcc_isCid(struct token *t);
void vcc_ExpectCid(struct tokenlist *tl);
void vcc_Lexer(struct tokenlist *tl, struct source *sp);
void vcc_NextToken(struct tokenlist *tl);
void vcc__ErrInternal(struct tokenlist *tl, const char *func, unsigned line);
......
......@@ -58,7 +58,7 @@ vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir)
unsigned u;
Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n",
PF(t_dir), tl->nbackend);
PF(t_dir), tl->ndirector);
vcc_AddDef(tl, t_dir, R_BACKEND);
fs = vcc_FldSpec(tl, "!backend", "!weight", NULL);
......
......@@ -187,6 +187,38 @@ vcc_IdIs(const struct token *t, const char *p)
return (1);
}
/*--------------------------------------------------------------------
* Check that we have a C-identifier
*/
int
vcc_isCid(struct token *t)
{
const char *q;
assert(t->tok == ID);
for (q = t->b; q < t->e; q++) {
if (!isalnum(*q) && *q != '_')
return (0);
}
return (1);
}
void
vcc_ExpectCid(struct tokenlist *tl)
{
ExpectErr(tl, ID);
ERRCHK(tl);
if (vcc_isCid(tl->t))
return;
vsb_printf(tl->sb, "Identifier ");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb,
" contains illegal characters, use [0-9a-zA-Z_] only.\n");
vcc_ErrWhere(tl, tl->t);
}
/*--------------------------------------------------------------------
* Decode %xx in a string
*/
......
......@@ -143,7 +143,7 @@ vcc_AddDef(struct tokenlist *tl, struct token *t, enum ref_type type)
r->name = t;
/* The first backend is the default and thus has an implicit ref */
if (type == R_BACKEND && tl->nbackend == 0)
if (type == R_BACKEND && tl->ndirector == 0)
r->refcnt++;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment