Commit 3fd16639 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Now that things are properly prepared: Implement PRIV_SESS and PRIV_REQ

Note that each VMOD only gets one of each, so that the same 'vmod_priv'
will appear on all VMOD functions which use PRIV_REQ and similarly
only a single vmod_priv appear for all PRIV_SESS uses in that VMOD.

Feedback welcome.
parent 5aca8b44
......@@ -120,6 +120,7 @@ struct sess;
struct sesspool;
struct vbc;
struct vrt_backend;
struct vrt_privs;
struct vsb;
struct waitinglist;
struct worker;
......@@ -681,11 +682,12 @@ struct sess {
char *client_addr_str;
char *client_port_str;
/* Timestamps, all on TIM_real() timescale */
double t_open; /* fd accepted */
double t_idle; /* fd accepted or resp sent */
VTAILQ_HEAD(,vrt_privs) privs;
#if defined(HAVE_EPOLL_CTL)
struct epoll_event ev;
#endif
......@@ -1116,6 +1118,7 @@ const char *VCL_Method_Name(unsigned);
*/
const char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap);
void VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id);
void ESI_Deliver(struct req *);
void ESI_DeliverChild(struct req *);
......
......@@ -201,6 +201,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
req->vcl = NULL;
}
VRTPRIV_dynamic_kill(sp, (uintptr_t)req);
/* Charge and log byte counters */
AN(req->vsl->wid);
CNT_AcctLogCharge(wrk->stats, req);
......
......@@ -90,6 +90,7 @@ ses_new(struct sesspool *pp)
sp->t_open = NAN;
sp->t_idle = NAN;
VTAILQ_INIT(&sp->privs);
Lck_New(&sp->mtx, lck_sess);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp);
......@@ -302,6 +303,7 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now)
now = VTIM_real();
AZ(isnan(sp->t_open));
VRTPRIV_dynamic_kill(sp, 0);
VSL(SLT_SessClose, sp->vxid, "%s %.3f",
sess_close_2str(sp->reason, 0), now - sp->t_open);
VSL(SLT_End, sp->vxid, "%s", "");
......
......@@ -37,20 +37,78 @@
#include "cache.h"
#include "cache_backend.h"
#include "hash/hash_slinger.h"
#include "vav.h"
#include "vcl.h"
#include "vrt.h"
#include "vrt_obj.h"
#include "vtcp.h"
#include "vtim.h"
struct vrt_privs {
unsigned magic;
#define VRT_PRIVS_MAGIC 0x24157a52
VTAILQ_ENTRY(vrt_privs) list;
struct vmod_priv priv[1];
const struct VCL_conf *vcl;
uintptr_t id;
};
/*--------------------------------------------------------------------
*/
static struct vmod_priv *
VRT_priv_dynamic(VRT_CTX, uintptr_t id)
{
struct vrt_privs *vps;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
VTAILQ_FOREACH(vps, &ctx->req->sp->privs, list) {
CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC);
if (vps->vcl == ctx->vcl && vps->id == id)
return (vps->priv);
}
ALLOC_OBJ(vps, VRT_PRIVS_MAGIC);
AN(vps);
vps->vcl = ctx->vcl;
vps->id = id;
VTAILQ_INSERT_TAIL(&ctx->req->sp->privs, vps, list);
return (vps->priv);
}
void
VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id)
{
struct vrt_privs *vps, *vps1;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
VTAILQ_FOREACH_SAFE(vps, &sp->privs, list, vps1) {
CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC);
if (id == vps->id) {
VTAILQ_REMOVE(&sp->privs, vps, list);
VRT_priv_fini(vps->priv);
FREE_OBJ(vps);
}
}
if (id == 0)
assert(VTAILQ_EMPTY(&sp->privs));
}
struct vmod_priv *
VRT_priv_req(VRT_CTX)
{
return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req));
}
struct vmod_priv *
VRT_priv_sess(VRT_CTX)
{
return (VRT_priv_dynamic(ctx, (uintptr_t)NULL));
}
/*--------------------------------------------------------------------
*/
void
VRT_priv_fini(const struct vmod_priv *p)
{
if (p->priv != (void*)0 && p->free != (void*)0)
p->free(p->priv);
}
......
varnishtest "Test priv_sess and priv_req"
server s1 {
rxreq
txresp
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import ${vmod_debug};
sub vcl_recv {
set req.http.x0 = debug.test_priv_req(req.url);
set req.http.y0 = debug.test_priv_sess(req.url);
}
sub vcl_deliver {
set resp.http.x0 = req.http.x0;
set resp.http.x1 = debug.test_priv_req("");
set resp.http.y0 = req.http.y0;
set resp.http.y1 = debug.test_priv_sess("");
}
} -start
client c1 {
txreq -url /foobar
rxresp
expect resp.http.x0 == /foobar
expect resp.http.x1 == /foobar
expect resp.http.y0 == /foobar
expect resp.http.y1 == /foobar
txreq -url /snafu
rxresp
expect resp.http.x0 == /snafu
expect resp.http.x1 == /snafu
expect resp.http.y0 == /foobar
expect resp.http.y1 == /foobar
} -run
......@@ -246,6 +246,8 @@ struct vmod_priv {
typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *);
void VRT_priv_fini(const struct vmod_priv *p);
struct vmod_priv *VRT_priv_sess(VRT_CTX);
struct vmod_priv *VRT_priv_req(VRT_CTX);
/* Stevedore related functions */
int VRT_Stv(const char *nm);
......
......@@ -566,6 +566,12 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
VSB_printf(ifp->fin, "\tVRT_priv_fini(&%s);", buf);
e2 = vcc_mk_expr(VOID, "&%s", buf);
p += strlen(p) + 1;
} else if (fmt == VOID && !strcmp(p, "PRIV_REQ")) {
e2 = vcc_mk_expr(VOID, "VRT_priv_req(ctx)");
p += strlen(p) + 1;
} else if (fmt == VOID && !strcmp(p, "PRIV_SESS")) {
e2 = vcc_mk_expr(VOID, "VRT_priv_sess(ctx)");
p += strlen(p) + 1;
} else if (fmt == ENUM) {
ExpectErr(tl, ID);
ERRCHK(tl);
......
......@@ -58,6 +58,8 @@ ctypes = {
'IP': "VCL_IP",
'PRIV_CALL': "struct vmod_priv *",
'PRIV_VCL': "struct vmod_priv *",
'PRIV_SESS': "struct vmod_priv *",
'PRIV_REQ': "struct vmod_priv *",
'REAL': "VCL_REAL",
'STRING': "VCL_STRING",
'STRING_LIST': "const char *, ...",
......
......@@ -51,6 +51,14 @@ $Function VOID test_priv_vcl(PRIV_VCL)
Test function for VCL private pointers
$Function STRING test_priv_req(PRIV_REQ, STRING)
Test function for REQ private pointers
$Function STRING test_priv_sess(PRIV_SESS, STRING)
Test function for SESS private pointers
$Function BLOB str2blob(STRING src)
Turn a string into a blob
......
......@@ -88,6 +88,30 @@ vmod_test_priv_call(VRT_CTX, struct vmod_priv *priv)
}
}
VCL_STRING __match_proto__(td_debug_test_priv_sess)
vmod_test_priv_sess(VRT_CTX, struct vmod_priv *priv, VCL_STRING s)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (priv->priv == NULL) {
priv->priv = strdup(s);
priv->free = free;
}
return (priv->priv);
}
VCL_STRING __match_proto__(td_debug_test_priv_req)
vmod_test_priv_req(VRT_CTX, struct vmod_priv *priv, VCL_STRING s)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (priv->priv == NULL) {
priv->priv = strdup(s);
priv->free = free;
}
return (priv->priv);
}
VCL_VOID __match_proto__(td_debug_test_priv_vcl)
vmod_test_priv_vcl(VRT_CTX, struct vmod_priv *priv)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment