From: phk Date: Tue, 22 Jan 2008 10:48:49 +0000 (+0000) Subject: Parse a random director into an appropriate data structure, X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=867f8ea8a9b974de6d2a5b637eb34758da8952f8;p=varnish Parse a random director into an appropriate data structure, still bits missing. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2367 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index 25abbc1d..d9e4a437 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -65,6 +65,17 @@ struct vrt_round_robin_backend { struct vrt_backend_entry *bentry; }; +struct vrt_dir_random_entry { + const struct vrt_backend_host *host; + double weight; +}; + +struct vrt_dir_random { + unsigned nmember; + struct vrt_dir_random_entry *members; + const char *ident; +}; + struct vrt_random_backend { const char *name; unsigned weighted; diff --git a/varnish-cache/lib/libvcl/vcc_backend.c b/varnish-cache/lib/libvcl/vcc_backend.c index fd41543d..3a69a814 100644 --- a/varnish-cache/lib/libvcl/vcc_backend.c +++ b/varnish-cache/lib/libvcl/vcc_backend.c @@ -85,7 +85,7 @@ vcc_EmitBeIdent(struct vsb *v, const struct token *first, const struct token *la } /*-------------------------------------------------------------------- - * Parse and emit a backend specification. + * Parse and emit a backend host specification. * * The syntax is the following: * @@ -245,8 +245,12 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh) vcc_NextToken(tl); } +/*-------------------------------------------------------------------- + * Parse a plain backend + */ + void -vcc_ParseSimpleBackend(struct tokenlist *tl) +vcc_ParseBackend(struct tokenlist *tl) { struct token *t_first; struct host *h; @@ -287,171 +291,102 @@ vcc_ParseSimpleBackend(struct tokenlist *tl) tl->nbackend++; } -void -vcc_ParseBalancedBackend(struct tokenlist *tl) +/*-------------------------------------------------------------------- + * Parse directors + */ + +static void +vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_first, struct token *t_dir) { - struct var *vp; - struct token *t_be = NULL; - struct token *t_host = NULL; - struct token *t_port = NULL; - double t_weight = 0; - const char *ep; - int cnt = 0; - int weighted = 0; - double weight = 0; - unsigned backend_type = tl->t->tok; + struct token *t_field, *tb, *tw; + int nbh, nelem; - vcc_NextToken(tl); - ExpectErr(tl, ID); - t_be = tl->t; - vcc_AddDef(tl, tl->t, R_BACKEND); + (void)t_first; + (void)t_dir; - /* 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); + vcc_NextToken(tl); /* ID: policy (= random) */ - vcc_NextToken(tl); 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; - } - vcc_NextToken(tl); - ExpectErr(tl, VAR); - vp = vcc_FindVar(tl, tl->t, vcc_be_vars); - ERRCHK(tl); - assert(vp != NULL); - vcc_NextToken(tl); - ExpectErr(tl, '='); - vcc_NextToken(tl); - if (vp->fmt != SET) { - vsb_printf(tl->sb, - "Assignments not possible for '%s'\n", vp->name); - vcc_ErrWhere(tl, tl->t); - return; - } - + + Fc(tl, 0, + "\nstatic const struct vrt_dir_random_entry vdre_%.*s[] = {\n", + PF(t_dir)); + + for (nelem = 0; tl->t->tok != '}'; nelem++) { /* List of members */ + tb = NULL; + tw = NULL; + nbh = -1; + ExpectErr(tl, '{'); vcc_NextToken(tl); - - while (1) { - if (tl->t->tok == '}') - break; - - ExpectErr(tl, '{'); + + while (tl->t->tok != '}') { /* Member fields */ + ExpectErr(tl, '.'); vcc_NextToken(tl); - - // Host - ExpectErr(tl, CSTR); - t_host = tl->t; + ExpectErr(tl, ID); + t_field = tl->t; vcc_NextToken(tl); - - ep = CheckHostPort(t_host->dec, "80"); - if (ep != NULL) { - vsb_printf(tl->sb, "Backend '%.*s': %s\n", PF(t_be), ep); - vcc_ErrWhere(tl, t_host); - return; - } - - if (tl->t->tok == ',') { + ExpectErr(tl, '='); + vcc_NextToken(tl); + if (vcc_IdIs(t_field, "backend")) { + assert(tb == NULL); + tb = t_field; + vcc_ParseBackendHost(tl, &nbh); + } else if (vcc_IdIs(t_field, "weight")) { + assert(tw == NULL); + ExpectErr(tl, CNUM); + tw = tl->t; vcc_NextToken(tl); - - // Port - - ExpectErr(tl, CSTR); - t_port = tl->t; + ExpectErr(tl, ';'); vcc_NextToken(tl); - - ep = CheckHostPort(t_host->dec, t_port->dec); - if (ep != NULL) { - vsb_printf(tl->sb, - "Backend '%.*s': %s\n", PF(t_be), ep); - vcc_ErrWhere(tl, t_port); - return; - } - - if (tl->t->tok == ',') { - - vcc_NextToken(tl); - - // Weight - t_weight = vcc_DoubleVal(tl); - weighted = 1; - weight += t_weight; - } + } else { + ExpectErr(tl, '?'); } - - ExpectErr(tl, '}'); - vcc_NextToken(tl); - - Fc(tl, 0, "\nstatic struct vrt_backend_entry bentry_%.*s_%d = {\n", - PF(t_be), cnt); - Fc(tl, 0, "\t.port = %.*s,\n", PF(t_port)); - Fc(tl, 0, "\t.host = %.*s,\n", PF(t_host)); - Fc(tl, 0, "\t.weight = %f,\n", t_weight); - if (cnt > 0) { - Fc(tl, 0, "\t.next = &bentry_%.*s_%d\n", PF(t_be), cnt-1); - } /*else { - Fc(tl, 0, "\t.next = NULL\n"); - }*/ - Fc(tl, 0, "};\n"); - t_weight = 0; - cnt++; } - ExpectErr(tl, '}'); + assert(tb != NULL); + Fc(tl, 0, "\t{"); + Fc(tl, 0, ".host = &bh_%d", nbh); + if (tw != NULL) + Fc(tl, 0, ", .weight = %.*s", PF(tw)); + Fc(tl, 0, "},\n"); vcc_NextToken(tl); - ExpectErr(tl, ';'); - vcc_NextToken(tl); - - if (t_host == NULL) { - vsb_printf(tl->sb, "Backend '%.*s' has no hostname\n", - PF(t_be)); - vcc_ErrWhere(tl, tl->t); - return; - } - - if (weighted && (int)weight != 1) { - vsb_printf(tl->sb, "Total weight must be 1\n"); - vcc_ErrWhere(tl, tl->t); - return; - } - - if (backend_type == T_BACKEND_ROUND_ROBIN) { - Fc(tl, 0, "\nstatic struct vrt_round_robin_backend sbe_%.*s = {\n", - PF(t_be)); - Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be)); - Fc(tl, 0, "\t.count = %d,\n", cnt); - Fc(tl, 0, "\t.bentry = &bentry_%.*s_%d\n", PF(t_be), cnt-1); - Fc(tl, 0, "};\n"); - Fi(tl, 0, "\tVRT_init_round_robin_backend(&VGC_backend_%.*s , &sbe_%.*s);\n", - PF(t_be), PF(t_be)); - } else if (backend_type == T_BACKEND_RANDOM) { - Fc(tl, 0, "\nstatic struct vrt_random_backend sbe_%.*s = {\n", - PF(t_be)); - Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be)); - Fc(tl, 0, "\t.weighted = %d,\n", weighted); - Fc(tl, 0, "\t.count = %d,\n", cnt); - Fc(tl, 0, "\t.bentry = &bentry_%.*s_%d\n", PF(t_be), cnt-1); - Fc(tl, 0, "};\n"); - Fi(tl, 0, "\tVRT_init_random_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)); - } - ExpectErr(tl, '}'); - + Fc(tl, 0, "\t{ .host = 0 }\n"); + Fc(tl, 0, "}\n"); + Fc(tl, 0, + "\nstatic const struct vrt_dir_random vdr_%.*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_NextToken(tl); - tl->nbackend++; } +/*-------------------------------------------------------------------- + * Parse directors + */ + +void +vcc_ParseDirector(struct tokenlist *tl) +{ + struct token *t_dir, *t_first; + + vcc_NextToken(tl); /* ID: director */ + t_first = tl->t; + + ExpectErr(tl, ID); /* ID: name */ + t_dir = tl->t; + vcc_NextToken(tl); + + ExpectErr(tl, ID); /* ID: policy */ + if (vcc_IdIs(tl->t, "random")) + vcc_ParseRandomDirector(tl, t_first, t_dir); + else { + vsb_printf(tl->sb, "Unknown director policy: "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, tl->t); + return; + } +} diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index 65cd678f..2faeb8ec 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -161,8 +161,8 @@ void vcc_Cond_Ip(const struct var *vp, struct tokenlist *tl); void vcc_ParseAction(struct tokenlist *tl); /* vcc_backend.c */ -void vcc_ParseSimpleBackend(struct tokenlist *tl); -void vcc_ParseBalancedBackend(struct tokenlist *tl); +void vcc_ParseBackend(struct tokenlist *tl); +void vcc_ParseDirector(struct tokenlist *tl); /* vcc_compile.c */ extern struct method method_tab[]; diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 27a8eb9d..70244946 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -165,32 +165,6 @@ vcl_fixed_token(const char *p, const char **q) return (T_ACL); } return (0); - case 'b': - if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && - p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && - p[6] == 'd' && p[7] == '_' && p[8] == 'r' && - p[9] == 'o' && p[10] == 'u' && p[11] == 'n' && - p[12] == 'd' && p[13] == '_' && p[14] == 'r' && - p[15] == 'o' && p[16] == 'b' && p[17] == 'i' && - p[18] == 'n' && !isvar(p[19])) { - *q = p + 19; - return (T_BACKEND_ROUND_ROBIN); - } - if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && - p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && - p[6] == 'd' && p[7] == '_' && p[8] == 'r' && - p[9] == 'a' && p[10] == 'n' && p[11] == 'd' && - p[12] == 'o' && p[13] == 'm' && !isvar(p[14])) { - *q = p + 14; - return (T_BACKEND_RANDOM); - } - if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && - p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && - p[6] == 'd' && !isvar(p[7])) { - *q = p + 7; - return (T_BACKEND); - } - return (0); case 'e': if (p[0] == 'e' && p[1] == 'l' && p[2] == 's' && p[3] == 'i' && p[4] == 'f' && !isvar(p[5])) { @@ -291,9 +265,6 @@ vcl_init_tnames(void) vcl_tnames[EOI] = "EOI"; vcl_tnames[ID] = "ID"; vcl_tnames[T_ACL] = "acl"; - vcl_tnames[T_BACKEND] = "backend"; - vcl_tnames[T_BACKEND_RANDOM] = "backend_random"; - vcl_tnames[T_BACKEND_ROUND_ROBIN] = "backend_round_robin"; vcl_tnames[T_CAND] = "&&"; vcl_tnames[T_COR] = "||"; vcl_tnames[T_DEC] = "--"; @@ -445,6 +416,17 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, " struct vrt_backend_entry *bentry;\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, "};\n"); + vsb_cat(sb, "\n"); + vsb_cat(sb, "struct vrt_dir_random {\n"); + vsb_cat(sb, " unsigned nmember;\n"); + vsb_cat(sb, " struct vrt_dir_random_entry *members;\n"); + vsb_cat(sb, " const char *ident;\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"); diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index 71bb8265..7dcc53cf 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -73,12 +73,6 @@ set keywords { sub acl - - backend - - backend_round_robin - - backend_random } # Non-word tokens diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c index e601a98b..d3e70919 100644 --- a/varnish-cache/lib/libvcl/vcc_parse.c +++ b/varnish-cache/lib/libvcl/vcc_parse.c @@ -564,13 +564,6 @@ vcc_Parse(struct tokenlist *tl) case T_SUB: Function(tl); break; - case T_BACKEND: - vcc_ParseSimpleBackend(tl); - break; - case T_BACKEND_RANDOM: - case T_BACKEND_ROUND_ROBIN: - vcc_ParseBalancedBackend(tl); - break; case CSRC: Fc(tl, 0, "%.*s\n", tl->t->e - (tl->t->b + 4), tl->t->b + 2); @@ -578,6 +571,16 @@ vcc_Parse(struct tokenlist *tl) break; case EOI: break; + case ID: + if (vcc_IdIs(tl->t, "backend")) { + vcc_ParseBackend(tl); + break; + } + if (vcc_IdIs(tl->t, "director")) { + vcc_ParseDirector(tl); + break; + } + /* FALLTHROUGH */ default: vsb_printf(tl->sb, "Expected 'acl', 'sub' or 'backend', found "); diff --git a/varnish-cache/lib/libvcl/vcc_token_defs.h b/varnish-cache/lib/libvcl/vcc_token_defs.h index ccbe6a5c..a45dc0b6 100644 --- a/varnish-cache/lib/libvcl/vcc_token_defs.h +++ b/varnish-cache/lib/libvcl/vcc_token_defs.h @@ -14,26 +14,23 @@ #define T_ELSIF 132 #define T_SUB 133 #define T_ACL 134 -#define T_BACKEND 135 -#define T_BACKEND_ROUND_ROBIN 136 -#define T_BACKEND_RANDOM 137 -#define T_INC 138 -#define T_DEC 139 -#define T_CAND 140 -#define T_COR 141 -#define T_LEQ 142 -#define T_EQ 143 -#define T_NEQ 144 -#define T_GEQ 145 -#define T_SHR 146 -#define T_SHL 147 -#define T_INCR 148 -#define T_DECR 149 -#define T_MUL 150 -#define T_DIV 151 -#define ID 152 -#define VAR 153 -#define CNUM 154 -#define CSTR 155 -#define EOI 156 -#define CSRC 157 +#define T_INC 135 +#define T_DEC 136 +#define T_CAND 137 +#define T_COR 138 +#define T_LEQ 139 +#define T_EQ 140 +#define T_NEQ 141 +#define T_GEQ 142 +#define T_SHR 143 +#define T_SHL 144 +#define T_INCR 145 +#define T_DECR 146 +#define T_MUL 147 +#define T_DIV 148 +#define ID 149 +#define VAR 150 +#define CNUM 151 +#define CSTR 152 +#define EOI 153 +#define CSRC 154