[master] c1d8d66 Add a generalized dependency tracking facility for VCLs
Poul-Henning Kamp
phk at FreeBSD.org
Tue Aug 16 11:20:15 CEST 2016
commit c1d8d66f80fc9ac5498cca82db7961f44b221681
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Aug 16 06:48:48 2016 +0000
Add a generalized dependency tracking facility for VCLs
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 61f8e7c..df11959 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -49,7 +49,20 @@ static const char * const VCL_STATE_WARM = "warm";
static const char * const VCL_STATE_AUTO = "auto";
static const char * const VCL_STATE_LABEL = "label";
+struct vclprog;
+
+struct vcldep {
+ unsigned magic;
+#define VCLDEP_MAGIC 0xa9a17dc2
+ struct vclprog *from;
+ VTAILQ_ENTRY(vcldep) lfrom;
+ struct vclprog *to;
+ VTAILQ_ENTRY(vcldep) lto;
+};
+
struct vclprog {
+ unsigned magic;
+#define VCLPROG_MAGIC 0x9ac09fea
VTAILQ_ENTRY(vclprog) list;
char *name;
char *fname;
@@ -57,6 +70,8 @@ struct vclprog {
const char * state;
double go_cold;
struct vclprog *label;
+ VTAILQ_HEAD(, vcldep) dfrom;
+ VTAILQ_HEAD(, vcldep) dto;
};
static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
@@ -65,6 +80,33 @@ static struct vev *e_poker;
/*--------------------------------------------------------------------*/
+static void
+mgt_vcl_dep_add(struct vclprog *vp_from, struct vclprog *vp_to)
+{
+ struct vcldep *vd;
+
+ CHECK_OBJ_NOTNULL(vp_from, VCLPROG_MAGIC);
+ CHECK_OBJ_NOTNULL(vp_to, VCLPROG_MAGIC);
+ ALLOC_OBJ(vd, VCLDEP_MAGIC);
+ XXXAN(vd);
+ vd->from = vp_from;
+ VTAILQ_INSERT_TAIL(&vp_from->dfrom, vd, lfrom);
+ vd->to = vp_to;
+ VTAILQ_INSERT_TAIL(&vp_to->dto, vd, lto);
+}
+
+static void
+mgt_vcl_dep_del(struct vcldep *vd)
+{
+
+ CHECK_OBJ_NOTNULL(vd, VCLDEP_MAGIC);
+ VTAILQ_REMOVE(&vd->from->dfrom, vd, lfrom);
+ VTAILQ_REMOVE(&vd->to->dfrom, vd, lto);
+ FREE_OBJ(vd);
+}
+
+/*--------------------------------------------------------------------*/
+
static struct vclprog *
mgt_vcl_add(const char *name, const char *libfile, const char *state)
{
@@ -74,10 +116,12 @@ mgt_vcl_add(const char *name, const char *libfile, const char *state)
state == VCL_STATE_COLD ||
state == VCL_STATE_AUTO ||
state == VCL_STATE_LABEL);
- vp = calloc(sizeof *vp, 1);
+ 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;
if (vp->state != VCL_STATE_COLD)
@@ -94,6 +138,10 @@ mgt_vcl_del(struct vclprog *vp)
{
char *p;
+ CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+ while (!VTAILQ_EMPTY(&vp->dfrom))
+ mgt_vcl_dep_del(VTAILQ_FIRST(&vp->dfrom));
+
VTAILQ_REMOVE(&vclhead, vp, list);
if (strcmp(vp->state, VCL_STATE_LABEL)) {
AZ(unlink(vp->fname));
@@ -112,7 +160,7 @@ mgt_vcl_del(struct vclprog *vp)
free(vp->fname);
}
free(vp->name);
- free(vp);
+ FREE_OBJ(vp);
}
static struct vclprog *
@@ -444,11 +492,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
VCLI_Out(cli, "Cannot discard active VCL program\n");
return;
}
- if (!strcmp(vp->state, VCL_STATE_LABEL)) {
- AN(vp->warm);
- vp->label->label = NULL;
- vp->label = NULL;
- } else {
+ if (!VTAILQ_EMPTY(&vp->dto)) {
if (vp->label != NULL) {
AN(vp->warm);
VCLI_SetResult(cli, CLIS_PARAM);
@@ -457,6 +501,13 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
vp->label->name);
return;
}
+ INCOMPL();
+ }
+ if (!strcmp(vp->state, VCL_STATE_LABEL)) {
+ AN(vp->warm);
+ vp->label->label = NULL;
+ vp->label = NULL;
+ } else {
(void)mgt_vcl_setstate(cli, vp, VCL_STATE_COLD);
}
if (child_pid >= 0) {
@@ -508,7 +559,6 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
char *p;
int i;
- (void)av;
(void)priv;
vpt = mcf_find_vcl(cli, av[3]);
if (vpt == NULL)
@@ -525,21 +575,25 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
return;
}
vpl = mgt_vcl_byname(av[2]);
- if (vpl == NULL)
- vpl = mgt_vcl_add(av[2], NULL, VCL_STATE_LABEL);
- AN(vpl);
- if (strcmp(vpl->state, VCL_STATE_LABEL)) {
- VCLI_SetResult(cli, CLIS_PARAM);
- VCLI_Out(cli, "%s is not a label", vpl->name);
- return;
- }
- vpl->warm = 1;
- if (vpl->label != NULL) {
+ if (vpl != NULL) {
+ if (strcmp(vpl->state, VCL_STATE_LABEL)) {
+ VCLI_SetResult(cli, CLIS_PARAM);
+ VCLI_Out(cli, "%s is not a label", vpl->name);
+ return;
+ }
+ AN(vpl->label);
assert(vpl->label->label == vpl);
/* XXX SET vp->label AUTO */
vpl->label->label = NULL;
vpl->label = NULL;
+ mgt_vcl_dep_del(VTAILQ_FIRST(&vpl->dfrom));
+ AN(VTAILQ_EMPTY(&vpl->dfrom));
+ } else {
+ vpl = mgt_vcl_add(av[2], NULL, VCL_STATE_LABEL);
}
+ AN(vpl);
+ mgt_vcl_dep_add(vpl, vpt);
+ vpl->warm = 1;
vpl->label = vpt;
vpt->label = vpl;
if (vpt->state == VCL_STATE_COLD)
More information about the varnish-commit
mailing list