r4224 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Wed Sep 2 20:05:15 CEST 2009


Author: phk
Date: 2009-09-02 20:05:15 +0200 (Wed, 02 Sep 2009)
New Revision: 4224

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/cache_http.c
   trunk/varnish-cache/bin/varnishd/flint.lnt
   trunk/varnish-cache/bin/varnishd/hash_slinger.h
   trunk/varnish-cache/bin/varnishd/mgt_param.c
Log:
Originally, we did not have the bereq.* and beresp.* variable sets,
and instead (ab)used the obj.* set.

This allowed, amongst other things, the headers of cached objects
to be munged by subsequent cache-hits.

This was just as bad an idea as it sounds.

The downside was, that we had to reserve object workspace for the
potentially created headers, and this really bites, memory wise,
if your content is many small objects.

This commit allows, and sets obj_workspace to zero, allocating only
as much space as is necessary for the actual headers after vcl_fetch()
has returned.

The downside is, without extra workspace, you can no longer change
the content of obj.* string variables after the vcl_fetch() which
instantiated the object.

For now we still allow the obj_workspace to be set to reserve such
space, but in all likelyhood, this ability will disappear in the
future.





Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2009-09-02 18:05:15 UTC (rev 4224)
@@ -154,6 +154,7 @@
 	txt			hd[HTTP_HDR_MAX];
 	unsigned char		hdf[HTTP_HDR_MAX];
 #define HDF_FILTER		(1 << 0)	/* Filtered by Connection */
+#define HDF_COPY		(1 << 1)	/* Copy this field */
 	unsigned		nhd;
 };
 
@@ -512,6 +513,7 @@
 
 /* cache_http.c */
 const char *http_StatusMessage(unsigned);
+unsigned http_EstimateWS(struct http *fm, unsigned how);
 void HTTP_Init(void);
 void http_ClrHeader(struct http *to);
 unsigned http_Write(struct worker *w, const struct http *hp, int resp);

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2009-09-02 18:05:15 UTC (rev 4224)
@@ -334,7 +334,7 @@
 	if (sp->obj == NULL) {
 		HSH_Prealloc(sp);
 		sp->wrk->cacheable = 0;
-		sp->obj = HSH_NewObject(sp);
+		sp->obj = HSH_NewObject(sp, 0);
 		sp->obj->xid = sp->xid;
 		sp->obj->entered = sp->t_req;
 	} else {
@@ -415,7 +415,7 @@
 	int i;
 	struct http *hp, *hp2;
 	char *b;
-	unsigned handling;
+	unsigned handling, l;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
@@ -516,11 +516,16 @@
 		AZ(sp->objcore);
 	}
 
+	l = http_EstimateWS(sp->wrk->beresp, HTTPH_A_INS);
+
+	/* Space for producing a Content-Length: header */
+	l += 30;
+
 	/*
 	 * XXX: If we have a Length: header, we should allocate the body
 	 * XXX: also.
  	 */
-	sp->obj = HSH_NewObject(sp);
+	sp->obj = HSH_NewObject(sp, l);
 
 	if (sp->objhead != NULL) {
 		CHECK_OBJ_NOTNULL(sp->objhead, OBJHEAD_MAGIC);

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2009-09-02 18:05:15 UTC (rev 4224)
@@ -82,22 +82,27 @@
 }
 
 struct object *
-HSH_NewObject(struct sess *sp)
+HSH_NewObject(struct sess *sp, unsigned l)
 {
 	struct object *o;
 	struct storage *st;
 	void *p;
 
+	if (l == 0)
+		l = 1024;
+	if (params->obj_workspace > 0 && params->obj_workspace > l)
+		l =  params->obj_workspace;
+
 	if (!sp->wrk->cacheable) {
-		p = malloc(sizeof *o + params->obj_workspace);
+		p = malloc(sizeof *o + l);
 		XXXAN(p);
 		o = p;
 		p = o + 1;
 		memset(o, 0, sizeof *o);
 		o->magic = OBJECT_MAGIC;
-		WS_Init(o->ws_o, "obj", p, params->obj_workspace);
+		WS_Init(o->ws_o, "obj", p, l);
 	} else {
-		st = STV_alloc(sp, params->obj_workspace);
+		st = STV_alloc(sp, sizeof *o + l);
 		XXXAN(st);
 		assert(st->space > sizeof *o);
 		o = (void *)st->ptr; /* XXX: align ? */

Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c	2009-09-02 18:05:15 UTC (rev 4224)
@@ -624,6 +624,34 @@
 	}
 }
 
