#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
{ 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 }
};
const char *name;
void *dlh;
struct VCL_conf *conf;
+ int discard;
};
/*
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 */
+ }
}
/*--------------------------------------------------------------------*/
free(vcl);
return (1);
}
+
if (vcl->conf->magic != VCL_CONF_MAGIC) {
if (cli == NULL)
fprintf(stderr, "Wrong VCL_CONF_MAGIC\n");
free(vcl);
return (1);
}
+ vcl->conf->priv = vcl;
vcl->name = strdup(name);
assert(vcl->name != NULL);
TAILQ_INSERT_TAIL(&vcl_head, vcl, list);
}
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
(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));
}
/*--------------------------------------------------------------------*/
{ 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 },
/* 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;
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)
}
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));
+}
"\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
unsigned nref;
unsigned busy;
+ void *priv;
+
vcl_init_f *init_func;
vcl_fini_f *fini_func;
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);
unsigned nref;
unsigned busy;
+ void *priv;
+
vcl_init_f *init_func;
vcl_fini_f *fini_func;
}