From: phk Date: Mon, 21 Jan 2008 13:09:17 +0000 (+0000) Subject: Start the long awaited overhaul of the backend code and syntax. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5cd30fd59c16688c2dcd3fc31d0460ae3178945;p=varnish Start the long awaited overhaul of the backend code and syntax. Off the bat, this affects only the simple backend case, and the main thrust is a syntax change from a dynamic procedural assignment style: backend b1 { set backend.host = "fs.freebsd.dk"; set backend..port = "80"; } to a constant structural definition style: backend b1 { .host = "fs.freebsd.dk"; .port = "80"; } A helpfull compile error will advice on this change. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2356 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_backend_simple.c b/varnish-cache/bin/varnishd/cache_backend_simple.c index d2519342..d21ed570 100644 --- a/varnish-cache/bin/varnishd/cache_backend_simple.c +++ b/varnish-cache/bin/varnishd/cache_backend_simple.c @@ -395,11 +395,11 @@ VRT_init_simple_backend(struct backend **bp, const struct vrt_simple_backend *t) AN(t->name); REPLACE(b->vcl_name, t->name); - AN(t->port); - REPLACE(bes->portname, t->port); + AN(t->host->portname); + REPLACE(bes->portname, t->host->portname); - AN(t->host); - REPLACE(bes->hostname, t->host); + AN(t->host->hostname); + REPLACE(bes->hostname, t->host->hostname); /* * The VCL compiler already did a lookup, but we'll do another one @@ -410,7 +410,7 @@ VRT_init_simple_backend(struct backend **bp, const struct vrt_simple_backend *t) UNLOCK(&b->mtx); if (p != NULL) printf("Warning: could not lookup backend %s (%s:%s): %s", - t->name, t->host, t->port, p); + b->vcl_name, bes->hostname, bes->portname, p); *bp = b; } diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index 544fbca3..6cbfcccd 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -418,8 +418,8 @@ mgt_vcc_default(const char *b_arg, const char *f_arg, int f_fd, int C_flag) buf = NULL; asprintf(&buf, "backend default {\n" - " set backend.host = \"%s\";\n" - " set backend.port = \"%s\";\n" + " .host = \"%s\";\n" + " .port = \"%s\";\n" "}\n", addr, port ? port : "http"); free(addr); free(port); diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index 857732e0..94ba4571 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -40,11 +40,15 @@ struct backend; struct VCL_conf; struct sockaddr; +struct vrt_backend_host { + const char *portname; + const char *hostname; +}; + struct vrt_simple_backend { - const char *ident; - const char *name; - const char *port; - const char *host; + const char *ident; + const char *name; + const struct vrt_backend_host *host; }; struct vrt_backend_entry { diff --git a/varnish-cache/lib/libvcl/vcc_backend.c b/varnish-cache/lib/libvcl/vcc_backend.c index af81603c..fdac3593 100644 --- a/varnish-cache/lib/libvcl/vcc_backend.c +++ b/varnish-cache/lib/libvcl/vcc_backend.c @@ -84,107 +84,162 @@ vcc_EmitBeIdent(struct tokenlist *tl, struct token *first, struct token *last) Fc(tl, 0, ",\n"); } -void -vcc_ParseSimpleBackend(struct tokenlist *tl) +/*-------------------------------------------------------------------- + * Parse and emit a backend specification. + * + * The syntax is the following: + * + * backend_spec: + * name_of_backend # by reference + * '{' be_elements '}' # by specification + * + * be_elements: + * be_element + * be_element be_elements + * + * be_element: + * '.' name '=' value ';' + * + * The struct vrt_backend_host is emitted to Fh(). + */ + +static void +vcc_ParseBackendHost(struct tokenlist *tl, int *nbh) { - struct var *vp; - struct token *t_be = NULL; + struct token *t_field; + struct token *t_first; struct token *t_host = NULL; struct token *t_port = NULL; - struct token *t_first; const char *ep; t_first = tl->t; - vcc_NextToken(tl); - ExpectErr(tl, ID); - t_be = tl->t; - vcc_AddDef(tl, tl->t, R_BACKEND); - - /* In the compiled vcl we use these macros to refer to backends */ - Fh(tl, 1, "#define VGC_backend_%.*s (VCL_conf.backend[%d])\n", - PF(tl->t), tl->nbackend); + *nbh = tl->nbackend_host++; - vcc_NextToken(tl); + if (tl->t->tok == ID) { + ErrInternal(tl); /* Reference by name */ + return; + } ExpectErr(tl, '{'); vcc_NextToken(tl); - - while (1) { - if (tl->t->tok == '}') - break; - ExpectErr(tl, ID); - if (!vcc_IdIs(tl->t, "set")) { - vsb_printf(tl->sb, - "Expected 'set', found "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, " at\n"); - vcc_ErrWhere(tl, tl->t); - return; - } + + Fh(tl, 0, "\nstatic const struct vrt_backend_host bh_%d = {\n", + *nbh); + + /* Check for old syntax */ + if (tl->t->tok == ID && vcc_IdIs(tl->t, "set")) { + vsb_printf(tl->sb, + "NB: Backend Syntax has changed:\n" + "Remove \"set\" and \"backend\" in front" + " of backend fields.\n" ); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, tl->t); + return; + } + + while (tl->t->tok == '.') { vcc_NextToken(tl); - ExpectErr(tl, VAR); - vp = vcc_FindVar(tl, tl->t, vcc_be_vars); - ERRCHK(tl); - assert(vp != NULL); + + ExpectErr(tl, ID); /* name */ + t_field = tl->t; vcc_NextToken(tl); + ExpectErr(tl, '='); vcc_NextToken(tl); - switch (vp->fmt) { - case HOSTNAME: + + if (vcc_IdIs(t_field, "host")) { ExpectErr(tl, CSTR); + assert(tl->t->dec != NULL); t_host = tl->t; vcc_NextToken(tl); - break; - case PORTNAME: + } else if (vcc_IdIs(t_field, "port")) { ExpectErr(tl, CSTR); + assert(tl->t->dec != NULL); t_port = tl->t; vcc_NextToken(tl); - break; - default: + } else { vsb_printf(tl->sb, - "Assignments not possible for '%s'\n", vp->name); - vcc_ErrWhere(tl, tl->t); + "Unknown field in backend host specification: "); + vcc_ErrToken(tl, t_field); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, t_field); return; } + ExpectErr(tl, ';'); vcc_NextToken(tl); } - ExpectErr(tl, '}'); if (t_host == NULL) { - vsb_printf(tl->sb, "Backend '%.*s' has no hostname\n", - PF(t_be)); + vsb_printf(tl->sb, "Backend has no hostname\n"); vcc_ErrWhere(tl, tl->t); return; } + + /* Check that the hostname makes sense */ ep = CheckHostPort(t_host->dec, "80"); if (ep != NULL) { - vsb_printf(tl->sb, "Backend '%.*s': %s\n", PF(t_be), ep); + vsb_printf(tl->sb, "Backend host '%.*s': %s\n", PF(t_host), ep); vcc_ErrWhere(tl, t_host); return; } + Fh(tl, 0, "\t.hostname = "); + EncToken(tl->fh, t_host); + Fh(tl, 0, ",\n"); + + /* Check that the hostname makes sense */ if (t_port != NULL) { ep = CheckHostPort(t_host->dec, t_port->dec); if (ep != NULL) { vsb_printf(tl->sb, - "Backend '%.*s': %s\n", PF(t_be), ep); + "Backend port '%.*s': %s\n", PF(t_port), ep); vcc_ErrWhere(tl, t_port); return; } + Fh(tl, 0, "\t.portname = "); + EncToken(tl->fh, t_port); + Fh(tl, 0, ",\n"); } + ExpectErr(tl, '}'); + Fh(tl, 0, "};\n"); + vcc_NextToken(tl); +} + +void +vcc_ParseSimpleBackend(struct tokenlist *tl) +{ + struct token *t_be = NULL; + struct token *t_first; + int nbh; + + t_first = tl->t; /* T_BACKEND */ + vcc_NextToken(tl); + + ExpectErr(tl, ID); /* name */ + t_be = tl->t; + vcc_NextToken(tl); + + vcc_ParseBackendHost(tl, &nbh); + ERRCHK(tl); + + /* 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", + PF(t_be), tl->nbackend); + + vcc_AddDef(tl, t_be, R_BACKEND); + + Fi(tl, 0, "\tVRT_init_simple_backend(&VGC_backend_%.*s , &sbe_%.*s);\n", + PF(t_be), PF(t_be)); + Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%.*s);\n", PF(t_be)); + Fc(tl, 0, "\nstatic const struct vrt_simple_backend sbe_%.*s = {\n", PF(t_be)); Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be)); - if (t_port != NULL) - Fc(tl, 0, "\t.port = %.*s,\n", PF(t_port)); - else - Fc(tl, 0, "\t.port = \"http\",\n"); - Fc(tl, 0, "\t.host = %.*s,\n", PF(t_host)); + Fc(tl, 0, "\t.host = &bh_%d,\n", nbh); vcc_EmitBeIdent(tl, t_first, tl->t); Fc(tl, 0, "};\n"); - Fi(tl, 0, "\tVRT_init_simple_backend(&VGC_backend_%.*s , &sbe_%.*s);\n", - PF(t_be), PF(t_be)); - Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%.*s);\n", PF(t_be)); + tl->nbackend++; } diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index c8977b5b..42c019b0 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -78,6 +78,7 @@ struct tokenlist { VTAILQ_HEAD(, ref) refs; struct vsb *sb; int err; + int nbackend_host; int nbackend; VTAILQ_HEAD(, proc) procs; struct proc *curproc; diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 638f89f3..0aaba94f 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -420,11 +420,15 @@ vcl_output_lang_h(struct vsb *sb) 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, " const char *portname;\n"); + vsb_cat(sb, " const char *hostname;\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 char *port;\n"); - vsb_cat(sb, " const char *host;\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, "struct vrt_backend_entry {\n");