+/*--------------------------------------------------------------------
+ * Estimate how much workspace we need to Filter this header according
+ * to 'how'.
+ */
+
+unsigned 
+http_EstimateWS(struct http *fm, unsigned how)
+{
+	unsigned u, l;
+
+	l = 0;
+	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
+	for (u = 0; u < fm->nhd; u++) {
+		if (fm->hd[u].b == NULL)
+			continue;
+		if (fm->hdf[u] & HDF_FILTER)
+			continue;
+#define HTTPH(a, b, c, d, e, f, g) \
+		if (((e) & how) && http_IsHdr(&fm->hd[u], (b))) \
+			continue;
+#include "http_headers.h"
+#undef HTTPH
+		l += Tlen(fm->hd[u]) + 1;
+		// fm->hdf[u] |= HDF_COPY;
+	}
+	return (l);
+}
+
 /*--------------------------------------------------------------------*/
 
 void

Modified: trunk/varnish-cache/bin/varnishd/flint.lnt
===================================================================
--- trunk/varnish-cache/bin/varnishd/flint.lnt	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/flint.lnt	2009-09-02 18:05:15 UTC (rev 4224)
@@ -131,7 +131,9 @@
 // cache_center.c
 -efunc(525, CNT_Session)	// Negative indentation from line
 -efunc(525, http_FilterFields)	// Negative indentation from line
+-efunc(525, http_EstimateWS)	// Negative indentation from line
 -efunc(539, http_FilterFields)	// Positive indentation from line
+-efunc(539, http_EstimateWS)	// Positive indentation from line
 
 // cache_vcl.c
 -efunc(525, vcl_handlingname)	// Negative indentation from line

Modified: trunk/varnish-cache/bin/varnishd/hash_slinger.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/hash_slinger.h	2009-09-02 18:05:15 UTC (rev 4224)
@@ -50,7 +50,7 @@
 };
 
 /* cache_hash.c */
-struct object *HSH_NewObject(struct sess *sp);
+struct object *HSH_NewObject(struct sess *sp, unsigned len);
 void HSH_Object(const struct sess *sp);
 void HSH_Prealloc(const struct sess *sp);
 void HSH_Cleanup(struct worker *w);

Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_param.c	2009-09-02 16:43:18 UTC (rev 4223)
+++ trunk/varnish-cache/bin/varnishd/mgt_param.c	2009-09-02 18:05:15 UTC (rev 4224)
@@ -492,14 +492,14 @@
 		"Minimum is 1024 bytes.",
 		DELAYED_EFFECT,
 		"16384", "bytes" },
-	{ "obj_workspace", tweak_uint, &master.obj_workspace, 1024, UINT_MAX,
+	{ "obj_workspace", tweak_uint, &master.obj_workspace, 0, UINT_MAX,
 		"Bytes of HTTP protocol workspace allocated for objects. "
 		"This space must be big enough for the entire HTTP protocol "
 		"header and any edits done to it in the VCL code while it "
 		"is cached.\n"
 		"Minimum is 1024 bytes.",
 		DELAYED_EFFECT,
-		"8192", "bytes" },
+		"0", "bytes" },
 	{ "shm_workspace", tweak_uint, &master.shm_workspace, 4096, UINT_MAX,
 		"Bytes of shmlog workspace allocated for worker threads. "
 		"If too big, it wastes some ram, if too small it causes "



More information about the varnish-commit mailing list