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

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@638 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 6706e440
......@@ -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
......
......@@ -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 }
};
......
......@@ -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));
}
/*--------------------------------------------------------------------*/
......
......@@ -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 },
......
......@@ -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;
......@@ -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));
}
......@@ -59,9 +59,9 @@
"\tCompile and load the VCL data under the name provided.", \
2, 2
#define CLI_CONFIG_UNLOAD \
"config.unload", \
"config.unload <configname>", \
#define CLI_CONFIG_DISCARD \
"config.discard", \
"config.discard <configname>", \
"\tUnload the named configuration (when possible).", \
1, 1
......
......@@ -22,6 +22,8 @@ struct VCL_conf {
unsigned nref;
unsigned busy;
void *priv;
vcl_init_f *init_func;
vcl_fini_f *fini_func;
......
......@@ -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);
......
......@@ -110,6 +110,8 @@ puts $fo { unsigned magic;
unsigned nref;
unsigned busy;
void *priv;
vcl_init_f *init_func;
vcl_fini_f *fini_func;
}
......
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