[master] 4752b12 Move the VMOD caching from worker to master to avoid too many Jail contortions.

Poul-Henning Kamp phk at FreeBSD.org
Sun Mar 5 00:55:05 CET 2017


commit 4752b126dd729c6f708ea8f6b89cc7eaea5e308b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat Mar 4 23:51:54 2017 +0000

    Move the VMOD caching from worker to master to avoid too many
    Jail contortions.
    
    Fixes #2245

diff --git a/bin/varnishd/cache/cache_vrt_vmod.c b/bin/varnishd/cache/cache_vrt_vmod.c
index 009da54..97a18b2 100644
--- a/bin/varnishd/cache/cache_vrt_vmod.c
+++ b/bin/varnishd/cache/cache_vrt_vmod.c
@@ -68,46 +68,6 @@ struct vmod {
 
 static VTAILQ_HEAD(,vmod)	vmods = VTAILQ_HEAD_INITIALIZER(vmods);
 
-static int
-vrt_vmod_backup_copy(VRT_CTX, 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) {
-		VSB_printf(ctx->msg, "Creating copy of vmod %s: %s\n",
-		    nm, strerror(errno));
-		return (1);
-	}
-	fi = open(fm, O_RDONLY);
-	if (fi < 0) {
-		VSB_printf(ctx->msg, "Opening vmod %s from %s: %s\n",
-		    nm, fm, strerror(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)) {
-			VSB_printf(ctx->msg, "Copying vmod %s: %s\n",
-			    nm, strerror(errno));
-			AZ(unlink(to));
-			ret = 1;
-			break;
-		}
-	}
-	closefd(&fi);
-	closefd(&fo);
-	return(ret);
-}
 
 int
 VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm,
@@ -124,14 +84,6 @@ VRT_Vmod_Init(VRT_CTX, struct vmod **hdl, void *ptr, int len, const char *nm,
 	AN(hdl);
 	AZ(*hdl);
 
-	/*
-	 * We make a backup copy of the VMOD shlib in our working directory
-	 * and dlopen that, so that we can still restart the VCL's we have
-	 * already compiled when people updated their VMOD package.
-	 */
-	if (vrt_vmod_backup_copy(ctx, nm, path, backup))
-		return (1);
-
 	dlhdl = dlopen(backup, RTLD_NOW | RTLD_LOCAL);
 	if (dlhdl == NULL) {
 		VSB_printf(ctx->msg, "Loading vmod %s from %s:\n", nm, backup);
@@ -222,7 +174,6 @@ VRT_Vmod_Fini(struct vmod **hdl)
 		return;
 	free(v->nm);
 	free(v->path);
-	AZ(unlink(v->backup));
 	free(v->backup);
 	VTAILQ_REMOVE(&vmods, v, list);
 	VSC_C_main->vmods--;
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 041dba4..02c58fe 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -188,6 +188,7 @@ 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);
+void mgt_vcl_vmod(struct vclprog *, const char *src, const char *dst);
 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 bfb8b6f..d2fcdb1 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -375,7 +375,9 @@ mgt_VccCompile(struct cli *cli, struct vclprog *vcl, const char *vclname,
 		AZ(strcmp(av[ac-1], "*/"));
 		if (!strcmp(av[3], "VCL"))
 			mgt_vcl_depends(vcl, av[4]);
-		else if (strcmp(av[3], "VMOD"))
+		else if (!strcmp(av[3], "VMOD"))
+			mgt_vcl_vmod(vcl, av[4], av[5]);
+		else
 			WRONG("Wrong VCCINFO");
 		VAV_Free(av);
 	}
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 7d9e52e..9c1e412 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -31,6 +31,7 @@
 
 #include "config.h"
 
+#include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,6 +52,15 @@ static const char * const VCL_STATE_AUTO = "auto";
 static const char * const VCL_STATE_LABEL = "label";
 
 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;
@@ -74,9 +84,19 @@ struct vclprog {
 	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);
 static struct vclprog		*active_vcl;
 static struct vev *e_poker;
 
@@ -202,6 +222,7 @@ mgt_vcl_add(const char *name, const char *state)
 	REPLACE(vp->name, name);
 	VTAILQ_INIT(&vp->dfrom);
 	VTAILQ_INIT(&vp->dto);
+	VTAILQ_INIT(&vp->vmods);
 	vp->state = state;
 
 	if (vp->state != VCL_STATE_COLD)
@@ -215,6 +236,8 @@ static void
 mgt_vcl_del(struct vclprog *vp)
 {
 	char *p;
+	struct vmoddep *vd;
+	struct vmodfile *vf;
 
 	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
 	while (!VTAILQ_EMPTY(&vp->dto))
@@ -239,6 +262,22 @@ mgt_vcl_del(struct vclprog *vp)
 		VJ_master(JAIL_MASTER_LOW);
 		free(vp->fname);
 	}
+	while (!VTAILQ_EMPTY(&vp->vmods)) {
+		vd = VTAILQ_FIRST(&vp->vmods);
+		CHECK_OBJ(vd, VMODDEP_MAGIC);
+		vf = vd->to;
+		CHECK_OBJ(vf, VMODFILE_MAGIC);
+		VTAILQ_REMOVE(&vp->vmods, vd, lfrom);
+		VTAILQ_REMOVE(&vf->vcls, vd, lto);
+		FREE_OBJ(vd);
+
+		if (VTAILQ_EMPTY(&vf->vcls)) {
+			AZ(unlink(vf->fname));
+			VTAILQ_REMOVE(&vmodhead, vf, list);
+			free(vf->fname);
+			FREE_OBJ(vf);
+		}
+	}
 	free(vp->name);
 	FREE_OBJ(vp);
 }
@@ -255,6 +294,78 @@ mgt_vcl_depends(struct vclprog *vp1, const char *name)
 	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, "Creating copy of vmod %s: %s\n",
+		    nm, strerror(errno));
+		return (1);
+	}
+	fi = open(fm, O_RDONLY);
+	if (fi < 0) {
+		fprintf(stderr, "Opening vmod %s from %s: %s\n",
+		    nm, fm, strerror(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, strerror(errno));
+			AZ(unlink(to));
+			ret = 1;
+			break;
+		}
+	}
+	closefd(&fi);
+	AZ(fchmod(fo, 0444));
+	closefd(&fo);
+	return(ret);
+}
+
+void
+mgt_vcl_vmod(struct vclprog *vp, const char *src, const char *dst)
+{
+	struct vmodfile *vf;
+	struct vmoddep *vd;
+
+	CHECK_OBJ_NOTNULL(vp, VCLPROG_MAGIC);
+	AN(src);
+	AN(dst);
+	assert(!strncmp(dst, "./vmod_cache/", 13));
+
+	VTAILQ_FOREACH(vf, &vmodhead, list)
+		if (!strcmp(vf->fname, dst))
+			break;
+	if (vf == NULL) {
+		ALLOC_OBJ(vf, VMODFILE_MAGIC);
+		AN(vf);
+		REPLACE(vf->fname, dst);
+		AN(vf->fname);
+		VTAILQ_INIT(&vf->vcls);
+		AZ(mgt_vcl_cache_vmod(vp->name, src, 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);
+}
+
 int
 mgt_has_vcl(void)
 {



More information about the varnish-commit mailing list