[PATCH] Allow vmod objects to trigger initialization failures
Martin Blix Grydeland
martin at varnish-software.com
Wed Jun 10 16:36:38 CEST 2015
This allows vmod objects to signal failures if the vmod fails to set
it's object pointer. The VCL will then return early and a VCL
initialization failure is reported.
Also change the deinitialization to only call the fini if the object
pointer is non-NULL.
---
bin/varnishtest/tests/m00022.vtc | 30 ++++++++++++++++++++++++++++++
lib/libvcc/vcc_action.c | 11 ++++++++++-
lib/libvmod_debug/vmod.vcc | 4 ++++
lib/libvmod_debug/vmod_debug_obj.c | 15 +++++++++++++++
4 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/bin/varnishtest/tests/m00022.vtc b/bin/varnishtest/tests/m00022.vtc
index c070f19..a173c08 100644
--- a/bin/varnishtest/tests/m00022.vtc
+++ b/bin/varnishtest/tests/m00022.vtc
@@ -14,9 +14,18 @@ varnish v1 -vcl {
import ${vmod_debug};
+ sub vcl_init {
+ new obj = debug.obj("asdf");
+ }
+
sub vcl_recv {
if (req.url == "/failinit") {
debug.set_failinit(1);
+ obj.set_failobj(0);
+ return (synth (200));
+ } else if (req.url == "/failobj") {
+ debug.set_failinit(0);
+ obj.set_failobj(1);
return (synth (200));
} else {
return (synth (404));
@@ -52,3 +61,24 @@ varnish v1 -errvcl {failinit=1} {
import ${vmod_debug};
}
+
+# Change to make object init fail
+client c1 {
+ txreq -url /failobj
+ rxresp
+ expect resp.status == 200
+} -run
+
+# Check that object init fails are caught
+varnish v1 -errvcl {failobj=1} {
+ backend default {
+ .host = "${s1_addr}";
+ .port = "${s1_port}";
+ }
+
+ import ${vmod_debug};
+
+ sub vcl_init {
+ new obj = debug.obj("asdf");
+ }
+}
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index c4f984d..b70c5ad 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -220,8 +220,17 @@ parse_new(struct vcc *tl)
bprintf(buf1, ", &vo_%s, \"%s\"", sy1->name, sy1->name);
vcc_Eval_Func(tl, s_init, buf1, sy2->name, s_init + strlen(s_init) + 1);
+
+ Fb(tl, 1, "if (!vo_%s) {\n", sy1->name);
+ tl->indent += INDENT;
+ Fb(tl, 1, "VRT_handling(ctx, VCL_RET_FAIL);\n");
+ Fb(tl, 1, "return (1);\n");
+ tl->indent -= INDENT;
+ Fb(tl, 1, "}\n");
+
ifp = New_IniFin(tl);
- VSB_printf(ifp->fin, "\t%s(&vo_%s);", s_fini, sy1->name);
+ VSB_printf(ifp->fin, "\tif (vo_%s)\n", sy1->name);
+ VSB_printf(ifp->fin, "\t\t%s(&vo_%s);", s_fini, sy1->name);
ExpectErr(tl, ';');
bprintf(buf1, ", vo_%s", sy1->name);
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index cbd89a8..8584878 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -93,6 +93,10 @@ $Method TIME .date()
You never know when you need a date.
+$Method VOID .set_failobj(INT)
+
+If set non-zero, the obj vmod object will fail during initialization.
+
$Function VOID rot52(HTTP hdr)
Encrypt the HTTP header with quad-ROT13 encryption,
diff --git a/lib/libvmod_debug/vmod_debug_obj.c b/lib/libvmod_debug/vmod_debug_obj.c
index 19a966c..7a20495 100644
--- a/lib/libvmod_debug/vmod_debug_obj.c
+++ b/lib/libvmod_debug/vmod_debug_obj.c
@@ -41,6 +41,8 @@ struct vmod_debug_obj {
int foobar;
};
+static int failobj = 0;
+
VCL_VOID
vmod_obj__init(VRT_CTX, struct vmod_debug_obj **op,
const char *vcl_name, VCL_STRING s)
@@ -48,6 +50,10 @@ vmod_obj__init(VRT_CTX, struct vmod_debug_obj **op,
struct vmod_debug_obj *o;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ if (failobj) {
+ VRT_cliout(ctx, "vmod_debug:obj_init:failobj=%u:", failobj);
+ return;
+ }
(void)vcl_name;
(void)s;
AN(op);
@@ -98,3 +104,12 @@ vmod_obj_date(VRT_CTX, struct vmod_debug_obj *o)
assert(o->foobar == 42);
return (21.4);
}
+
+VCL_VOID __match_proto__(td_debug_obj_set_failobj)
+vmod_obj_set_failobj(VRT_CTX, struct vmod_debug_obj *o, VCL_INT val)
+{
+
+ (void)ctx;
+ (void)o;
+ failobj = val;
+}
--
2.1.4
More information about the varnish-dev
mailing list