[master] d1bbd0b Properly clean up resources after STV_NewObject fails before jumping to error.

Martin Blix Grydeland martin at varnish-cache.org
Tue Mar 19 15:43:19 CET 2013


commit d1bbd0b38fe067da391a1ad9cba42484321c6b8b
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Mon Mar 18 16:07:02 2013 +0100

    Properly clean up resources after STV_NewObject fails before jumping to error.
    
    Fixes: #1284

diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index a7f8778..49a6732 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -487,6 +487,7 @@ cnt_fetchbody(struct worker *wrk, struct req *req)
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
 	bo = req->busyobj;
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
@@ -571,7 +572,6 @@ cnt_fetchbody(struct worker *wrk, struct req *req)
 
 	/* Create Vary instructions */
 	if (req->objcore->objhead != NULL) {
-		CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
 		vary = VRY_Create(req, bo->beresp);
 		if (vary != NULL) {
 			varyl = VSB_len(vary);
@@ -610,6 +610,8 @@ cnt_fetchbody(struct worker *wrk, struct req *req)
 	if (req->obj == NULL) {
 		req->err_code = 503;
 		req->req_step = R_STP_ERROR;
+		AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
+		req->objcore = NULL;
 		VDI_CloseFd(&bo->vbc);
 		VBO_DerefBusyObj(wrk, &req->busyobj);
 		return (REQ_FSM_MORE);
diff --git a/bin/varnishtest/tests/r01284.vtc b/bin/varnishtest/tests/r01284.vtc
new file mode 100644
index 0000000..33a2a08
--- /dev/null
+++ b/bin/varnishtest/tests/r01284.vtc
@@ -0,0 +1,43 @@
+varnishtest "#1284 - Test resource cleanup after STV_NewObject fail in fetch"
+
+server s1 {
+	rxreq
+	expect req.url == "/obj1"
+	txresp -bodylen 1048000
+	rxreq
+	expect req.url == "/obj2"
+	txresp -hdr "Long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -hdr "Long2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+} -start
+
+varnish v1 -arg "-p nuke_limit=0" -storage "-sTransient=malloc,1m" -vcl+backend {
+	sub vcl_fetch {
+		set beresp.storage = "Transient";
+	}
+} -start
+
+client c1 {
+	# Fill transient
+	txreq -url "/obj1"
+	rxresp
+	expect resp.status == 200
+} -run
+
+varnish v1 -expect SMA.Transient.g_bytes > 1048000
+varnish v1 -expect SMA.Transient.g_space < 200
+
+client c1 {
+	# No space for this object (more than 256 bytes in headers). Don't wait
+	# for reply as Varnish will not send one due to Transient full.
+	txreq -url "/obj2"
+	delay 1
+} -run
+
+# Two failures, one for obj2 and two for the attempts at sending error
+varnish v1 -expect SMA.Transient.c_fail == 3
+
+client c1 {
+	# Check that Varnish is still alive
+	txreq -url "/obj1"
+	rxresp
+	expect resp.status == 200
+} -run



More information about the varnish-commit mailing list