[3.0] f124895 Register buffer allocation failuers on vgz's and make failure to clean those up non-fatal.

Tollef Fog Heen tfheen at varnish-cache.org
Mon Apr 16 10:20:34 CEST 2012


commit f124895fc3e704eb39a16bfa1811c88a0ba631a7
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Oct 25 09:44:39 2011 +0000

    Register buffer allocation failuers on vgz's and make failure
    to clean those up non-fatal.
    
    Fixes	#1036
    
    Conflicts:
    
    	bin/varnishd/cache_gzip.c

diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c
index b32b5cf..1eaa7fa 100644
--- a/bin/varnishd/cache_gzip.c
+++ b/bin/varnishd/cache_gzip.c
@@ -82,6 +82,7 @@ struct vgz {
 	const char		*id;
 	struct ws		*tmp;
 	char			*tmp_snapshot;
+	const char		*error;
 
 	struct storage		*obuf;
 
@@ -263,8 +264,10 @@ VGZ_ObufStorage(const struct sess *sp, struct vgz *vg)
 	struct storage *st;
 
 	st = FetchStorage(sp, 0);
-	if (st == NULL)
+	if (st == NULL) {
+		vg->error = "Could not get ObufStorage";
 		return (-1);
+	}
 
 	vg->obuf = st;
 	VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len);
@@ -409,6 +412,7 @@ void
 VGZ_Destroy(struct vgz **vgp)
 {
 	struct vgz *vg;
+	const char *err;
 
 	vg = *vgp;
 	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
@@ -421,12 +425,13 @@ VGZ_Destroy(struct vgz **vgp)
 	    (intmax_t)vg->vz.start_bit,
 	    (intmax_t)vg->vz.last_bit,
 	    (intmax_t)vg->vz.stop_bit);
+	err = vg->error;
 	if (vg->tmp != NULL)
 		WS_Reset(vg->tmp, vg->tmp_snapshot);
 	if (vg->dir == VGZ_GZ)
-		AZ(deflateEnd(&vg->vz));
+		assert(deflateEnd(&vg->vz) == 0 || err != NULL);
 	else
-		AZ(inflateEnd(&vg->vz));
+		assert(inflateEnd(&vg->vz) == 0 || err != NULL);
 	FREE_OBJ(vg);
 }
 
@@ -566,18 +571,21 @@ vfp_gzip_end(struct sess *sp)
 	int i;
 
 	vg = sp->wrk->vgz_rx;
-	sp->wrk->vgz_rx = NULL;
 	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
-	do {
-		VGZ_Ibuf(vg, "", 0);
-		if (VGZ_ObufStorage(sp, vg))
-			return (-1);
-		i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
-		sp->obj->len += dl;
-	} while (i != Z_STREAM_END);
-	if (sp->wrk->do_stream)
-		RES_StreamPoll(sp);
-	VGZ_UpdateObj(vg, sp->obj);
+	sp->wrk->vgz_rx = NULL;
+
+	if (vg->error == NULL) {
+		do {
+			VGZ_Ibuf(vg, "", 0);
+			if (VGZ_ObufStorage(sp, vg))
+				return (-1);
+			i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
+			sp->obj->len += dl;
+		} while (i != Z_STREAM_END);
+		if (sp->wrk->do_stream)
+			RES_StreamPoll(sp);
+		VGZ_UpdateObj(vg, sp->obj);
+	}
 	VGZ_Destroy(&vg);
 	return (0);
 }
@@ -621,6 +629,7 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
 		st = FetchStorage(sp, 0);
 		if (st == NULL) {
 			htc->error = "Could not get storage";
+			vg->error = htc->error;
 			return (-1);
 		}
 		l = st->space - st->len;
diff --git a/bin/varnishtest/tests/r01036.vtc b/bin/varnishtest/tests/r01036.vtc
new file mode 100644
index 0000000..8fb7600
--- /dev/null
+++ b/bin/varnishtest/tests/r01036.vtc
@@ -0,0 +1,22 @@
+varnishtest "Test case for #1036"
+
+server s1 {
+	rxreq
+	# Send a bodylen of 1,5M, which will exceed cache space of 1M
+	non-fatal
+	txresp -bodylen 1572864
+} -start
+
+varnish v1 -arg "-smalloc,1M" -arg "-pgzip_level=0" -vcl+backend {
+	sub vcl_fetch {
+		set beresp.do_gzip = true;
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == "503"
+} -run
+
+



More information about the varnish-commit mailing list