From: phk Date: Fri, 4 Aug 2006 10:54:30 +0000 (+0000) Subject: Redo VCL program handling. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27be845254f922b4319343840f4c2f69108b0f6e;p=varnish Redo VCL program handling. Keep track of all loaded VCL programs in the manager and tell the child to load them via VCL. Don't start he acceptor thread until a "start" command cones down the CLI. XXX: Right now we leak stuff when a VCL program is dicarded git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@638 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 02bfeaab..48730dde 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -406,7 +406,7 @@ int VCL_Load(const char *fn, const char *name, struct cli *cli); #ifdef CLI_PRIV_H cli_func_t cli_func_config_list; cli_func_t cli_func_config_load; -cli_func_t cli_func_config_unload; +cli_func_t cli_func_config_discard; cli_func_t cli_func_config_use; #endif diff --git a/varnish-cache/bin/varnishd/cache_cli.c b/varnish-cache/bin/varnishd/cache_cli.c index 70be1dfd..53502204 100644 --- a/varnish-cache/bin/varnishd/cache_cli.c +++ b/varnish-cache/bin/varnishd/cache_cli.c @@ -44,7 +44,7 @@ struct cli_proto CLI_cmds[] = { { CLI_URL_PURGE, cli_func_url_purge }, { CLI_CONFIG_LOAD, cli_func_config_load }, { CLI_CONFIG_LIST, cli_func_config_list }, - { CLI_CONFIG_UNLOAD, cli_func_config_unload }, + { CLI_CONFIG_DISCARD, cli_func_config_discard }, { CLI_CONFIG_USE, cli_func_config_use }, { NULL } }; diff --git a/varnish-cache/bin/varnishd/cache_vcl.c b/varnish-cache/bin/varnishd/cache_vcl.c index ab725cf5..02b23a0e 100644 --- a/varnish-cache/bin/varnishd/cache_vcl.c +++ b/varnish-cache/bin/varnishd/cache_vcl.c @@ -25,6 +25,7 @@ struct vcls { const char *name; void *dlh; struct VCL_conf *conf; + int discard; }; /* @@ -58,10 +59,24 @@ VCL_Get(void) void VCL_Rel(struct VCL_conf *vc) { + struct vcls *vcl; AZ(pthread_mutex_lock(&vcl_mtx)); + assert(vc->busy > 0); vc->busy--; + vcl = vc->priv; /* XXX miniobj */ + if (vc->busy == 0 && vcl_active != vcl) { + /* XXX: purge backends */ + } + if (vc->busy == 0 && vcl->discard) { + TAILQ_REMOVE(&vcl_head, vcl, list); + } else { + vcl = NULL; + } AZ(pthread_mutex_unlock(&vcl_mtx)); + if (vcl != NULL) { + /* XXX: dispose of vcl */ + } } /*--------------------------------------------------------------------*/ @@ -114,6 +129,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli) free(vcl); return (1); } + if (vcl->conf->magic != VCL_CONF_MAGIC) { if (cli == NULL) fprintf(stderr, "Wrong VCL_CONF_MAGIC\n"); @@ -123,6 +139,7 @@ VCL_Load(const char *fn, const char *name, struct cli *cli) free(vcl); return (1); } + vcl->conf->priv = vcl; vcl->name = strdup(name); assert(vcl->name != NULL); TAILQ_INSERT_TAIL(&vcl_head, vcl, list); @@ -167,12 +184,34 @@ cli_func_config_load(struct cli *cli, char **av, void *priv) } void -cli_func_config_unload(struct cli *cli, char **av, void *priv) +cli_func_config_discard(struct cli *cli, char **av, void *priv) { + struct vcls *vcl; (void)av; (void)priv; - cli_result(cli, CLIS_UNIMPL); + vcl = vcl_find(av[2]); + if (vcl->discard) { + cli_result(cli, CLIS_PARAM); + cli_out(cli, "VCL %s already discarded", av[2]); + return; + } + AZ(pthread_mutex_lock(&vcl_mtx)); + if (vcl == vcl_active) { + AZ(pthread_mutex_unlock(&vcl_mtx)); + cli_result(cli, CLIS_PARAM); + cli_out(cli, "VCL %s is the active VCL", av[2]); + return; + } + vcl->discard = 1; + if (vcl->conf->busy == 0) + TAILQ_REMOVE(&vcl_head, vcl, list); + else + vcl = NULL; + AZ(pthread_mutex_unlock(&vcl_mtx)); + if (vcl != NULL) { + /* XXX dispose of vcl */ + } } void @@ -183,14 +222,19 @@ cli_func_config_use(struct cli *cli, char **av, void *priv) (void)av; (void)priv; vcl = vcl_find(av[2]); - if (vcl != NULL) { - AZ(pthread_mutex_lock(&vcl_mtx)); - vcl_active = vcl; - AZ(pthread_mutex_unlock(&vcl_mtx)); - } else { - cli_out(cli, "No config named '%s' loaded", av[2]); + if (vcl == NULL) { + cli_out(cli, "No VCL named '%s'", av[2]); + cli_result(cli, CLIS_PARAM); + return; + } + if (vcl->discard) { + cli_out(cli, "VCL '%s' has been discarded", av[2]); cli_result(cli, CLIS_PARAM); + return; } + AZ(pthread_mutex_lock(&vcl_mtx)); + vcl_active = vcl; + AZ(pthread_mutex_unlock(&vcl_mtx)); } /*--------------------------------------------------------------------*/ diff --git a/varnish-cache/bin/varnishd/mgt_cli.c b/varnish-cache/bin/varnishd/mgt_cli.c index 618ceae3..36c63f47 100644 --- a/varnish-cache/bin/varnishd/mgt_cli.c +++ b/varnish-cache/bin/varnishd/mgt_cli.c @@ -111,6 +111,8 @@ static struct cli_proto mgt_cli_proto[] = { { CLI_STATS, mcf_stats, NULL }, { CLI_CONFIG_LOAD, mcf_config_load, NULL }, { CLI_CONFIG_INLINE, mcf_config_inline, NULL }, + { CLI_CONFIG_USE, mcf_config_use, NULL }, + { CLI_CONFIG_DISCARD, mcf_config_discard, NULL }, #if 0 { CLI_SERVER_STOP, m_cli_func_server_stop, NULL }, { CLI_SERVER_RESTART }, diff --git a/varnish-cache/bin/varnishd/mgt_cli.h b/varnish-cache/bin/varnishd/mgt_cli.h index a0454b9c..5d05d78e 100644 --- a/varnish-cache/bin/varnishd/mgt_cli.h +++ b/varnish-cache/bin/varnishd/mgt_cli.h @@ -8,3 +8,5 @@ cli_func_t mcf_server_startstop; /* mgt_vcc.c */ cli_func_t mcf_config_load; cli_func_t mcf_config_inline; +cli_func_t mcf_config_use; +cli_func_t mcf_config_discard; diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index 5e50e8ed..778b4c30 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -206,9 +206,6 @@ mgt_vcc_atexit(void) if (getpid() != mgt_pid) return; AZ(pthread_mutex_lock(&vcc_mtx)); - TAILQ_FOREACH(vp, &vclhead, list) { - printf("Has %s %s\n", vp->name, vp->fname); - } while (1) { vp = TAILQ_FIRST(&vclhead); if (vp == NULL) @@ -287,3 +284,71 @@ mcf_config_load(struct cli *cli, char **av, void *priv) } mgt_vcc_add(av[2], vf); } + +static struct vcls * +mcf_find_vcl(struct cli *cli, const char *name) +{ + struct vcls *vp; + + TAILQ_FOREACH(vp, &vclhead, list) + if (!strcmp(vp->name, name)) + break; + if (vp == NULL) { + cli_result(cli, CLIS_PARAM); + cli_out(cli, "No configuration named %s known.", name); + } + return (vp); +} + +void +mcf_config_use(struct cli *cli, char **av, void *priv) +{ + int status; + char *p; + struct vcls *vp; + + (void)priv; + AZ(pthread_mutex_lock(&vcc_mtx)); + vp = mcf_find_vcl(cli, av[2]); + if (vp != NULL && vp->active == 0) { + if (mgt_cli_askchild(&status, &p, "config.use %s\n", av[2])) { + cli_result(cli, status); + cli_out(cli, "%s", p); + free(p); + } else { + vp->active = 2; + TAILQ_FOREACH(vp, &vclhead, list) { + if (vp->active == 1) + vp->active = 0; + else if (vp->active == 2) + vp->active = 1; + } + } + } + AZ(pthread_mutex_unlock(&vcc_mtx)); +} + +void +mcf_config_discard(struct cli *cli, char **av, void *priv) +{ + int status; + char *p; + struct vcls *vp; + (void)priv; + AZ(pthread_mutex_lock(&vcc_mtx)); + vp = mcf_find_vcl(cli, av[2]); + if (vp != NULL && vp->active) { + cli_result(cli, CLIS_PARAM); + cli_out(cli, "Cannot discard active VCL program\n"); + } else if (vp != NULL) { + if (mgt_cli_askchild(&status, &p, + "config.discard %s\n", av[2])) { + cli_result(cli, status); + cli_out(cli, "%s", p); + free(p); + } else { + AZ(mgt_vcc_delbyname(av[2])); + } + } + AZ(pthread_mutex_unlock(&vcc_mtx)); +} diff --git a/varnish-cache/include/cli.h b/varnish-cache/include/cli.h index 146011b0..4695dc73 100644 --- a/varnish-cache/include/cli.h +++ b/varnish-cache/include/cli.h @@ -59,9 +59,9 @@ "\tCompile and load the VCL data under the name provided.", \ 2, 2 -#define CLI_CONFIG_UNLOAD \ - "config.unload", \ - "config.unload ", \ +#define CLI_CONFIG_DISCARD \ + "config.discard", \ + "config.discard ", \ "\tUnload the named configuration (when possible).", \ 1, 1 diff --git a/varnish-cache/include/vcl.h b/varnish-cache/include/vcl.h index a6c78957..67a53dc4 100644 --- a/varnish-cache/include/vcl.h +++ b/varnish-cache/include/vcl.h @@ -22,6 +22,8 @@ struct VCL_conf { unsigned nref; unsigned busy; + void *priv; + vcl_init_f *init_func; vcl_fini_f *fini_func; diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 6675de1e..fb254bca 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -455,6 +455,8 @@ vcl_output_lang_h(FILE *f) fputs(" unsigned nref;\n", f); fputs(" unsigned busy;\n", f); fputs("\n", f); + fputs(" void *priv;\n", f); + fputs("\n", f); fputs(" vcl_init_f *init_func;\n", f); fputs(" vcl_fini_f *fini_func;\n", f); fputs("\n", f); diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index ce827693..0e7edc34 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -110,6 +110,8 @@ puts $fo { unsigned magic; unsigned nref; unsigned busy; + void *priv; + vcl_init_f *init_func; vcl_fini_f *fini_func; }