[master] 02acb35b5 More work to turn our VCL dependency tracking into a proper symboltable with references.
Poul-Henning Kamp
phk at FreeBSD.org
Mon May 27 08:01:10 UTC 2019
commit 02acb35b54eb22b39eada5e2ef12120d835718b9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon May 27 07:32:02 2019 +0000
More work to turn our VCL dependency tracking into a proper symboltable
with references.
diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 86ec2d460..41fffd334 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -89,6 +89,7 @@ varnishd_SOURCES = \
mgt/mgt_param_tweak.c \
mgt/mgt_pool.c \
mgt/mgt_shmem.c \
+ mgt/mgt_symtab.c \
mgt/mgt_util.c \
mgt/mgt_vcc.c \
mgt/mgt_vcl.c \
@@ -137,6 +138,7 @@ noinst_HEADERS = \
http1/cache_http1.h \
http2/cache_http2.h \
mgt/mgt.h \
+ mgt/mgt_vcl.h \
mgt/mgt_param.h \
storage/storage.h \
storage/storage_persistent.h \
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 78f79ce4d..82c34b52a 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -215,9 +215,7 @@ void mgt_vcl_init(void);
void mgt_vcl_startup(struct cli *, const char *vclsrc, const char *origin,
const char *vclname, int Cflag);
int mgt_push_vcls(struct cli *, unsigned *status, char **p);
-void mgt_vcl_export_labels(struct vcc *);
int mgt_has_vcl(void);
-void mgt_vcl_symtab(struct vclprog *, struct vjsn *);
extern char *mgt_cc_cmd;
extern const char *mgt_vcl_path;
extern const char *mgt_vmod_path;
diff --git a/bin/varnishd/mgt/mgt_symtab.c b/bin/varnishd/mgt/mgt_symtab.c
new file mode 100644
index 000000000..608c3c24e
--- /dev/null
+++ b/bin/varnishd/mgt/mgt_symtab.c
@@ -0,0 +1,200 @@
+/*-
+ * Copyright (c) 2019 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * VCL/VMOD symbol table
+ */
+
+#include "config.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
+
+#include "libvcc.h"
+#include "vjsn.h"
+
+/*--------------------------------------------------------------------*/
+
+static const char *
+mgt_vcl_symtab_val(const struct vjsn_val *vv, const char *val)
+{
+ const struct vjsn_val *jv;
+
+ jv = vjsn_child(vv, val);
+ AN(jv);
+ assert(jv->type == VJSN_STRING);
+ AN(jv->value);
+ return (jv->value);
+}
+
+static void
+mgt_vcl_import_vcl(struct vclprog *vp1, const struct vjsn_val *vv)
+{
+ struct vclprog *vp2;
+
+ CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
+ AN(vv);
+
+ vp2 = mcf_vcl_byname(mgt_vcl_symtab_val(vv, "name"));
+ CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
+ mgt_vcl_dep_add(vp1, vp2);
+}
+
+static int
+mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
+{
+ int fi, fo;
+ int ret = 0;
+ ssize_t sz;
+ char buf[BUFSIZ];
+
+ fo = open(to, O_WRONLY | O_CREAT | O_EXCL, 0744);
+ if (fo < 0 && errno == EEXIST)
+ return (0);
+ if (fo < 0) {
+ fprintf(stderr, "While creating copy of vmod %s:\n\t%s: %s\n",
+ nm, to, vstrerror(errno));
+ return (1);
+ }
+ fi = open(fm, O_RDONLY);
+ if (fi < 0) {
+ fprintf(stderr, "Opening vmod %s from %s: %s\n",
+ nm, fm, vstrerror(errno));
+ AZ(unlink(to));
+ closefd(&fo);
+ return (1);
+ }
+ while (1) {
+ sz = read(fi, buf, sizeof buf);
+ if (sz == 0)
+ break;
+ if (sz < 0 || sz != write(fo, buf, sz)) {
+ fprintf(stderr, "Copying vmod %s: %s\n",
+ nm, vstrerror(errno));
+ AZ(unlink(to));
+ ret = 1;
+ break;
+ }
+ }
+ closefd(&fi);
+ AZ(fchmod(fo, 0444));
+ closefd(&fo);
+ return (ret);
+}
+
+static void
+mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
+{
+ struct vmodfile *vf;
+ struct vmoddep *vd;
+ const char *v_name;
+ const char *v_file;
+ const char *v_dst;
+
+ CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+ AN(vv);
+
+ v_name = mgt_vcl_symtab_val(vv, "name");
+ v_file = mgt_vcl_symtab_val(vv, "file");
+ v_dst = mgt_vcl_symtab_val(vv, "dst");
+
+ VTAILQ_FOREACH(vf, &vmodhead, list)
+ if (!strcmp(vf->fname, v_dst))
+ break;
+ if (vf == NULL) {
+ ALLOC_OBJ(vf, VMODFILE_MAGIC);
+ AN(vf);
+ REPLACE(vf->fname, v_dst);
+ AN(vf->fname);
+ VTAILQ_INIT(&vf->vcls);
+ AZ(mgt_vcl_cache_vmod(v_name, v_file, v_dst));
+ VTAILQ_INSERT_TAIL(&vmodhead, vf, list);
+ }
+ ALLOC_OBJ(vd, VMODDEP_MAGIC);
+ AN(vd);
+ vd->to = vf;
+ VTAILQ_INSERT_TAIL(&vp->vmods, vd, lfrom);
+ VTAILQ_INSERT_TAIL(&vf->vcls, vd, lto);
+}
+
+void
+mgt_vcl_symtab(struct vclprog *vp, const char *input)
+{
+ struct vjsn *vj;
+ struct vjsn_val *v1, *v2;
+ const char *typ, *err;
+
+ CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+ AN(input);
+ vj = vjsn_parse(input, &err);
+ if (err != NULL) {
+ fprintf(stderr, "FATAL: Symtab parse error: %s\n%s\n",
+ err, input);
+ }
+ AZ(err);
+ AN(vj);
+ vp->symtab = vj;
+ assert(vj->value->type == VJSN_ARRAY);
+ VTAILQ_FOREACH(v1, &vj->value->children, list) {
+ assert(v1->type == VJSN_OBJECT);
+ v2 = vjsn_child(v1, "dir");
+ if (v2 == NULL)
+ continue;
+ assert(v2->type == VJSN_STRING);
+ if (strcmp(v2->value, "import"))
+ continue;
+ typ = mgt_vcl_symtab_val(v1, "type");
+ if (!strcmp(typ, "$VMOD"))
+ mgt_vcl_import_vmod(vp, v1);
+ else if (!strcmp(typ, "$VCL"))
+ mgt_vcl_import_vcl(vp, v1);
+ else
+ WRONG("Bad symtab import entry");
+ }
+}
+
+
+/*--------------------------------------------------------------------*/
+
+void
+mgt_vcl_export_labels(struct vcc *vcc)
+{
+ struct vclprog *vp;
+ VTAILQ_FOREACH(vp, &vclhead, list) {
+ if (mcf_is_label(vp))
+ VCC_Predef(vcc, "VCL_VCL", vp->name);
+ }
+}
+
+/*--------------------------------------------------------------------*/
+
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index adb98efe6..5316ab299 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -39,25 +39,25 @@
#include <sys/stat.h>
#include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
#include "common/heritage.h"
#include "storage/storage.h"
#include "libvcc.h"
#include "vcli_serve.h"
#include "vfil.h"
-#include "vjsn.h"
#include "vsub.h"
#include "vtim.h"
struct vcc_priv {
unsigned magic;
#define VCC_PRIV_MAGIC 0x70080cb8
- char *dir;
const char *vclsrc;
const char *vclsrcfile;
- char *csrcfile;
- char *libfile;
- char *symfile;
+ struct vsb *dir;
+ struct vsb *csrcfile;
+ struct vsb *libfile;
+ struct vsb *symfile;
};
char *mgt_cc_cmd;
@@ -96,7 +96,7 @@ run_vcc(void *priv)
VJ_subproc(JAIL_SUBPROC_VCC);
CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
- AZ(chdir(vp->dir));
+ AZ(chdir(VSB_data(vp->dir)));
vcc = VCC_New();
AN(vcc);
@@ -132,7 +132,7 @@ run_cc(void *priv)
VJ_subproc(JAIL_SUBPROC_CC);
CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
- AZ(chdir(vp->dir));
+ AZ(chdir(VSB_data(vp->dir)));
sb = VSB_new_auto();
AN(sb);
@@ -180,7 +180,7 @@ run_dlopen(void *priv)
VJ_subproc(JAIL_SUBPROC_VCLLOAD);
CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
- if (VCL_TestLoad(vp->libfile))
+ if (VCL_TestLoad(VSB_data(vp->libfile)))
exit(1);
exit(0);
}
@@ -215,13 +215,13 @@ static unsigned
mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
{
char *csrc;
- const char *err;
unsigned subs;
- struct vjsn *vj;
- if (mgt_vcc_touchfile(vp->csrcfile, sb))
+ AN(sb);
+ VSB_clear(sb);
+ if (mgt_vcc_touchfile(VSB_data(vp->csrcfile), sb))
return (2);
- if (mgt_vcc_touchfile(vp->libfile, sb))
+ if (mgt_vcc_touchfile(VSB_data(vp->libfile), sb))
return (2);
subs = VSUB_run(sb, run_vcc, vp, "VCC-compiler", -1);
@@ -229,20 +229,15 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
return (subs);
if (C_flag) {
- csrc = VFIL_readfile(NULL, vp->csrcfile, NULL);
+ csrc = VFIL_readfile(NULL, VSB_data(vp->csrcfile), NULL);
AN(csrc);
VSB_cat(sb, csrc);
free(csrc);
VSB_printf(sb, "/* EXTERNAL SYMBOL TABLE\n");
- csrc = VFIL_readfile(NULL, vp->symfile, NULL);
+ csrc = VFIL_readfile(NULL, VSB_data(vp->symfile), NULL);
AN(csrc);
VSB_cat(sb, csrc);
- vj = vjsn_parse(csrc, &err);
- if (err != NULL)
- VSB_printf(sb, "# Parse error: %s\n", err);
- if (vj != NULL)
- vjsn_delete(&vj);
VSB_printf(sb, "*/\n");
free(csrc);
}
@@ -257,25 +252,53 @@ mgt_vcc_compile(struct vcc_priv *vp, struct vsb *sb, int C_flag)
/*--------------------------------------------------------------------*/
+static void
+mgt_vcc_init_vp(struct vcc_priv *vp)
+{
+ INIT_OBJ(vp, VCC_PRIV_MAGIC);
+ vp->csrcfile = VSB_new_auto();
+ AN(vp->csrcfile);
+ vp->libfile = VSB_new_auto();
+ AN(vp->libfile);
+ vp->symfile = VSB_new_auto();
+ AN(vp->symfile);
+ vp->dir = VSB_new_auto();
+ AN(vp->dir);
+}
+
+static void
+mgt_vcc_fini_vp(struct vcc_priv *vp, int leave_lib)
+{
+ if (!MGT_DO_DEBUG(DBG_VCL_KEEP)) {
+ (void)unlink(VSB_data(vp->csrcfile));
+ (void)unlink(VSB_data(vp->symfile));
+ if (!leave_lib)
+ (void)unlink(VSB_data(vp->libfile));
+ }
+ (void)rmdir(VSB_data(vp->dir));
+ VSB_destroy(&vp->csrcfile);
+ VSB_destroy(&vp->libfile);
+ VSB_destroy(&vp->symfile);
+ VSB_destroy(&vp->dir);
+}
+
char *
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 vcc_priv vp[1];
struct vsb *sb;
- struct vjsn *vj;
unsigned status;
- const char *err;
char *p;
AN(cli);
sb = VSB_new_auto();
- XXXAN(sb);
+ AN(sb);
- INIT_OBJ(&vp, VCC_PRIV_MAGIC);
- vp.vclsrc = vclsrc;
- vp.vclsrcfile = vclsrcfile;
+ mgt_vcc_init_vp(vp);
+ vp->vclsrc = vclsrc;
+ vp->vclsrcfile = vclsrcfile;
/*
* The subdirectory must have a unique name to 100% certain evade
@@ -309,56 +332,35 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
*
* The Best way to reproduce this is to have regexps in the VCL.
*/
- VSB_printf(sb, "vcl_%s.%.6f", vclname, VTIM_real());
- AZ(VSB_finish(sb));
- vp.dir = strdup(VSB_data(sb));
- AN(vp.dir);
- if (VJ_make_subdir(vp.dir, "VCL", cli->sb)) {
- free(vp.dir);
+ VSB_printf(vp->dir, "vcl_%s.%.6f", vclname, VTIM_real());
+ AZ(VSB_finish(vp->dir));
+
+ VSB_printf(vp->csrcfile, "%s/%s", VSB_data(vp->dir), VGC_SRC);
+ AZ(VSB_finish(vp->csrcfile));
+
+ VSB_printf(vp->libfile, "%s/%s", VSB_data(vp->dir), VGC_LIB);
+ AZ(VSB_finish(vp->libfile));
+
+ VSB_printf(vp->symfile, "%s/%s", VSB_data(vp->dir), VGC_SYM);
+ AZ(VSB_finish(vp->symfile));
+
+ if (VJ_make_subdir(VSB_data(vp->dir), "VCL", cli->sb)) {
+ mgt_vcc_fini_vp(vp, 0);
VSB_destroy(&sb);
VCLI_Out(cli, "VCL compilation failed");
VCLI_SetResult(cli, CLIS_PARAM);
return (NULL);
}
- VSB_clear(sb);
- VSB_printf(sb, "%s/%s", vp.dir, VGC_SRC);
- AZ(VSB_finish(sb));
- vp.csrcfile = strdup(VSB_data(sb));
- AN(vp.csrcfile);
- VSB_clear(sb);
-
- VSB_printf(sb, "%s/%s", vp.dir, VGC_LIB);
- AZ(VSB_finish(sb));
- vp.libfile = strdup(VSB_data(sb));
- AN(vp.csrcfile);
- VSB_clear(sb);
-
- VSB_printf(sb, "%s/%s", vp.dir, VGC_SYM);
- AZ(VSB_finish(sb));
- vp.symfile = strdup(VSB_data(sb));
- AN(vp.symfile);
- VSB_clear(sb);
-
- status = mgt_vcc_compile(&vp, sb, C_flag);
-
+ status = mgt_vcc_compile(vp, sb, C_flag);
AZ(VSB_finish(sb));
if (VSB_len(sb) > 0)
VCLI_Out(cli, "%s", VSB_data(sb));
VSB_destroy(&sb);
if (status || C_flag) {
- if (!MGT_DO_DEBUG(DBG_VCL_KEEP)) {
- (void)unlink(vp.csrcfile);
- (void)unlink(vp.libfile);
- (void)unlink(vp.symfile);
- (void)rmdir(vp.dir);
- }
- free(vp.csrcfile);
- free(vp.libfile);
- free(vp.symfile);
- free(vp.dir);
+ mgt_vcc_fini_vp(vp, 0);
if (status) {
VCLI_Out(cli, "VCL compilation failed");
VCLI_SetResult(cli, CLIS_PARAM);
@@ -366,26 +368,13 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
return (NULL);
}
- p = VFIL_readfile(NULL, vp.symfile, NULL);
+ p = VFIL_readfile(NULL, VSB_data(vp->symfile), NULL);
AN(p);
- vj = vjsn_parse(p, &err);
- if (err != NULL)
- fprintf(stderr, "FATAL: Symtab parse error: %s\n%s\n",
- err, p);
- AZ(err);
- AN(vj);
- free(p);
- mgt_vcl_symtab(vcl, vj);
- (void)unlink(vp.symfile);
- free(vp.symfile);
-
- if (!MGT_DO_DEBUG(DBG_VCL_KEEP))
- (void)unlink(vp.csrcfile);
- free(vp.csrcfile);
-
- free(vp.dir);
+ mgt_vcl_symtab(vcl, p);
VCLI_Out(cli, "VCL compiled.\n");
- return (vp.libfile);
+ REPLACE(p, VSB_data(vp->libfile));
+ mgt_vcc_fini_vp(vp, 1);
+ return (p);
}
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 1a388248c..88e8bcce0 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -31,17 +31,15 @@
#include "config.h"
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <sys/stat.h>
#include "mgt/mgt.h"
+#include "mgt/mgt_vcl.h"
#include "common/heritage.h"
-#include "libvcc.h"
#include "vcli_serve.h"
#include "vct.h"
#include "vev.h"
@@ -56,53 +54,8 @@ static const char * const VCL_STATE_LABEL = "label";
static int vcl_count;
-struct vclprog;
-struct vmodfile;
-
-struct vmoddep {
- unsigned magic;
-#define VMODDEP_MAGIC 0xc1490542
- VTAILQ_ENTRY(vmoddep) lfrom;
- struct vmodfile *to;
- VTAILQ_ENTRY(vmoddep) lto;
-};
-
-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;
- unsigned warm;
- const char * state;
- double go_cold;
- struct vjsn *symtab;
- VTAILQ_HEAD(, vcldep) dfrom;
- VTAILQ_HEAD(, vcldep) dto;
- int nto;
- int loaded;
- VTAILQ_HEAD(, vmoddep) vmods;
-};
-
-struct vmodfile {
- unsigned magic;
-#define VMODFILE_MAGIC 0xffa1a0d5
- char *fname;
- VTAILQ_ENTRY(vmodfile) list;
- VTAILQ_HEAD(, vmoddep) vcls;
-};
-
-static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
-static VTAILQ_HEAD(, vmodfile) vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead);
+struct vclproghead vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
+struct vmodfilehead vmodhead = VTAILQ_HEAD_INITIALIZER(vmodhead);
static struct vclprog *active_vcl;
static struct vev *e_poker;
@@ -127,7 +80,7 @@ mcf_vcl_parse_state(struct cli *cli, const char *s)
return (NULL);
}
-static struct vclprog *
+struct vclprog *
mcf_vcl_byname(const char *name)
{
struct vclprog *vp;
@@ -189,7 +142,7 @@ mcf_find_no_vcl(struct cli *cli, const char *name)
return (1);
}
-static int
+int
mcf_is_label(const struct vclprog *vp)
{
return (vp->state == VCL_STATE_LABEL);
@@ -197,7 +150,7 @@ mcf_is_label(const struct vclprog *vp)
/*--------------------------------------------------------------------*/
-static void
+void
mgt_vcl_dep_add(struct vclprog *vp_from, struct vclprog *vp_to)
{
struct vcldep *vd;
@@ -316,135 +269,6 @@ mgt_vcl_del(struct vclprog *vp)
FREE_OBJ(vp);
}
-static const char *
-mgt_vcl_symtab_val(const struct vjsn_val *vv, const char *val)
-{
- const struct vjsn_val *jv;
-
- jv = vjsn_child(vv, val);
- AN(jv);
- assert(jv->type == VJSN_STRING);
- AN(jv->value);
- return (jv->value);
-}
-
-static void
-mgt_vcl_import_vcl(struct vclprog *vp1, const struct vjsn_val *vv)
-{
- struct vclprog *vp2;
-
- CHECK_OBJ_NOTNULL(vp1, VCLPROG_MAGIC);
- AN(vv);
-
- vp2 = mcf_vcl_byname(mgt_vcl_symtab_val(vv, "name"));
- CHECK_OBJ_NOTNULL(vp2, VCLPROG_MAGIC);
- mgt_vcl_dep_add(vp1, vp2);
-}
-
-static int
-mgt_vcl_cache_vmod(const char *nm, const char *fm, const char *to)
-{
- int fi, fo;
- int ret = 0;
- ssize_t sz;
- char buf[BUFSIZ];
-
- fo = open(to, O_WRONLY | O_CREAT | O_EXCL, 0744);
- if (fo < 0 && errno == EEXIST)
- return (0);
- if (fo < 0) {
- fprintf(stderr, "While creating copy of vmod %s:\n\t%s: %s\n",
- nm, to, vstrerror(errno));
- return (1);
- }
- fi = open(fm, O_RDONLY);
- if (fi < 0) {
- fprintf(stderr, "Opening vmod %s from %s: %s\n",
- nm, fm, vstrerror(errno));
- AZ(unlink(to));
- closefd(&fo);
- return (1);
- }
- while (1) {
- sz = read(fi, buf, sizeof buf);
- if (sz == 0)
- break;
- if (sz < 0 || sz != write(fo, buf, sz)) {
- fprintf(stderr, "Copying vmod %s: %s\n",
- nm, vstrerror(errno));
- AZ(unlink(to));
- ret = 1;
- break;
- }
- }
- closefd(&fi);
- AZ(fchmod(fo, 0444));
- closefd(&fo);
- return (ret);
-}
-
-static void
-mgt_vcl_import_vmod(struct vclprog *vp, const struct vjsn_val *vv)
-{
- struct vmodfile *vf;
- struct vmoddep *vd;
- const char *v_name;
- const char *v_file;
- const char *v_dst;
-
- CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
- AN(vv);
-
- v_name = mgt_vcl_symtab_val(vv, "name");
- v_file = mgt_vcl_symtab_val(vv, "file");
- v_dst = mgt_vcl_symtab_val(vv, "dst");
-
- VTAILQ_FOREACH(vf, &vmodhead, list)
- if (!strcmp(vf->fname, v_dst))
- break;
- if (vf == NULL) {
- ALLOC_OBJ(vf, VMODFILE_MAGIC);
- AN(vf);
- REPLACE(vf->fname, v_dst);
- AN(vf->fname);
- VTAILQ_INIT(&vf->vcls);
- AZ(mgt_vcl_cache_vmod(v_name, v_file, v_dst));
- VTAILQ_INSERT_TAIL(&vmodhead, vf, list);
- }
- ALLOC_OBJ(vd, VMODDEP_MAGIC);
- AN(vd);
- vd->to = vf;
- VTAILQ_INSERT_TAIL(&vp->vmods, vd, lfrom);
- VTAILQ_INSERT_TAIL(&vf->vcls, vd, lto);
-}
-
-void
-mgt_vcl_symtab(struct vclprog *vp, struct vjsn *vj)
-{
- struct vjsn_val *v1, *v2;
- const char *typ;
-
- CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
- vp->symtab = vj;
- assert(vj->value->type == VJSN_ARRAY);
- VTAILQ_FOREACH(v1, &vj->value->children, list) {
- assert(v1->type == VJSN_OBJECT);
- v2 = vjsn_child(v1, "dir");
- if (v2 == NULL)
- continue;
- assert(v2->type == VJSN_STRING);
- if (strcmp(v2->value, "import"))
- continue;
- typ = mgt_vcl_symtab_val(v1, "type");
- if (!strcmp(typ, "$VMOD"))
- mgt_vcl_import_vmod(vp, v1);
- else if (!strcmp(typ, "$VCL"))
- mgt_vcl_import_vcl(vp, v1);
- else
- WRONG("Bad symtab import entry");
- }
-}
-
int
mgt_has_vcl(void)
{
@@ -673,18 +497,6 @@ mgt_vcl_startup(struct cli *cli, const char *vclsrc, const char *vclname,
/*--------------------------------------------------------------------*/
-void
-mgt_vcl_export_labels(struct vcc *vcc)
-{
- struct vclprog *vp;
- VTAILQ_FOREACH(vp, &vclhead, list) {
- if (mcf_is_label(vp))
- VCC_Predef(vcc, "VCL_VCL", vp->name);
- }
-}
-
-/*--------------------------------------------------------------------*/
-
int
mgt_push_vcls(struct cli *cli, unsigned *status, char **p)
{
diff --git a/bin/varnishd/mgt/mgt_vcl.h b/bin/varnishd/mgt/mgt_vcl.h
new file mode 100644
index 000000000..21163d7ae
--- /dev/null
+++ b/bin/varnishd/mgt/mgt_vcl.h
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2019 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * VCL/VMOD symbol table
+ */
+
+struct vclprog;
+struct vmodfile;
+
+struct vmoddep {
+ unsigned magic;
+#define VMODDEP_MAGIC 0xc1490542
+ VTAILQ_ENTRY(vmoddep) lfrom;
+ struct vmodfile *to;
+ VTAILQ_ENTRY(vmoddep) lto;
+};
+
+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;
+ unsigned warm;
+ const char * state;
+ double go_cold;
+ struct vjsn *symtab;
+ VTAILQ_HEAD(, vcldep) dfrom;
+ VTAILQ_HEAD(, vcldep) dto;
+ int nto;
+ int loaded;
+ VTAILQ_HEAD(, vmoddep) vmods;
+};
+
+struct vmodfile {
+ unsigned magic;
+#define VMODFILE_MAGIC 0xffa1a0d5
+ char *fname;
+ VTAILQ_ENTRY(vmodfile) list;
+ VTAILQ_HEAD(, vmoddep) vcls;
+};
+
+extern VTAILQ_HEAD(vclproghead, vclprog) vclhead;
+extern VTAILQ_HEAD(vmodfilehead, vmodfile) vmodhead;
+
+struct vclprog *mcf_vcl_byname(const char *name);
+void mgt_vcl_dep_add(struct vclprog *vp_from, struct vclprog *vp_to);
+int mcf_is_label(const struct vclprog *vp);
+
+void mgt_vcl_export_labels(struct vcc *vcc);
+void mgt_vcl_symtab(struct vclprog *vp, const char *input);
+
More information about the varnish-commit
mailing list