[master] 2d1c467 Track VCL->VCL dependencies
Poul-Henning Kamp
phk at FreeBSD.org
Tue Aug 16 11:20:16 CEST 2016
commit 2d1c4679a5300e21c23bc2292f8e7be03141250f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Aug 16 09:02:37 2016 +0000
Track VCL->VCL dependencies
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 29ada85..1877424 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -36,6 +36,7 @@
struct cli;
struct parspec;
struct vcc;
+struct vclprog;
extern struct vev_base *mgt_evb;
extern unsigned d_flag;
@@ -170,8 +171,8 @@ void STV_Config(const char *spec);
void STV_Config_Transient(void);
/* mgt_vcc.c */
-char *mgt_VccCompile(struct cli *, const char *vclname, const char *vclsrc,
- const char *vclsrcfile, int C_flag);
+char *mgt_VccCompile(struct cli *, struct vclprog *, const char *vclname,
+ const char *vclsrc, const char *vclsrcfile, int C_flag);
void mgt_vcl_init(void);
void mgt_vcc_startup(struct cli *, const char *b_arg, const char *f_arg,
@@ -179,6 +180,7 @@ void mgt_vcc_startup(struct cli *, const char *b_arg, const char *f_arg,
int mgt_push_vcls_and_start(struct cli *, unsigned *status, char **p);
void mgt_vcl_export_labels(struct vcc *);
int mgt_has_vcl(void);
+void mgt_vcl_depends(struct vclprog *vp1, const char *name);
extern char *mgt_cc_cmd;
extern const char *mgt_vcl_path;
extern const char *mgt_vmod_path;
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 36dbbd4..f8d6224 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -47,6 +47,7 @@
#include "vcli_serve.h"
#include "vfil.h"
#include "vsub.h"
+#include "vav.h"
#include "vtim.h"
struct vcc_priv {
@@ -258,12 +259,16 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
/*--------------------------------------------------------------------*/
char *
-mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
- const char *vclsrcfile, int C_flag)
+mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
+ const char *vclsrc, const char *vclsrcfile, int C_flag)
{
struct vcc_priv vp;
struct vsb *sb;
unsigned status;
+ char buf[1024];
+ FILE *fcs;
+ char **av;
+ int ac;
AN(cli);
@@ -339,10 +344,9 @@ mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
VCLI_Out(cli, "%s", VSB_data(sb));
VSB_destroy(&sb);
- (void)unlink(vp.csrcfile);
- free(vp.csrcfile);
-
if (status || C_flag) {
+ (void)unlink(vp.csrcfile);
+ free(vp.csrcfile);
(void)unlink(vp.libfile);
free(vp.libfile);
(void)rmdir(vp.dir);
@@ -354,6 +358,26 @@ mgt_VccCompile(struct cli *cli, const char *vclname, const char *vclsrc,
return (NULL);
}
+ fcs = fopen(vp.csrcfile, "r");
+ AN(fcs);
+ while (1) {
+ AN(fgets(buf, sizeof buf, fcs));
+ if (memcmp(buf, VCC_INFO_PREFIX, strlen(VCC_INFO_PREFIX)))
+ break;
+ av = VAV_Parse(buf, &ac, 0);
+ AN(av);
+ AZ(av[0]);
+ AZ(strcmp(av[1], "/*"));
+ AZ(strcmp(av[ac-1], "*/"));
+ AZ(strcmp(av[3], "VCL"));
+ mgt_vcl_depends(vcl, av[4]);
+ VAV_Free(av);
+ }
+ AZ(fclose(fcs));
+
+ (void)unlink(vp.csrcfile);
+ free(vp.csrcfile);
+
free(vp.dir);
VCLI_Out(cli, "VCL compiled.\n");
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 245fa54..6b873a5 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -109,7 +109,7 @@ mgt_vcl_dep_del(struct vcldep *vd)
/*--------------------------------------------------------------------*/
static struct vclprog *
-mgt_vcl_add(const char *name, const char *libfile, const char *state)
+mgt_vcl_add(const char *name, const char *state)
{
struct vclprog *vp;
@@ -120,7 +120,6 @@ mgt_vcl_add(const char *name, const char *libfile, const char *state)
ALLOC_OBJ(vp, VCLPROG_MAGIC);
XXXAN(vp);
REPLACE(vp->name, name);
- REPLACE(vp->fname, libfile);
VTAILQ_INIT(&vp->dfrom);
VTAILQ_INIT(&vp->dto);
vp->state = state;
@@ -144,7 +143,7 @@ mgt_vcl_del(struct vclprog *vp)
mgt_vcl_dep_del(VTAILQ_FIRST(&vp->dfrom));
VTAILQ_REMOVE(&vclhead, vp, list);
- if (strcmp(vp->state, VCL_STATE_LABEL)) {
+ if (vp->fname != NULL) {
AZ(unlink(vp->fname));
p = strrchr(vp->fname, '/');
AN(p);
@@ -175,6 +174,18 @@ mgt_vcl_byname(const char *name)
return (NULL);
}
+void
+mgt_vcl_depends(struct vclprog *vp1, const char *name)
+{
+ struct vclprog *vp2;
+
+ CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
+
+ vp2 = mgt_vcl_byname(name);
+ CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
+ mgt_vcl_dep_add(vp1, vp2);
+}
+
int
mgt_has_vcl(void)
{
@@ -261,13 +272,15 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc,
return;
}
- lib = mgt_VccCompile(cli, vclname, vclsrc, vclsrcfile, C_flag);
- if (lib == NULL)
+ vp = mgt_vcl_add(vclname, state);
+ lib = mgt_VccCompile(cli, vp, vclname, vclsrc, vclsrcfile, C_flag);
+ if (lib == NULL) {
+ mgt_vcl_del(vp);
return;
+ }
AZ(C_flag);
- vp = mgt_vcl_add(vclname, lib, state);
- free(lib);
+ vp->fname = lib;
if (child_pid < 0)
return;
@@ -311,8 +324,10 @@ void
mgt_vcl_export_labels(struct vcc *vcc)
{
struct vclprog *vp;
- VTAILQ_FOREACH(vp, &vclhead, list)
- VCC_Predef(vcc, "VCL_VCL", vp->name);
+ VTAILQ_FOREACH(vp, &vclhead, list) {
+ if (!strcmp(vp->state, VCL_STATE_LABEL))
+ VCC_Predef(vcc, "VCL_VCL", vp->name);
+ }
}
/*--------------------------------------------------------------------*/
@@ -493,6 +508,8 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
unsigned status;
char *p = NULL;
struct vclprog *vp;
+ struct vcldep *vd;
+ int n;
(void)priv;
vp = mcf_find_vcl(cli, av[2]);
@@ -504,7 +521,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
return;
}
if (!VTAILQ_EMPTY(&vp->dto)) {
- if (vp->label != NULL) {
+ if (vp->label != NULL && strcmp(vp->state, VCL_STATE_LABEL)) {
AN(vp->warm);
VCLI_SetResult(cli, CLIS_PARAM);
VCLI_Out(cli,
@@ -512,7 +529,19 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
vp->label->name);
return;
}
- INCOMPL();
+ VCLI_SetResult(cli, CLIS_PARAM);
+ VCLI_Out(cli,
+ "Cannot discard \"%s\" VCL label, "
+ "other VCLs depend on it.\n", vp->name);
+ n = 0;
+ VTAILQ_FOREACH(vd, &vp->dto, lto) {
+ if (n++ == 5) {
+ VCLI_Out(cli, "\t[...]");
+ break;
+ }
+ VCLI_Out(cli, "\t%s\n", vd->from->name);
+ }
+ return;
}
if (!strcmp(vp->state, VCL_STATE_LABEL)) {
AN(vp->warm);
@@ -600,7 +629,13 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
mgt_vcl_dep_del(VTAILQ_FIRST(&vpl->dfrom));
AN(VTAILQ_EMPTY(&vpl->dfrom));
} else {
- vpl = mgt_vcl_add(av[2], NULL, VCL_STATE_LABEL);
+ /* XXX should check for C-syntax */
+ if (strchr(av[2], '.')) {
+ VCLI_SetResult(cli, CLIS_PARAM);
+ VCLI_Out(cli, "VCL labels cannot contain '.'");
+ return;
+ }
+ vpl = mgt_vcl_add(av[2], VCL_STATE_LABEL);
}
AN(vpl);
mgt_vcl_dep_add(vpl, vpt);
More information about the varnish-commit
mailing list