Commit e8b10379 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Fix a problem in director teardown at vcl.discard time:

We didn't create/destroy directors and backends in a consistent order,
and in some case we even destroyed directors more than once.

Always destroy in opposite order of creation (which follows VCL
source order).

Turn the bottom element of the array into (only) an indication
of which backend/director is the default.

Fixes:	#722



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4967 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 4e69924f
# $Id$
test "Director cleanup fails on vcl.discard"
server s1 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
director foo random {
{ .backend = s1; .weight = 1; }
{ .backend = { .host = "${s1_addr}"; .port = "${s1_port}";} .weight =1; }
{ .backend = { .host = "${s1_addr}"; .port = "${s1_port}";} .weight =1; }
}
sub vcl_recv {
set req.backend = foo;
}
} -start
varnish v1 -vcl+backend { }
varnish v1 -cliok "vcl.list"
varnish v1 -cliok "vcl.discard vcl1"
client c1 {
txreq
rxresp
} -run
......@@ -607,8 +607,6 @@ vcc_ParseBackendHost(struct tokenlist *tl, int serial, char **nm)
sprintf(vgcname, "%.*s_%d", PF(tl->t_dir), serial);
Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(_%.*s));\n",
PF(tl->t_dir));
vcc_ParseHostDef(tl, serial, vgcname);
if (tl->err) {
vsb_printf(tl->sb,
......@@ -672,6 +670,7 @@ vcc_ParseDirector(struct tokenlist *tl)
{
struct token *t_first;
struct dirlist const *dl;
int isfirst;
t_first = tl->t;
vcc_NextToken(tl); /* ID: director | backend */
......@@ -682,14 +681,12 @@ vcc_ParseDirector(struct tokenlist *tl)
vcc_NextToken(tl);
isfirst = tl->ndirector;
if (vcc_IdIs(t_first, "backend")) {
tl->t_policy = t_first;
vcc_ParseSimpleDirector(tl);
} else {
Fh(tl, 1, "\n#define VGC_backend__%.*s %d\n",
PF(tl->t_dir), tl->ndirector);
vcc_AddDef(tl, tl->t_dir, R_BACKEND);
tl->ndirector++;
ExpectErr(tl, ID); /* ID: policy */
tl->t_policy = tl->t;
vcc_NextToken(tl);
......@@ -708,9 +705,14 @@ vcc_ParseDirector(struct tokenlist *tl)
dl->func(tl);
if (!tl->err)
SkipToken(tl, '}');
Fh(tl, 1, "\n#define VGC_backend__%.*s %d\n",
PF(tl->t_dir), tl->ndirector);
tl->ndirector++;
Fi(tl, 0,
"\tVRT_init_dir(cli, VCL_conf.director, \"%.*s\",\n",
PF(tl->t_policy));
Ff(tl, 0, "\tVRT_fini_dir(cli, VGCDIR(_%.*s));\n",
PF(tl->t_dir));
Fi(tl, 0, "\t VGC_backend__%.*s, &vgc_dir_priv_%.*s);\n",
PF(tl->t_dir), PF(tl->t_dir));
......@@ -722,6 +724,18 @@ vcc_ParseDirector(struct tokenlist *tl)
vcc_ErrWhere(tl, t_first);
return;
}
if (isfirst == 1) {
/*
* If this is the first backend|director explicitly
* defined, use it as default backend.
*/
Fi(tl, 0,
"\tVCL_conf.director[0] = VCL_conf.director[%d];\n",
tl->ndirector - 1);
vcc_AddRef(tl, tl->t_dir, R_BACKEND);
}
tl->t_policy = NULL;
tl->t_dir = NULL;
}
......@@ -469,6 +469,7 @@ vcc_NewTokenList(void)
VTAILQ_INIT(&tl->sources);
tl->nsources = 0;
tl->ndirector = 1;
/* General C code */
tl->fc = vsb_newauto();
......@@ -580,7 +581,7 @@ vcc_CompileSource(struct vsb *sb, struct source *sp)
return (vcc_DestroyTokenList(tl, NULL));
/* Check if we have any backends at all */
if (tl->ndirector == 0) {
if (tl->ndirector == 1) {
vsb_printf(tl->sb,
"No backends or directors found in VCL program, "
"at least one is necessary.\n");
......
......@@ -143,10 +143,6 @@ vcc_AddDef(struct tokenlist *tl, struct token *t, enum ref_type type)
}
r->defcnt++;
r->name = t;
/* The first backend is the default and thus has an implicit ref */
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