[experimental-ims] b3690c6 Make it possible for VCL initializtion to fail gracefully, particularly so VMOD loading can emit sensible diagnostics.
Geoff Simmons
geoff at varnish-cache.org
Mon Jan 9 21:51:46 CET 2012
commit b3690c63fdbb06caf6b33aa55b8ca83a1b8455d2
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Sep 7 19:30:48 2011 +0000
Make it possible for VCL initializtion to fail gracefully, particularly
so VMOD loading can emit sensible diagnostics.
diff --git a/bin/varnishd/cache_vcl.c b/bin/varnishd/cache_vcl.c
index 49f3fbb..ac712fb 100644
--- a/bin/varnishd/cache_vcl.c
+++ b/bin/varnishd/cache_vcl.c
@@ -170,10 +170,15 @@ VCL_Load(const char *fn, const char *name, struct cli *cli)
FREE_OBJ(vcl);
return (1);
}
+ if (vcl->conf->init_vcl(cli)) {
+ VCLI_Out(cli, "VCL \"%s\" Failed to initialize", name);
+ (void)dlclose(vcl->dlh);
+ FREE_OBJ(vcl);
+ return (1);
+ }
REPLACE(vcl->name, name);
- VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
- vcl->conf->init_vcl(cli);
+ VTAILQ_INSERT_TAIL(&vcl_head, vcl, list);
(void)vcl->conf->init_func(NULL);
Lck_Lock(&vcl_mtx);
if (vcl_active == NULL)
diff --git a/bin/varnishd/cache_vrt_vmod.c b/bin/varnishd/cache_vrt_vmod.c
index 4a4d230..84a2bb7 100644
--- a/bin/varnishd/cache_vrt_vmod.c
+++ b/bin/varnishd/cache_vrt_vmod.c
@@ -60,12 +60,12 @@ struct vmod {
static VTAILQ_HEAD(,vmod) vmods = VTAILQ_HEAD_INITIALIZER(vmods);
-void
-VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
+int
+VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
+ const char *path, struct cli *cli)
{
struct vmod *v;
- void *x;
- const int *i;
+ void *x, *y, *z;
ASSERT_CLI();
@@ -76,31 +76,46 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
ALLOC_OBJ(v, VMOD_MAGIC);
AN(v);
- VTAILQ_INSERT_TAIL(&vmods, v, list);
- VSC_C_main->vmods++;
-
- REPLACE(v->nm, nm);
- REPLACE(v->path, path);
-
- v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL);
- if (! v->hdl) {
- char buf[1024];
- sprintf(buf, "dlopen failed (child process lacks permission?): %.512s", dlerror());
- VAS_Fail(__func__, __FILE__, __LINE__, buf, 0, 0);
+ v->hdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+ if (v->hdl == NULL) {
+ VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+ VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
+ VCLI_Out(cli, "Check child process permissions.\n");
+ FREE_OBJ(v);
+ return (1);
}
x = dlsym(v->hdl, "Vmod_Name");
+ y = dlsym(v->hdl, "Vmod_Len");
+ z = dlsym(v->hdl, "Vmod_Func");
+ if (x == NULL || y == NULL || z == NULL) {
+ VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+ VCLI_Out(cli, "VMOD symbols not found\n");
+ VCLI_Out(cli, "Check relative pathnames.\n");
+ (void)dlclose(v->hdl);
+ FREE_OBJ(v);
+ return (1);
+ }
AN(x);
- /* XXX: check that name is correct */
+ AN(y);
+ AN(z);
+ if (strcmp(x, nm)) {
+ VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
+ VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", x);
+ VCLI_Out(cli, "Check relative pathnames ?.\n");
+ (void)dlclose(v->hdl);
+ FREE_OBJ(v);
+ return (1);
+ }
- x = dlsym(v->hdl, "Vmod_Len");
- AN(x);
- i = x;
- v->funclen = *i;
+ v->funclen = *(const int *)y;
+ v->funcs = z;
- x = dlsym(v->hdl, "Vmod_Func");
- AN(x);
- v->funcs = x;
+ REPLACE(v->nm, nm);
+ REPLACE(v->path, path);
+
+ VSC_C_main->vmods++;
+ VTAILQ_INSERT_TAIL(&vmods, v, list);
}
assert(len == v->funclen);
@@ -108,6 +123,7 @@ VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
v->ref++;
*hdl = v;
+ return (0);
}
void
diff --git a/bin/varnishd/mgt_child.c b/bin/varnishd/mgt_child.c
index 2664931..ebdf57b 100644
--- a/bin/varnishd/mgt_child.c
+++ b/bin/varnishd/mgt_child.c
@@ -385,7 +385,7 @@ start_child(struct cli *cli)
mgt_cli_start_child(child_cli_in, child_VCLI_Out);
child_pid = pid;
if (mgt_push_vcls_and_start(&u, &p)) {
- REPORT(LOG_ERR, "Pushing vcls failed: %s", p);
+ REPORT(LOG_ERR, "Pushing vcls failed:\n%s", p);
free(p);
child_state = CH_RUNNING;
mgt_stop_child();
diff --git a/include/vrt.h b/include/vrt.h
index cfafe75..9f0228f 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -183,8 +183,8 @@ void VRT_init_dir(struct cli *, struct director **, const char *name,
void VRT_fini_dir(struct cli *, struct director *);
/* VMOD/Modules related */
-void VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
- const char *path);
+int VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
+ const char *path, struct cli *cli);
void VRT_Vmod_Fini(void **hdl);
struct vmod_priv;
diff --git a/lib/libvcl/generate.py b/lib/libvcl/generate.py
index 5407a51..fde8bb2 100755
--- a/lib/libvcl/generate.py
+++ b/lib/libvcl/generate.py
@@ -712,7 +712,7 @@ fo.write("""
struct sess;
struct cli;
-typedef void vcl_init_f(struct cli *);
+typedef int vcl_init_f(struct cli *);
typedef void vcl_fini_f(struct cli *);
typedef int vcl_func_f(struct sess *sp);
""")
diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c
index b0019ca..c2a52d4 100644
--- a/lib/libvcl/vcc_compile.c
+++ b/lib/libvcl/vcc_compile.c
@@ -310,9 +310,10 @@ static void
EmitInitFunc(const struct vcc *tl)
{
- Fc(tl, 0, "\nstatic void\nVGC_Init(struct cli *cli)\n{\n\n");
+ Fc(tl, 0, "\nstatic int\nVGC_Init(struct cli *cli)\n{\n\n");
AZ(VSB_finish(tl->fi));
VSB_cat(tl->fc, VSB_data(tl->fi));
+ Fc(tl, 0, "\treturn(0);\n");
Fc(tl, 0, "}\n");
}
@@ -321,7 +322,7 @@ EmitFiniFunc(const struct vcc *tl)
{
unsigned u;
- Fc(tl, 0, "\nstatic void\nVGC_Fini(struct cli *cli)\n{\n\n");
+ Fc(tl, 0, "\nstatic int\nVGC_Fini(struct cli *cli)\n{\n\n");
/*
* We do this here, so we are sure they happen before any
@@ -332,6 +333,7 @@ EmitFiniFunc(const struct vcc *tl)
AZ(VSB_finish(tl->ff));
VSB_cat(tl->fc, VSB_data(tl->ff));
+ Fc(tl, 0, "\treturn(0);\n");
Fc(tl, 0, "}\n");
}
diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c
index 35cc702..f74f874 100644
--- a/lib/libvcl/vcc_vmod.c
+++ b/lib/libvcl/vcc_vmod.c
@@ -102,13 +102,15 @@ vcc_ParseImport(struct vcc *tl)
Fh(tl, 0, "static void *VGC_vmod_%.*s;\n", PF(mod));
- Fi(tl, 0, "\tVRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
+ Fi(tl, 0, "\tif (VRT_Vmod_Init(&VGC_vmod_%.*s,\n", PF(mod));
Fi(tl, 0, "\t &Vmod_Func_%.*s,\n", PF(mod));
Fi(tl, 0, "\t sizeof(Vmod_Func_%.*s),\n", PF(mod));
Fi(tl, 0, "\t \"%.*s\",\n", PF(mod));
Fi(tl, 0, "\t ");
EncString(tl->fi, fn, NULL, 0);
- Fi(tl, 0, ");\n");
+ Fi(tl, 0, ",\n\t ");
+ Fi(tl, 0, "cli))\n");
+ Fi(tl, 0, "\t\treturn(1);\n");
SkipToken(tl, ';');
More information about the varnish-commit
mailing list