From: Tollef Fog Heen Date: Tue, 25 Nov 2008 23:55:34 +0000 (+0100) Subject: Make vcl.reload keep old VCL X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f8ac7c240505638158de2a17624552e87c4fe19;p=varnish Make vcl.reload keep old VCL vcl.reload foo now works as follows: - drop foo.old (unless it is active, in which case we whine and stop) - rename foo to foo.old - compile foo, if this fails, rename foo.old to foo again - if foo was active, switch to foo (from foo.old) --- diff --git a/varnish-cache/bin/varnishd/cache_vcl.c b/varnish-cache/bin/varnishd/cache_vcl.c index 64c34680..6baefa86 100644 --- a/varnish-cache/bin/varnishd/cache_vcl.c +++ b/varnish-cache/bin/varnishd/cache_vcl.c @@ -242,22 +242,44 @@ ccf_config_list(struct cli *cli, const char * const *av, void *priv) static void ccf_config_reload(struct cli *cli, const char * const *av, void *priv) { - char *t; + char *oldname; struct vcls *vcl, *vcl_discard; (void)av; (void)priv; ASSERT_CLI(); - asprintf(&t, "vcltmp-%d", random()); - if (VCL_Load(av[3], t, cli)) - cli_result(cli, CLIS_PARAM); + asprintf(&oldname, "%s.old", av[2]); + + vcl_discard = vcl_find(oldname); + if (vcl_discard) { + if (vcl_active == vcl_discard) { + cli_out(cli, "VCL named %s exists and is the active VCL. " + "Can not reload %s", oldname, av[2]); + free(oldname); + return (1); + } + VSL_stats->n_vcl_discard++; + VSL_stats->n_vcl_avail--; + vcl_discard->conf->discard = 1; + if (vcl_discard->conf->busy == 0) + VCL_Nuke(vcl_discard); + } - vcl = vcl_find(t); vcl_discard = vcl_find(av[2]); - REPLACE(vcl->name, av[2]); + if (vcl_discard) + REPLACE(vcl_discard->name, oldname); + free(oldname); + + if (VCL_Load(av[3], av[2], cli)) { + cli_result(cli, CLIS_PARAM); + REPLACE(vcl_discard->name, av[2]); + return (1); + } + vcl = vcl_find(av[2]); Lck_Lock(&vcl_mtx); - vcl_active = vcl; + if (vcl_active == vcl_discard) + vcl_active = vcl; Lck_Unlock(&vcl_mtx); VSL_stats->n_vcl_discard++; @@ -266,7 +288,6 @@ ccf_config_reload(struct cli *cli, const char * const *av, void *priv) if (vcl_discard->conf->busy == 0) VCL_Nuke(vcl_discard); - return; } diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index b713dea1..7558c313 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -491,25 +491,38 @@ mcf_config_inline(struct cli *cli, const char * const *av, void *priv) void mcf_config_reload(struct cli *cli, const char *const *av, void *priv) { - char *vf; + char *vf, *vcl, *oldname; struct vsb *sb; unsigned status; char *p = NULL; struct vclprog *vp; int active; + asprintf(&oldname, "%s.old", av[2]); + vp = mgt_vcc_byname(oldname); + if (vp != NULL) { + if (vp->active) { + cli_out(cli, "VCL named %s, is active, can not reload %s", + oldname, av[2]); + cli_result(cli, CLIS_PARAM); + free(oldname); + return; + } + mgt_vcc_del(vp); + } vp = mgt_vcc_byname(av[2]); - if (vp == NULL) { - cli_out(cli, "No VCL program named %s, use vcl.load", av[2]); + + vcl = vreadfile(av[3]); + if (vcl == NULL) { + cli_out(cli, "Cannot open '%s'", av[3]); cli_result(cli, CLIS_PARAM); + free(oldname); return; } - sb = vsb_newauto(); - XXXAN(sb); - vf = mgt_VccCompileFile(sb, av[3], 0, -1); - vsb_finish(sb); - AZ(vsb_overflowed(sb)); + vf = mgt_VccCompile(&sb, vcl, 0); + free(vcl); + if (vsb_len(sb) > 0) cli_out(cli, "%s", vsb_data(sb)); vsb_delete(sb); @@ -518,6 +531,7 @@ mcf_config_reload(struct cli *cli, const char *const *av, void *priv) cli_result(cli, CLIS_PARAM); return; } + cli_out(cli, "VCL compiled."); if (child_pid >= 0 && mgt_cli_askchild(&status, &p, "vcl.reload %s %s\n", av[2], vf)) { @@ -525,7 +539,7 @@ mcf_config_reload(struct cli *cli, const char *const *av, void *priv) cli_out(cli, "%s", p); } else { active = vp->active; - mgt_vcc_del(vp); + REPLACE(vp->name, oldname); vp = mgt_vcc_add(av[2], vf); vp->active = active; } diff --git a/varnish-cache/bin/varnishtest/tests/c00020.vtc b/varnish-cache/bin/varnishtest/tests/c00020.vtc index e48b6e3a..a3466caa 100644 --- a/varnish-cache/bin/varnishtest/tests/c00020.vtc +++ b/varnish-cache/bin/varnishtest/tests/c00020.vtc @@ -59,3 +59,4 @@ varnish v1 -expect client_req == 6 varnish v1 -expect s_sess == 3 varnish v1 -expect s_req == 6 varnish v1 -expect s_fetch == 3 + diff --git a/varnish-cache/bin/varnishtest/tests/c00023.vtc b/varnish-cache/bin/varnishtest/tests/c00023.vtc index 058e4928..0ff30030 100644 --- a/varnish-cache/bin/varnishtest/tests/c00023.vtc +++ b/varnish-cache/bin/varnishtest/tests/c00023.vtc @@ -9,6 +9,6 @@ varnish v1 -vcl { varnish v1 -cli "vcl.reload vcl1 /tmp/_varnishtest_c00020.vcl" varnish v1 -start -varnish v1 -expect n_vcl_avail == 1 +varnish v1 -expect n_vcl_avail == 2 varnish v1 -cli "vcl.reload vcl1 /tmp/_varnishtest_c00020.vcl" -varnish v1 -expect n_vcl_avail == 1 +varnish v1 -expect n_vcl_avail == 2 diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index bb6df1d8..212a5cc0 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -159,10 +159,9 @@ vcl_output_lang_h(struct vsb *sb) /* ../../include/vcl.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3534 2009-01-19 13"); - vsb_cat(sb, ":46:31Z phk $\n *\n * NB: This file is machine genera"); - vsb_cat(sb, "ted, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_t"); - vsb_cat(sb, "oken.tcl instead\n */\n\nstruct sess;\n"); + vsb_cat(sb, "/*\n * $Id$\n *\n * NB: This file is machine generate"); + vsb_cat(sb, "d, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_tok"); + vsb_cat(sb, "en.tcl instead\n */\n\nstruct sess;\n"); vsb_cat(sb, "struct cli;\n\ntypedef 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"); @@ -235,15 +234,15 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI"); vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT"); vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3541 2009-01-23 21:"); - vsb_cat(sb, "17:02Z phk $\n *\n * Runtime support for compiled VCL "); - vsb_cat(sb, "programs.\n *\n * XXX: When this file is changed, lib/"); - vsb_cat(sb, "libvcl/vcc_gen_fixed_token.tcl\n"); - vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n"); - vsb_cat(sb, "\nstruct sess;\nstruct vsb;\nstruct cli;\n"); - vsb_cat(sb, "struct director;\nstruct VCL_conf;\n"); - vsb_cat(sb, "struct sockaddr;\n\n/*\n * A backend probe specificati"); - vsb_cat(sb, "on\n */\n\nextern void *vrt_magic_string_end;\n"); + vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id$\n *\n"); + vsb_cat(sb, " * Runtime support for compiled VCL programs.\n"); + vsb_cat(sb, " *\n * XXX: When this file is changed, lib/libvcl/vcc_"); + vsb_cat(sb, "gen_fixed_token.tcl\n * XXX: *MUST* be rerun.\n"); + vsb_cat(sb, " */\n\nstruct sess;\nstruct vsb;\n"); + vsb_cat(sb, "struct cli;\nstruct director;\n"); + vsb_cat(sb, "struct VCL_conf;\nstruct sockaddr;\n"); + vsb_cat(sb, "\n/*\n * A backend probe specification\n"); + vsb_cat(sb, " */\n\nextern void *vrt_magic_string_end;\n"); vsb_cat(sb, "\nstruct vrt_backend_probe {\n\tconst char\t*url;\n"); vsb_cat(sb, "\tconst char\t*request;\n\tdouble\t\ttimeout;\n"); vsb_cat(sb, "\tdouble\t\tinterval;\n\tunsigned\twindow;\n"); @@ -324,9 +323,8 @@ vcl_output_lang_h(struct vsb *sb) /* ../../include/vrt_obj.h */ - vsb_cat(sb, "/*\n * $Id: vrt_obj.h 3406 2008-11-19 14:13:57Z petter"); - vsb_cat(sb, " $\n *\n * NB: This file is machine generated, DO NOT"); - vsb_cat(sb, " EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); + vsb_cat(sb, "/*\n * $Id$\n *\n * NB: This file is machine generate"); + vsb_cat(sb, "d, DO NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct "); vsb_cat(sb, "sess *);\nstruct sockaddr * VRT_r_server_ip(struct ses"); vsb_cat(sb, "s *);\nint VRT_r_server_port(struct sess *);\n");