[4.0] 5cf517e Change the way we build synth content for vcl_error{}.

Poul-Henning Kamp phk at FreeBSD.org
Thu Mar 13 10:24:31 CET 2014


commit 5cf517e858b212a37a106a8ae78ffabe13a0dd5b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 10 19:59:24 2014 +0000

    Change the way we build synth content for vcl_error{}.
    
    This eliminates the need for the SMS stevedore.

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 8cd8cf5..d9a8e62 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -78,7 +78,6 @@ varnishd_SOURCES = \
 	storage/storage_persistent_mgt.c \
 	storage/storage_persistent_silo.c \
 	storage/storage_persistent_subr.c \
-	storage/storage_synth.c \
 	storage/storage_umem.c \
 	waiter/mgt_waiter.c \
 	waiter/cache_waiter.c \
diff --git a/bin/varnishd/Makefile.phk b/bin/varnishd/Makefile.phk
index 1cbd5c2..f8bf48a 100644
--- a/bin/varnishd/Makefile.phk
+++ b/bin/varnishd/Makefile.phk
@@ -73,7 +73,6 @@ PROG_SRC += storage/storage_persistent.c
 PROG_SRC += storage/storage_persistent_mgt.c
 PROG_SRC += storage/storage_persistent_silo.c
 PROG_SRC += storage/storage_persistent_subr.c
-PROG_SRC += storage/storage_synth.c
 PROG_SRC += storage/storage_umem.c
 
 PROG_SRC += waiter/cache_waiter.c
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index a954316..e0f45c9 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -722,6 +722,9 @@ struct req {
 
 	/* Temporary accounting */
 	struct acct		acct_req;
+
+	/* Synth content in vcl_error */
+	struct vsb		*synth_body;
 };
 
 /*--------------------------------------------------------------------
@@ -1226,11 +1229,6 @@ int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len);
 void STV_BanExport(const uint8_t *bans, unsigned len);
 struct storage *STV_alloc_transient(size_t size);
 
-/* storage_synth.c */
-struct vsb *SMS_Makesynth(struct object *obj);
-void SMS_Finish(struct object *obj);
-void SMS_Init(void);
-
 /* storage_persistent.c */
 void SMP_Init(void);
 void SMP_Ready(void);
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index 8e116c9..a5674c0 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -226,7 +226,6 @@ child_main(void)
 
 	VCA_Init();
 
-	SMS_Init();
 	SMP_Init();
 	STV_open();
 
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 8696dad..f5ae189 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -190,6 +190,8 @@ cnt_error(struct worker *wrk, struct req *req)
 	struct http *h;
 	struct busyobj *bo;
 	char date[40];
+	ssize_t l;
+	struct storage *st;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -205,7 +207,6 @@ cnt_error(struct worker *wrk, struct req *req)
 	    TRANSIENT_STORAGE, cache_param->http_resp_size,
 	    (uint16_t)cache_param->http_max_hdr);
 	req->obj = bo->fetch_obj;
-	bo->stats = NULL;
 	if (req->obj == NULL) {
 		req->doclose = SC_OVERLOAD;
 		req->director_hint = NULL;
@@ -213,6 +214,7 @@ cnt_error(struct worker *wrk, struct req *req)
 		bo->fetch_objcore = NULL;
 		http_Teardown(bo->beresp);
 		http_Teardown(bo->bereq);
+		bo->stats = NULL;
 		VBO_DerefBusyObj(wrk, &bo);
 		return (REQ_FSM_DONE);
 	}
@@ -239,13 +241,25 @@ cnt_error(struct worker *wrk, struct req *req)
 		http_PutResponse(h, req->err_reason);
 	else
 		http_PutResponse(h, http_StatusMessage(req->err_code));
+
+	AZ(req->synth_body);
+	req->synth_body = VSB_new_auto();
+	AN(req->synth_body);
+
 	VCL_error_method(req->vcl, wrk, req, NULL, req->http->ws);
 
+	http_Unset(req->obj->http, H_Content_Length);
+
+	AZ(VSB_finish(req->synth_body));
+
 	/* Stop the insanity before it turns "Hotel California" on us */
 	if (req->restarts >= cache_param->max_restarts)
 		wrk->handling = VCL_RET_DELIVER;
 
 	if (wrk->handling == VCL_RET_RESTART) {
+		VSB_delete(req->synth_body);
+		req->synth_body = NULL;
+		bo->stats = NULL;
 		VBO_DerefBusyObj(wrk, &bo);
 		HSH_Drop(wrk, &req->obj);
 		req->req_step = R_STP_RESTART;
@@ -258,10 +272,28 @@ cnt_error(struct worker *wrk, struct req *req)
 	req->wantbody = 1;
 
 	assert(wrk->handling == VCL_RET_DELIVER);
+
+	l = VSB_len(req->synth_body);
+	if (l > 0) {
+		st = STV_alloc(bo, l);
+		if (st != NULL) {
+			VTAILQ_INSERT_TAIL(&req->obj->store, st, list);
+			if (st->space >= l) {
+				memcpy(st->ptr, VSB_data(req->synth_body), l);
+				st->len = l;
+				req->obj->len = l;
+			}
+		}
+	}
+
+	VSB_delete(req->synth_body);
+	req->synth_body = NULL;
+
 	req->err_code = 0;
 	req->err_reason = NULL;
 	http_Teardown(bo->bereq);
 	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
+	bo->stats = NULL;
 	VBO_DerefBusyObj(wrk, &bo);
 	req->req_step = R_STP_DELIVER;
 	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 95a37b0..c423eb2 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -369,21 +369,19 @@ VRT_Rollback(const struct vrt_ctx *ctx)
 /*--------------------------------------------------------------------*/
 
 void
-VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
+VRT_synth_page(const struct vrt_ctx *ctx, const char *str, ...)
 {
 	va_list ap;
 	const char *p;
 	struct vsb *vsb;
 
-	(void)flags;
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	if (ctx->method == VCL_MET_BACKEND_ERROR) {
 		CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
 		vsb = ctx->bo->synth_body;
 	} else {
 		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
-		CHECK_OBJ_NOTNULL(ctx->req->obj, OBJECT_MAGIC);
-		vsb = SMS_Makesynth(ctx->req->obj);
+		vsb = ctx->req->synth_body;
 	}
 	AN(vsb);
 
@@ -396,10 +394,6 @@ VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
 		p = va_arg(ap, const char *);
 	}
 	va_end(ap);
-	if (ctx->method != VCL_MET_BACKEND_ERROR) {
-		SMS_Finish(ctx->req->obj);
-		http_Unset(ctx->req->obj->http, H_Content_Length);
-	}
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/storage/storage_synth.c b/bin/varnishd/storage/storage_synth.c
deleted file mode 100644
index ba3fa24..0000000
--- a/bin/varnishd/storage/storage_synth.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*-
- * Copyright (c) 2008-2011 Varnish Software AS
- * All rights reserved.
- *
- * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Storage method for synthetic content, based on vsb.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "cache/cache.h"
-#include "storage/storage.h"
-
-
-static struct lock		sms_mtx;
-
-static void
-sms_free(struct storage *sto)
-{
-
-	CHECK_OBJ_NOTNULL(sto, STORAGE_MAGIC);
-	Lck_Lock(&sms_mtx);
-	VSC_C_main->sms_nobj--;
-	VSC_C_main->sms_nbytes -= sto->len;
-	VSC_C_main->sms_bfree += sto->len;
-	Lck_Unlock(&sms_mtx);
-	VSB_delete(sto->priv);
-	free(sto);
-}
-
-void
-SMS_Init(void)
-{
-
-	Lck_New(&sms_mtx, lck_sms);
-}
-
-static struct stevedore sms_stevedore = {
-	.magic	=	STEVEDORE_MAGIC,
-	.name	=	"synth",
-	.free	=	sms_free,
-};
-
-struct vsb *
-SMS_Makesynth(struct object *obj)
-{
-	struct storage *sto;
-	struct vsb *vsb;
-
-	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
-	STV_Freestore(obj);
-	obj->len = 0;
-
-	Lck_Lock(&sms_mtx);
-	VSC_C_main->sms_nreq++;
-	VSC_C_main->sms_nobj++;
-	Lck_Unlock(&sms_mtx);
-
-	sto = calloc(sizeof *sto, 1);
-	XXXAN(sto);
-	vsb = VSB_new_auto();
-	XXXAN(vsb);
-	sto->priv = vsb;
-	sto->len = 0;
-	sto->space = 0;
-	sto->stevedore = &sms_stevedore;
-	sto->magic = STORAGE_MAGIC;
-
-	VTAILQ_INSERT_TAIL(&obj->store, sto, list);
-	return (vsb);
-}
-
-void
-SMS_Finish(struct object *obj)
-{
-	struct storage *sto;
-	struct vsb *vsb;
-
-	CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
-	sto = VTAILQ_FIRST(&obj->store);
-	assert(sto->stevedore == &sms_stevedore);
-	vsb = sto->priv;
-	AZ(VSB_finish(vsb));
-
-	sto->ptr = (void*)VSB_data(vsb);
-	sto->len = VSB_len(vsb);
-	sto->space = VSB_len(vsb);
-	obj->len = sto->len;
-	Lck_Lock(&sms_mtx);
-	VSC_C_main->sms_nbytes += sto->len;
-	VSC_C_main->sms_balloc += sto->len;
-	Lck_Unlock(&sms_mtx);
-}
diff --git a/bin/varnishtest/tests/b00017.vtc b/bin/varnishtest/tests/b00017.vtc
index 633e6e1..0912e64 100644
--- a/bin/varnishtest/tests/b00017.vtc
+++ b/bin/varnishtest/tests/b00017.vtc
@@ -7,12 +7,18 @@ varnish v1 -vcl {
 	sub vcl_recv {
 		return (error(888));
 	}
+
+	sub vcl_error {
+		synthetic "Custom vcl_error's synth output";
+		return (deliver);
+	}
 } -start
 
 client c1 {
 	txreq -url "/"
 	rxresp
 	expect resp.status == 888
+	expect resp.bodylen == 31
 	expect resp.http.connection == close
 } -run
 
diff --git a/include/vrt.h b/include/vrt.h
index dc84852..8e5acba 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -222,7 +222,7 @@ void VRT_memmove(void *dst, const void *src, unsigned len);
 void VRT_Rollback(const struct vrt_ctx *);
 
 /* Synthetic pages */
-void VRT_synth_page(const struct vrt_ctx *, unsigned flags, const char *, ...);
+void VRT_synth_page(const struct vrt_ctx *, const char *, ...);
 
 /* Backend related */
 void VRT_init_dir(struct cli *, struct director **, int idx, const void *priv);
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 0026ad4..ff5f0f4 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -396,7 +396,7 @@ parse_synthetic(struct vcc *tl)
 {
 	vcc_NextToken(tl);
 
-	Fb(tl, 1, "VRT_synth_page(ctx, 0, ");
+	Fb(tl, 1, "VRT_synth_page(ctx, ");
 	vcc_Expr(tl, STRING_LIST);
 	ERRCHK(tl);
 	Fb(tl, 0, ");\n");



More information about the varnish-commit mailing list