[master] 63fcff3 Move the HTTP session steps into the HTTP1 session code, and have it contribute panic dumping methods

Poul-Henning Kamp phk at FreeBSD.org
Fri Feb 12 23:30:33 CET 2016


commit 63fcff379e2658d44e16bb12dd66104eb9e689aa
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Feb 12 20:15:37 2016 +0000

    Move the HTTP session steps into the HTTP1 session code, and have
    it contribute panic dumping methods

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index c1e29fa..2b8691a 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -625,31 +625,20 @@ enum sess_attr {
 	SA_LAST
 };
 
-enum sess_step {
-#define SESS_STEP(l, u)		S_STP_##u,
-#include "tbl/steps.h"
-#undef SESS_STEP
-};
-
 struct sess {
 	unsigned		magic;
 #define SESS_MAGIC		0x2c2f9c5a
 
-	enum sess_step		sess_step;
-	struct lock		mtx;
+	uint16_t		sattr[SA_LAST];
 	int			fd;
 	uint32_t		vxid;
 
-	/* Cross references ------------------------------------------*/
+	struct lock		mtx;
 
 	struct pool		*pool;
 
-	/* Session related fields ------------------------------------*/
-
 	struct ws		ws[1];
 
-	uint16_t		sattr[SA_LAST];
-
 	/* Timestamps, all on TIM_real() timescale */
 	double			t_open;		/* fd accepted */
 	double			t_idle;		/* fd accepted or resp sent */
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index c2f0db7..a890d6d 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -374,15 +374,25 @@ static void
 pan_req(struct vsb *vsb, const struct req *req)
 {
 	const char *stp;
+	const struct transport *xp;
 
 	VSB_printf(vsb, "req = %p {\n", req);
 	if (pan_already(vsb, req))
 		return;
 	VSB_indent(vsb, 2);
 
-	VSB_printf(vsb, "vxid = %u, transport = %s\n", VXID(req->vsl->wid),
-	    req->transport == NULL ? "NULL" : req->transport->name);
+	xp = req->transport;
+	VSB_printf(vsb, "vxid = %u, transport = %s", VXID(req->vsl->wid),
+	    xp == NULL ? "NULL" : xp->name);
 
+	if (xp != NULL && xp->req_panic != NULL) {
+		VSB_printf(vsb, " {\n");
+		VSB_indent(vsb, 2);
+		xp->req_panic(vsb, req);
+		VSB_indent(vsb, -2);
+		VSB_printf(vsb, "}");
+	}
+	VSB_printf(vsb, "\n");
 	switch (req->req_step) {
 #define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break;
 #include "tbl/steps.h"
@@ -442,7 +452,6 @@ pan_req(struct vsb *vsb, const struct req *req)
 static void
 pan_sess(struct vsb *vsb, const struct sess *sp)
 {
-	const char *stp;
 	const char *ci;
 	const char *cp;
 	const struct transport *xp;
@@ -452,22 +461,19 @@ pan_sess(struct vsb *vsb, const struct sess *sp)
 		return;
 	VSB_indent(vsb, 2);
 	xp = XPORT_ByNumber(sp->sattr[SA_TRANSPORT]);
-	VSB_printf(vsb, "fd = %d, vxid = %u, transport = %s\n",
+	VSB_printf(vsb, "fd = %d, vxid = %u, transport = %s",
 	    sp->fd, VXID(sp->vxid),
 	    xp == NULL ? "<none>" : xp->name);
+	if (xp != NULL && xp->sess_panic != NULL) {
+		VSB_printf(vsb, " {\n");
+		VSB_indent(vsb, 2);
+		xp->sess_panic(vsb, sp);
+		VSB_indent(vsb, -2);
+		VSB_printf(vsb, "}");
+	}
 	ci = SES_Get_String_Attr(sp, SA_CLIENT_IP);
 	cp = SES_Get_String_Attr(sp, SA_CLIENT_PORT);
-	VSB_printf(vsb, "client = %s %s,\n", ci, cp);
-	switch (sp->sess_step) {
-#define SESS_STEP(l, u) case S_STP_##u: stp = "S_STP_" #u; break;
-#include "tbl/steps.h"
-#undef SESS_STEP
-		default: stp = NULL;
-	}
-	if (stp != NULL)
-		VSB_printf(vsb, "step = %s,\n", stp);
-	else
-		VSB_printf(vsb, "step = 0x%x,\n", sp->sess_step);
+	VSB_printf(vsb, "\nclient = %s %s,\n", ci, cp);
 
 	VSB_indent(vsb, -2);
 	VSB_printf(vsb, "},\n");
diff --git a/bin/varnishd/cache/cache_transport.h b/bin/varnishd/cache/cache_transport.h
index 7048823..0af1a11 100644
--- a/bin/varnishd/cache/cache_transport.h
+++ b/bin/varnishd/cache/cache_transport.h
@@ -38,6 +38,8 @@ struct boc;
 
 typedef void vtr_deliver_f (struct req *, struct boc *, int sendbody);
 typedef void vtr_req_body_f (struct req *);
+typedef void vtr_sess_panic_f (struct vsb *, const struct sess *);
+typedef void vtr_req_panic_f (struct vsb *, const struct req *);
 
 struct transport {
 	unsigned			magic;
@@ -52,6 +54,8 @@ struct transport {
 
 	vtr_req_body_f			*req_body;
 	vtr_deliver_f			*deliver;
+	vtr_sess_panic_f		*sess_panic;
+	vtr_req_panic_f			*req_panic;
 
 	VTAILQ_ENTRY(transport)		list;
 };
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index faa1926..f30c3b0 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -43,8 +43,32 @@
 #include "cache_http1.h"
 #include "hash/hash_slinger.h"
 
+#include "vsb.h"
 #include "vtcp.h"
 
+static const char H1NEWREQ[] = "HTTP1::NewReq";
+static const char H1PROC[] = "HTTP1::Proc";
+static const char H1BUSY[] = "HTTP1::Busy";
+static const char H1CLEANUP[] = "HTTP1::Cleanup";
+
+static void
+http1_setstate(const struct sess *sp, const char *s)
+{
+	uintptr_t p;
+
+	p = (uintptr_t)s;
+	AZ(SES_Set_xport_priv(sp, &p));
+}
+
+static const char *
+http1_getstate(const struct sess *sp)
+{
+	uintptr_t *p;
+
+	AZ(SES_Get_xport_priv(sp, &p));
+	return (const char *)*p;
+}
+
 /*--------------------------------------------------------------------
  * Call protocol for this request
  */
@@ -81,13 +105,15 @@ http1_new_session(struct worker *wrk, void *arg)
 {
 	struct sess *sp;
 	struct req *req;
+	uintptr_t *u;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CAST_OBJ_NOTNULL(req, arg, REQ_MAGIC);
 	sp = req->sp;
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
-	sp->sess_step = S_STP_H1NEWREQ;
+	SES_Reserve_xport_priv(sp, &u);
+	http1_setstate(sp, H1NEWREQ);
 	wrk->task.func = http1_req;
 	wrk->task.priv = req;
 }
@@ -106,7 +132,7 @@ http1_unwait(struct worker *wrk, void *arg)
 	req->htc->fd = sp->fd;
 	SES_RxInit(req->htc, req->ws,
 	    cache_param->http_req_size, cache_param->http_req_hdr_len);
-	sp->sess_step = S_STP_H1NEWREQ;
+	http1_setstate(sp, H1NEWREQ);
 	wrk->task.func = http1_req;
 	wrk->task.priv = req;
 }
@@ -127,6 +153,20 @@ http1_req_body(struct req *req)
 	}
 }
 
+static void
+http1_sess_panic(struct vsb *vsb, const struct sess *sp)
+{
+
+	VSB_printf(vsb, "state = %s\n", http1_getstate(sp));
+}
+
+static void
+http1_req_panic(struct vsb *vsb, const struct req *req)
+{
+
+	VSB_printf(vsb, "state = %s\n", http1_getstate(req->sp));
+}
+
 struct transport HTTP1_transport = {
 	.name =			"HTTP/1",
 	.magic =		TRANSPORT_MAGIC,
@@ -134,6 +174,8 @@ struct transport HTTP1_transport = {
 	.unwait =		http1_unwait,
 	.req_body =		http1_req_body,
 	.new_session =		http1_new_session,
+	.sess_panic =		http1_sess_panic,
+	.req_panic =		http1_req_panic,
 };
 
 /*----------------------------------------------------------------------
@@ -247,6 +289,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 {
 	enum htc_status_e hs;
 	struct sess *sp;
+	const char *st;
 	int i;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -260,7 +303,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 	 * or waiter, but we'd rather do the syscall in the worker thread.
 	 * On systems which return errors for ioctl, we close early
 	 */
-	if (sp->sess_step == S_STP_H1NEWREQ && VTCP_blocking(sp->fd)) {
+	if (http1_getstate(sp) == H1NEWREQ && VTCP_blocking(sp->fd)) {
 		if (errno == ECONNRESET)
 			SES_Close(sp, SC_REM_CLOSE);
 		else
@@ -270,8 +313,8 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 	}
 
 	while (1) {
-		switch (sp->sess_step) {
-		case S_STP_H1NEWREQ:
+		st = http1_getstate(sp);
+		if (st == H1NEWREQ) {
 			assert(isnan(req->t_prev));
 			assert(isnan(req->t_req));
 			AZ(req->vcl);
@@ -318,13 +361,12 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 			    req->htc->rxbuf_e - req->htc->rxbuf_b;
 			if (i) {
 				SES_Close(req->sp, req->doclose);
-				sp->sess_step = S_STP_H1CLEANUP;
-				break;
+				http1_setstate(sp, H1CLEANUP);
+			} else {
+				req->req_step = R_STP_RECV;
+				http1_setstate(sp, H1PROC);
 			}
-			req->req_step = R_STP_RECV;
-			sp->sess_step = S_STP_H1PROC;
-			break;
-		case S_STP_H1BUSY:
+		} else if (st == H1BUSY) {
 			/*
 			 * Return from waitinglist.
 			 * Check to see if the remote has left.
@@ -337,30 +379,26 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 				AN(Req_Cleanup(sp, wrk, req));
 				return;
 			}
-			sp->sess_step = S_STP_H1PROC;
-			break;
-		case S_STP_H1PROC:
+			http1_setstate(sp, H1PROC);
+		} else if (st == H1PROC) {
 			req->transport = &HTTP1_transport;
 			if (CNT_Request(wrk, req) == REQ_FSM_DISEMBARK) {
 				req->task.func = http1_req;
 				req->task.priv = req;
-				sp->sess_step = S_STP_H1BUSY;
+				http1_setstate(sp, H1BUSY);
 				return;
 			}
 			req->transport = NULL;
-			sp->sess_step = S_STP_H1CLEANUP;
-			break;
-		case S_STP_H1CLEANUP:
+			http1_setstate(sp, H1CLEANUP);
+		} else if (st == H1CLEANUP) {
 			if (Req_Cleanup(sp, wrk, req))
 				return;
 			SES_RxReInit(req->htc);
 			if (req->htc->rxbuf_e != req->htc->rxbuf_b)
 				wrk->stats->sess_readahead++;
-			sp->sess_step = S_STP_H1NEWREQ;
-			break;
-		default:
+			http1_setstate(sp, H1NEWREQ);
+		} else {
 			WRONG("Wrong H1 session state");
 		}
-
 	}
 }
diff --git a/include/tbl/steps.h b/include/tbl/steps.h
index a2fd654..2d2bf66 100644
--- a/include/tbl/steps.h
+++ b/include/tbl/steps.h
@@ -30,13 +30,6 @@
 
 /*lint -save -e525 -e539 */
 
-#ifdef SESS_STEP
-SESS_STEP(h1newreq,	H1NEWREQ)
-SESS_STEP(h1proc,	H1PROC)
-SESS_STEP(h1busy,	H1BUSY)
-SESS_STEP(h1cleanup,	H1CLEANUP)
-#endif
-
 #ifdef REQ_STEP
 REQ_STEP(restart,	RESTART,	(wrk, req))
 REQ_STEP(recv,		RECV,		(wrk, req))



More information about the varnish-commit mailing list