Commit c6abb700 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Give sessions a backend connection instead of a backend and

have the directors provide that.

Entirely a no-op, apart from a bugfix that just would screw
you even more (than "totally") if socket(2) should ever fail.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3129 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 49c0f789
......@@ -354,7 +354,7 @@ struct sess {
VTAILQ_ENTRY(sess) list;
struct director *director;
struct backend *backend;
struct vbe_conn *vbe;
struct bereq *bereq;
struct object *obj;
struct objhead *objhead;
......@@ -397,9 +397,9 @@ extern int vca_pipes[2];
/* cache_backend.c */
struct vbe_conn *VBE_GetFd(struct sess *sp);
void VBE_ClosedFd(struct worker *w, struct vbe_conn *vc);
void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc);
void VBE_GetFd(struct sess *sp);
void VBE_ClosedFd(struct sess *sp);
void VBE_RecycleFd(struct sess *sp);
struct bereq * VBE_new_bereq(void);
void VBE_free_bereq(struct bereq *bereq);
void VBE_AddHostHeader(const struct sess *sp);
......
......@@ -66,9 +66,10 @@ VBE_AddHostHeader(const struct sess *sp)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->bereq, BEREQ_MAGIC);
CHECK_OBJ_NOTNULL(sp->bereq->http, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC);
http_PrintfHeader(sp->wrk, sp->fd, sp->bereq->http,
"Host: %s", sp->backend->hosthdr);
"Host: %s", sp->vbe->backend->hosthdr);
}
/*--------------------------------------------------------------------
......@@ -81,24 +82,21 @@ VBE_AddHostHeader(const struct sess *sp)
*/
static int
VBE_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa, socklen_t salen)
VBE_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa, socklen_t salen, const struct backend *bp)
{
int s, i, tmo;
char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
s = socket(pf, SOCK_STREAM, 0);
if (s < 0) {
LOCK(&sp->backend->mtx);
if (s < 0)
return (s);
}
tmo = params->connect_timeout;
if (sp->backend->connect_timeout > 10e-3)
tmo = (int)(sp->backend->connect_timeout * 1000);
if (bp->connect_timeout > 10e-3)
tmo = (int)(bp->connect_timeout * 1000);
if (tmo > 0)
i = TCP_connect(s, sa, salen, tmo);
......@@ -113,7 +111,7 @@ VBE_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa, socklen
TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
TCP_name(sa, salen, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s",
sp->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
bp->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
return (s);
}
......@@ -250,11 +248,11 @@ bes_conn_try(const struct sess *sp, struct backend *bp)
/* release lock during stuff that can take a long time */
if (params->prefer_ipv6 && bp->ipv6 != NULL)
s = VBE_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len);
s = VBE_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, bp);
if (s == -1 && bp->ipv4 != NULL)
s = VBE_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len);
s = VBE_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len, bp);
if (s == -1 && !params->prefer_ipv6 && bp->ipv6 != NULL)
s = VBE_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len);
s = VBE_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, bp);
if (s < 0) {
LOCK(&bp->mtx);
......@@ -269,20 +267,15 @@ bes_conn_try(const struct sess *sp, struct backend *bp)
* should contact.
*/
struct vbe_conn *
void
VBE_GetFd(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
if (sp->director->getfd != NULL)
return (sp->director->getfd(sp));
sp->backend = sp->director->choose(sp);
CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
return (VBE_GetVbe(sp));
AN (sp->director->getfd);
sp->vbe = sp->director->getfd(sp);
}
/*--------------------------------------------------------------------
......@@ -290,12 +283,11 @@ VBE_GetFd(struct sess *sp)
*/
struct vbe_conn *
VBE_GetVbe(const struct sess *sp)
VBE_GetVbe(struct sess *sp, struct backend *bp)
{
struct backend *bp;
struct vbe_conn *vc;
bp = sp->backend;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
/* first look for vbe_conn's we can recycle */
......@@ -317,7 +309,8 @@ VBE_GetVbe(const struct sess *sp)
VSL_stats->backend_conn++;
return (vc);
}
VBE_ClosedFd(sp->wrk, vc);
sp->vbe = vc;
VBE_ClosedFd(sp);
}
vc = VBE_NewConn();
......@@ -337,37 +330,41 @@ VBE_GetVbe(const struct sess *sp)
/* Close a connection ------------------------------------------------*/
void
VBE_ClosedFd(struct worker *w, struct vbe_conn *vc)
VBE_ClosedFd(struct sess *sp)
{
struct backend *b;
struct backend *bp;
CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
b = vc->backend;
assert(vc->fd >= 0);
WSL(w, SLT_BackendClose, vc->fd, "%s", vc->backend->vcl_name);
TCP_close(&vc->fd);
VBE_DropRef(vc->backend);
vc->backend = NULL;
VBE_ReleaseConn(vc);
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC);
assert(sp->vbe->fd >= 0);
bp = sp->vbe->backend;
WSL(sp->wrk, SLT_BackendClose, sp->vbe->fd, "%s", bp->vcl_name);
TCP_close(&sp->vbe->fd);
VBE_DropRef(bp);
sp->vbe->backend = NULL;
VBE_ReleaseConn(sp->vbe);
sp->vbe = NULL;
}
/* Recycle a connection ----------------------------------------------*/
void
VBE_RecycleFd(struct worker *w, struct vbe_conn *vc)
VBE_RecycleFd(struct sess *sp)
{
struct backend *bp;
CHECK_OBJ_NOTNULL(vc, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
assert(vc->fd >= 0);
bp = vc->backend;
WSL(w, SLT_BackendReuse, vc->fd, "%s", vc->backend->vcl_name);
LOCK(&vc->backend->mtx);
CHECK_OBJ_NOTNULL(sp->vbe, VBE_CONN_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbe->backend, BACKEND_MAGIC);
assert(sp->vbe->fd >= 0);
bp = sp->vbe->backend;
WSL(sp->wrk, SLT_BackendReuse, sp->vbe->fd, "%s", bp->vcl_name);
LOCK(&bp->mtx);
VSL_stats->backend_recycle++;
VTAILQ_INSERT_HEAD(&bp->connlist, vc, list);
VBE_DropRefLocked(vc->backend);
CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
VTAILQ_INSERT_HEAD(&bp->connlist, sp->vbe, list);
sp->vbe = NULL;
VBE_DropRefLocked(bp);
}
......@@ -78,14 +78,12 @@ struct vrt_backend_probe;
*/
typedef struct vbe_conn *vdi_getfd_f(struct sess *sp);
typedef struct backend *vdi_choose_f(struct sess *sp);
typedef void vdi_fini_f(struct director *d);
struct director {
unsigned magic;
#define DIRECTOR_MAGIC 0x3336351d
const char *name;
vdi_choose_f *choose;
vdi_getfd_f *getfd;
vdi_fini_f *fini;
void *priv;
......@@ -123,7 +121,7 @@ struct backend {
/* cache_backend.c */
void VBE_ReleaseConn(struct vbe_conn *vc);
struct vbe_conn *VBE_GetVbe(const struct sess *sp);
struct vbe_conn *VBE_GetVbe(struct sess *sp, struct backend *bp);
/* cache_backend_cfg.c */
extern MTX VBE_mtx;
......
......@@ -175,10 +175,6 @@ cnt_deliver(struct sess *sp)
sp->director = NULL;
sp->restarts = 0;
sp->backend = NULL; /*
* XXX: we may want to leave this
* behind to hint directors ?
*/
RES_WriteObj(sp);
HSH_Deref(sp->obj);
......@@ -209,13 +205,10 @@ cnt_done(struct sess *sp)
CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC);
AZ(sp->obj);
AZ(sp->vbe);
AZ(sp->bereq);
sp->director = NULL;
sp->restarts = 0;
sp->backend = NULL; /*
* XXX: we may want to leave this
* behind to hint directors ?
*/
if (sp->vcl != NULL && sp->esis == 0) {
if (sp->wrk->vcl != NULL)
......@@ -389,7 +382,9 @@ cnt_fetch(struct sess *sp)
AN(sp->bereq);
AN(sp->director);
AZ(sp->vbe);
i = Fetch(sp);
AZ(sp->vbe);
AN(sp->director);
if (i) {
......
......@@ -62,15 +62,15 @@ struct vdi_random {
};
/*lint -e{818} not const-able */
static struct backend *
vdi_random_choose(struct sess *sp)
static struct vbe_conn *
vdi_random_getfd(struct sess *sp)
{
int i;
struct vdi_random *vs;
uint32_t r;
struct vdi_random_host *vh;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_RANDOM_MAGIC);
r = random();
......@@ -78,7 +78,7 @@ vdi_random_choose(struct sess *sp)
for (i = 0, vh = vs->hosts; i < vs->nhosts; vh++)
if (r < vh->weight)
return (vh->backend);
return (VBE_GetVbe(sp, vh->backend));
assert(0 == __LINE__);
return (NULL);
}
......@@ -122,7 +122,7 @@ VRT_init_dir_random(struct cli *cli, struct director **bp, const struct vrt_dir_
vs->dir.magic = DIRECTOR_MAGIC;
vs->dir.priv = vs;
vs->dir.name = "random";
vs->dir.choose = vdi_random_choose;
vs->dir.getfd = vdi_random_getfd;
vs->dir.fini = vdi_random_fini;
s = 0;
......
......@@ -59,21 +59,20 @@ struct vdi_round_robin {
unsigned next_host;
};
/*lint -e{818} not const-able */
static struct backend *
vdi_round_robin_choose(struct sess *sp)
static struct vbe_conn *
vdi_round_robin_getfd(struct sess *sp)
{
struct vdi_round_robin *vs;
struct backend *backend;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_ROUND_ROBIN_MAGIC);
backend = vs->hosts[ vs->next_host ].backend;
vs->next_host = (vs->next_host + 1) % vs->nhosts;
return (backend);
return (VBE_GetVbe(sp, backend));
}
/*lint -e{818} not const-able */
......@@ -114,7 +113,7 @@ VRT_init_dir_round_robin(struct cli *cli, struct director **bp, const struct vrt
vs->dir.magic = DIRECTOR_MAGIC;
vs->dir.priv = vs;
vs->dir.name = "round_robin";
vs->dir.choose = vdi_round_robin_choose;
vs->dir.getfd = vdi_round_robin_getfd;
vs->dir.fini = vdi_round_robin_fini;
vh = vs->hosts;
......
......@@ -55,15 +55,15 @@ struct vdi_simple {
struct backend *backend;
};
/*lint -e{818} not const-able */
static struct backend *
vdi_simple_choose(struct sess *sp)
static struct vbe_conn *
vdi_simple_getfd(struct sess *sp)
{
struct vdi_simple *vs;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_SIMPLE_MAGIC);
return (vs->backend);
return (VBE_GetVbe(sp, vs->backend));
}
/*lint -e{818} not const-able */
......@@ -92,7 +92,7 @@ VRT_init_dir_simple(struct cli *cli, struct director **bp, const struct vrt_dir_
vs->dir.magic = DIRECTOR_MAGIC;
vs->dir.priv = vs;
vs->dir.name = "simple";
vs->dir.choose = vdi_simple_choose;
vs->dir.getfd = vdi_simple_getfd;
vs->dir.fini = vdi_simple_fini;
vs->backend = VBE_AddBackend(cli, t->host);
......
......@@ -332,9 +332,10 @@ Fetch(struct sess *sp)
/* Set up obj's workspace */
WS_Assert(sp->obj->ws_o);
vc = VBE_GetFd(sp);
if (vc == NULL)
VBE_GetFd(sp);
if (sp->vbe == NULL)
return (__LINE__);
vc = sp->vbe;
/*
* Now that we know our backend, we can set a default Host:
......@@ -351,12 +352,12 @@ Fetch(struct sess *sp)
/* Deal with any message-body the request might have */
i = FetchReqBody(sp);
if (i > 0) {
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
return (__LINE__);
}
if (WRK_Flush(w)) {
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
}
......@@ -370,13 +371,13 @@ Fetch(struct sess *sp)
while (i == 0);
if (i < 0) {
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
}
if (http_DissectResponse(sp->wrk, htc, hp)) {
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
/* XXX: other cleanup ? */
return (__LINE__);
}
......@@ -408,7 +409,7 @@ Fetch(struct sess *sp)
} else if (http_GetHdr(hp, H_Transfer_Encoding, &b)) {
/* XXX: AUGH! */
WSL(sp->wrk, SLT_Debug, vc->fd, "Invalid Transfer-Encoding");
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
return (__LINE__);
} else {
switch (http_GetStatus(hp)) {
......@@ -428,7 +429,7 @@ Fetch(struct sess *sp)
VTAILQ_REMOVE(&sp->obj->store, st, list);
STV_free(st);
}
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
sp->obj->len = 0;
return (__LINE__);
}
......@@ -451,9 +452,9 @@ Fetch(struct sess *sp)
cls = 1;
if (cls)
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
else
VBE_RecycleFd(sp->wrk, vc);
VBE_RecycleFd(sp);
return (0);
}
......
......@@ -83,10 +83,14 @@ pan_ws(const struct ws *ws, int indent)
/*--------------------------------------------------------------------*/
static void
pan_backend(const struct backend *be)
pan_vbe(const struct vbe_conn *vbe)
{
vsb_printf(vsp, " backend = %p {\n", be);
struct backend *be;
be = vbe->backend;
vsb_printf(vsp, " backend = %p fd = %d {\n", be, vbe->fd);
vsb_printf(vsp, " vcl_name = \"%s\",\n", be->vcl_name);
vsb_printf(vsp, " },\n");
}
......@@ -242,8 +246,8 @@ pan_sess(const struct sess *sp)
if (VALID_OBJ(sp->vcl, VCL_CONF_MAGIC))
pan_vcl(sp->vcl);
if (VALID_OBJ(sp->backend, BACKEND_MAGIC))
pan_backend(sp->backend);
if (VALID_OBJ(sp->vbe, BACKEND_MAGIC))
pan_vbe(sp->vbe);
if (VALID_OBJ(sp->obj, OBJECT_MAGIC))
pan_object(sp->obj);
......
......@@ -77,9 +77,10 @@ PipeSession(struct sess *sp)
bereq = sp->bereq;
sp->bereq = NULL;
vc = VBE_GetFd(sp);
if (vc == NULL)
VBE_GetFd(sp);
if (sp->vbe == NULL)
return;
vc = sp->vbe;
TCP_blocking(vc->fd);
WRK_Reset(w, &vc->fd);
......@@ -91,7 +92,7 @@ PipeSession(struct sess *sp)
if (WRK_Flush(w)) {
vca_close_session(sp, "pipe");
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
return;
}
......@@ -134,5 +135,5 @@ PipeSession(struct sess *sp)
(void)shutdown(vc->fd, SHUT_WR);
}
vca_close_session(sp, "pipe");
VBE_ClosedFd(sp->wrk, vc);
VBE_ClosedFd(sp);
}
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