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

Continue the rototilling of the backend code to fit the finally

decided naming/identity scheme.

Now I just need to get probing working again, will say when it works,
right now s00002.vtc plus likely others fail.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5092 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 289b97f3
......@@ -453,6 +453,7 @@ struct vbc {
#define VBC_MAGIC 0x0c5e6592
VTAILQ_ENTRY(vbc) list;
struct backend *backend;
struct vdi_simple *vdis;
int fd;
/* Timeouts */
......@@ -472,6 +473,7 @@ const char *VCA_waiter_name(void);
extern pthread_t VCA_thread;
/* cache_backend.c */
void VBE_UseHealth(struct director *vdi);
struct vbc *VDI_GetFd(const struct director *, struct sess *sp);
int VDI_Healthy(double now, const struct director *, uintptr_t target);
......
......@@ -48,11 +48,42 @@ SVNID("$Id$")
#include "cache_backend.h"
#include "vrt.h"
/*--------------------------------------------------------------------
* The "simple" director really isn't, since thats where all the actual
* connections happen. Nontheless, pretend it is simple by sequestering
* the directoricity of it under this line.
*/
struct vdi_simple {
unsigned magic;
#define VDI_SIMPLE_MAGIC 0x476d25b7
struct director dir;
struct backend *backend;
const struct vrt_backend *vrt;
};
/*
* List of cached vbcs, used if enabled in params/heritage
*/
static VTAILQ_HEAD(,vbc) vbcs = VTAILQ_HEAD_INITIALIZER(vbcs);
/*--------------------------------------------------------------------
* Create default Host: header for backend request
*/
void
VDI_AddHostHeader(const struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbc->vdis, VDI_SIMPLE_MAGIC);
http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq,
"Host: %s", sp->vbc->vdis->vrt->hosthdr);
}
/*--------------------------------------------------------------------*/
/* Private interface from backend_cfg.c */
void
......@@ -85,7 +116,6 @@ VBE_ReleaseConn(struct vbc *vc)
dst = params->tmx; \
} while (0)
/*--------------------------------------------------------------------
* Attempt to connect to a given addrinfo entry.
*
......@@ -97,7 +127,7 @@ VBE_ReleaseConn(struct vbc *vc)
static int
vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa,
socklen_t salen, const struct backend *bp)
socklen_t salen, struct vdi_simple *vs)
{
int s, i, tmo;
double tmod;
......@@ -105,12 +135,13 @@ vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa,
char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
s = socket(pf, SOCK_STREAM, 0);
if (s < 0)
return (s);
FIND_TMO(connect_timeout, tmod, sp, bp);
FIND_TMO(connect_timeout, tmod, sp, vs->vrt);
tmo = (int)(tmod * 1000.0);
......@@ -127,7 +158,7 @@ vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa,
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",
bp->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
vs->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
return (s);
}
......@@ -135,9 +166,12 @@ vbe_TryConnect(const struct sess *sp, int pf, const struct sockaddr *sa,
/*--------------------------------------------------------------------*/
static int
bes_conn_try(const struct sess *sp, struct backend *bp)
bes_conn_try(const struct sess *sp, struct vdi_simple *vs)
{
int s;
struct backend *bp = vs->backend;
CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
Lck_Lock(&bp->mtx);
bp->refcount++;
......@@ -150,11 +184,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, bp);
s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, vs);
if (s == -1 && bp->ipv4 != NULL)
s = vbe_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len, bp);
s = vbe_TryConnect(sp, PF_INET, bp->ipv4, bp->ipv4len, vs);
if (s == -1 && !params->prefer_ipv6 && bp->ipv6 != NULL)
s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, bp);
s = vbe_TryConnect(sp, PF_INET6, bp->ipv6, bp->ipv6len, vs);
if (s < 0) {
Lck_Lock(&bp->mtx);
......@@ -215,7 +249,6 @@ vbe_NewConn(void)
return (vc);
}
/*--------------------------------------------------------------------
* It evaluates if a backend is healthy _for_a_specific_object_.
* That means that it relies on sp->objhead. This is mainly for saint-mode,
......@@ -228,7 +261,7 @@ vbe_NewConn(void)
*/
static unsigned int
vbe_Healthy(double now, uintptr_t target, struct backend *backend)
vbe_Healthy(double now, uintptr_t target, struct vdi_simple *vs, struct backend *backend)
{
struct trouble *tr;
struct trouble *tr2;
......@@ -236,6 +269,7 @@ vbe_Healthy(double now, uintptr_t target, struct backend *backend)
unsigned i = 0, retval;
unsigned int threshold;
CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC);
if (!backend->healthy)
......@@ -244,10 +278,10 @@ vbe_Healthy(double now, uintptr_t target, struct backend *backend)
/* VRT/VCC sets threshold to UINT_MAX to mark that it's not
* specified by VCL (thus use param).
*/
if (backend->saintmode_threshold == UINT_MAX)
if (vs->vrt->saintmode_threshold == UINT_MAX)
threshold = params->saintmode_threshold;
else
threshold = backend->saintmode_threshold;
threshold = vs->vrt->saintmode_threshold;
/* Saintmode is disabled */
if (threshold == 0)
......@@ -299,11 +333,14 @@ vbe_Healthy(double now, uintptr_t target, struct backend *backend)
*/
static struct vbc *
vbe_GetVbe(struct sess *sp, struct backend *bp)
vbe_GetVbe(struct sess *sp, struct vdi_simple *vs)
{
struct vbc *vc;
struct backend *bp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(vs, VDI_SIMPLE_MAGIC);
bp = vs->backend;
CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
/* first look for vbc's we can recycle */
......@@ -324,6 +361,7 @@ vbe_GetVbe(struct sess *sp, struct backend *bp)
VSC_main->backend_reuse += 1;
WSP(sp, SLT_Backend, "%d %s %s",
vc->fd, sp->director->vcl_name, bp->vcl_name);
vc->vdis = vs;
return (vc);
}
VSC_main->backend_toolate++;
......@@ -331,12 +369,13 @@ vbe_GetVbe(struct sess *sp, struct backend *bp)
VDI_CloseFd(sp);
}
if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) {
if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, vs, bp)) {
VSC_main->backend_unhealthy++;
return (NULL);
}
if (bp->max_conn > 0 && bp->n_conn >= bp->max_conn) {
if (vs->vrt->max_connections > 0 &&
bp->n_conn >= vs->vrt->max_connections) {
VSC_main->backend_busy++;
return (NULL);
}
......@@ -344,7 +383,7 @@ vbe_GetVbe(struct sess *sp, struct backend *bp)
vc = vbe_NewConn();
assert(vc->fd == -1);
AZ(vc->backend);
vc->fd = bes_conn_try(sp, bp);
vc->fd = bes_conn_try(sp, vs);
if (vc->fd < 0) {
VBE_ReleaseConn(vc);
VSC_main->backend_fail++;
......@@ -354,27 +393,17 @@ vbe_GetVbe(struct sess *sp, struct backend *bp)
VSC_main->backend_conn++;
WSP(sp, SLT_Backend, "%d %s %s",
vc->fd, sp->director->vcl_name, bp->vcl_name);
vc->vdis = vs;
return (vc);
}
/*--------------------------------------------------------------------
* The "simple" director really isn't, since thats where all the actual
* connections happen. Nontheless, pretend it is simple by sequestering
* the directoricity of it under this line.
*/
struct vdi_simple {
unsigned magic;
#define VDI_SIMPLE_MAGIC 0x476d25b7
struct director dir;
struct backend *backend;
};
/* Returns the backend if and only if the this is a simple director.
* Returns the backend if and only if the this is a simple director.
* XXX: Needs a better name and possibly needs a better general approach.
* XXX: This is mainly used by the DNS director to fetch the actual backend
* XXX: so it can compare DNS lookups with the actual IP.
*/
struct backend *
vdi_get_backend_if_simple(const struct director *d)
{
......@@ -385,9 +414,33 @@ vdi_get_backend_if_simple(const struct director *d)
if (vs2->magic != VDI_SIMPLE_MAGIC)
return NULL;
CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
return vs->backend;
return (vs->backend);
}
/*--------------------------------------------------------------------
*
*/
void
VBE_UseHealth(struct director *vdi)
{
struct vdi_simple *vs;
ASSERT_CLI();
if (strcmp(vdi->name, "simple"))
return;
printf("USE HEALTH %p\n", vdi);
CAST_OBJ_NOTNULL(vs, vdi->priv, VDI_SIMPLE_MAGIC);
if (vs->vrt->probe == NULL)
return;
VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr);
}
/*--------------------------------------------------------------------
*
*/
static struct vbc *
vdi_simple_getfd(const struct director *d, struct sess *sp)
{
......@@ -397,12 +450,12 @@ vdi_simple_getfd(const struct director *d, struct sess *sp)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
vc = vbe_GetVbe(sp, vs->backend);
vc = vbe_GetVbe(sp, vs);
if (vc != NULL) {
FIND_TMO(first_byte_timeout,
vc->first_byte_timeout, sp, vc->backend);
vc->first_byte_timeout, sp, vs->vrt);
FIND_TMO(between_bytes_timeout,
vc->between_bytes_timeout, sp, vc->backend);
vc->between_bytes_timeout, sp, vs->vrt);
}
return (vc);
}
......@@ -414,7 +467,7 @@ vdi_simple_healthy(double now, const struct director *d, uintptr_t target)
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
return (vbe_Healthy(now, target, vs->backend));
return (vbe_Healthy(now, target, vs, vs->backend));
}
/*lint -e{818} not const-able */
......@@ -426,8 +479,8 @@ vdi_simple_fini(struct director *d)
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);
VBP_Stop(vs->backend, vs->vrt->probe);
VBE_DropRef(vs->backend);
// vbe_stat_deref(vs->dir.vcl_name);
free(vs->dir.vcl_name);
vs->dir.magic = 0;
FREE_OBJ(vs);
......@@ -454,7 +507,11 @@ VRT_init_dir_simple(struct cli *cli, struct director **bp, int idx,
vs->dir.fini = vdi_simple_fini;
vs->dir.healthy = vdi_simple_healthy;
vs->vrt = t;
vs->backend = VBE_AddBackend(cli, t);
if (vs->backend->probe == NULL)
VBP_Start(vs->backend, vs->vrt->probe, vs->vrt->hosthdr);
bp[idx] = &vs->dir;
}
......@@ -117,7 +117,6 @@ struct backend {
int refcount;
struct lock mtx;
char *hosthdr;
char *vcl_name;
char *ipv4_addr;
char *ipv6_addr;
......@@ -136,12 +135,6 @@ struct backend {
VTAILQ_HEAD(, trouble) troublelist;
struct vsc_vbe *vsc;
double connect_timeout;
double first_byte_timeout;
double between_bytes_timeout;
unsigned max_conn;
unsigned saintmode_threshold;
};
/* cache_backend.c */
......@@ -155,9 +148,8 @@ void VBE_DropRef(struct backend *);
void VBE_DropRefLocked(struct backend *b);
/* cache_backend_poll.c */
void VBP_Start(struct backend *b, struct vrt_backend_probe const *p);
void VBP_Stop(struct backend *b);
void VBP_Start(struct backend *b, struct vrt_backend_probe const *p, const char *hosthdr);
void VBP_Stop(struct backend *b, struct vrt_backend_probe const *p);
/* Init functions for directors */
typedef void dir_init_f(struct cli *, struct director **, int , const void*);
......
......@@ -56,7 +56,6 @@ struct lock VBE_mtx;
*/
static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends);
/*--------------------------------------------------------------------
*/
......@@ -66,7 +65,6 @@ VBE_Nuke(struct backend *b)
ASSERT_CLI();
VTAILQ_REMOVE(&backends, b, list);
free(b->hosthdr);
free(b->ipv4);
free(b->ipv4_addr);
free(b->ipv6);
......@@ -122,10 +120,7 @@ VBE_DropRefLocked(struct backend *b)
vbe->backend = NULL;
VBE_ReleaseConn(vbe);
}
if (b->probe != NULL)
VBP_Stop(b);
else
VBE_Nuke(b);
VBE_Nuke(b);
}
void
......@@ -222,13 +217,6 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
REPLACE(b->ipv4_addr, vb->ipv4_addr);
REPLACE(b->ipv6_addr, vb->ipv6_addr);
REPLACE(b->port, vb->port);
REPLACE(b->hosthdr, vb->hosthdr);
b->connect_timeout = vb->connect_timeout;
b->first_byte_timeout = vb->first_byte_timeout;
b->between_bytes_timeout = vb->between_bytes_timeout;
b->max_conn = vb->max_connections;
b->saintmode_threshold = vb->saintmode_threshold;
/*
* Copy over the sockaddrs
......@@ -240,13 +228,13 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
assert(b->ipv4 != NULL || b->ipv6 != NULL);
VBP_Start(b, vb->probe);
b->healthy = 1;
VTAILQ_INSERT_TAIL(&backends, b, list);
VSC_main->n_backend++;
return (b);
}
/*--------------------------------------------------------------------*/
void
......@@ -293,10 +281,9 @@ cli_debug_backend(struct cli *cli, const char * const *av, void *priv)
ASSERT_CLI();
VTAILQ_FOREACH(b, &backends, list) {
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
cli_out(cli, "%p %s(%s,%s,:%s) %d %d/%d\n",
cli_out(cli, "%p %s(%s,%s,:%s) %d %d\n",
b, b->vcl_name, b->ipv4_addr, b->ipv6_addr, b->port,
b->refcount,
b->n_conn, b->max_conn);
b->refcount, b->n_conn);
}
}
......
......@@ -57,11 +57,23 @@ SVNID("$Id$")
/* Default averaging rate, we want something pretty responsive */
#define AVG_RATE 4
struct vbp_vcl {
unsigned magic;
#define VBP_VCL_MAGIC 0x70829764
VTAILQ_ENTRY(vbp_vcl) list;
const struct vrt_backend_probe *probe;
const char *hosthdr;
};
struct vbp_target {
unsigned magic;
#define VBP_TARGET_MAGIC 0x6b7cb656
struct backend *backend;
VTAILQ_HEAD( ,vbp_vcl) vcls;
const struct vrt_backend_probe *probe_cache;
struct vrt_backend_probe probe;
int stop;
char *req;
......@@ -86,6 +98,8 @@ struct vbp_target {
static VTAILQ_HEAD(, vbp_target) vbp_list =
VTAILQ_HEAD_INITIALIZER(vbp_list);
static struct lock vbp_mtx;
static const char default_request[] =
"GET / HTTP/1.1\r\n"
"Connection: close\r\n"
......@@ -413,26 +427,50 @@ static struct cli_proto debug_cmds[] = {
};
/*--------------------------------------------------------------------
* Start/Stop called from cache_backend_cfg.c
* Start/Stop called from cache_backend.c
*/
void
VBP_Start(struct backend *b, struct vrt_backend_probe const *p)
VBP_Start(struct backend *b, const struct vrt_backend_probe *p, const char *hosthdr)
{
struct vbp_target *vt;
struct vsb *vsb;
struct vbp_vcl *vcl;
int startthread = 0;
ASSERT_CLI();
if (p == NULL) {
b->healthy = 1;
if (p == NULL)
return;
Lck_Lock(&vbp_mtx);
if (b->probe == NULL) {
ALLOC_OBJ(vt, VBP_TARGET_MAGIC);
XXXAN(vt);
VTAILQ_INIT(&vt->vcls);
vt->backend = b;
startthread = 1;
VTAILQ_INSERT_TAIL(&vbp_list, vt, list);
} else {
vt = b->probe;
}
VTAILQ_FOREACH(vcl, &vt->vcls, list)
if (vcl->probe == p)
break;
if (vcl == NULL) {
ALLOC_OBJ(vcl, VBP_VCL_MAGIC);
XXXAN(vcl);
vcl->probe = p;
vcl->hosthdr = hosthdr;
VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list);
} else {
VTAILQ_REMOVE(&vt->vcls, vcl, list);
VTAILQ_INSERT_HEAD(&vt->vcls, vcl, list);
}
ALLOC_OBJ(vt, VBP_TARGET_MAGIC);
AN(vt);
vt->backend = b;
vt->probe = *p;
vt->probe = *vcl->probe;
p = &vt->probe;
......@@ -443,8 +481,8 @@ VBP_Start(struct backend *b, struct vrt_backend_probe const *p)
XXXAN(vsb);
vsb_printf(vsb, "GET %s HTTP/1.1\r\n",
p->url != NULL ? p->url : "/");
if (b->hosthdr != NULL)
vsb_printf(vsb, "Host: %s\r\n", b->hosthdr);
if (hosthdr != NULL)
vsb_printf(vsb, "Host: %s\r\n", hosthdr);
vsb_printf(vsb, "Connection: close\r\n");
vsb_printf(vsb, "\r\n");
vsb_finish(vsb);
......@@ -455,25 +493,48 @@ VBP_Start(struct backend *b, struct vrt_backend_probe const *p)
}
vt->req_len = strlen(vt->req);
b->probe = vt;
VTAILQ_INSERT_TAIL(&vbp_list, vt, list);
AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt));
Lck_Unlock(&vbp_mtx);
if (startthread)
AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt));
}
void
VBP_Stop(struct backend *b)
VBP_Stop(struct backend *b, struct vrt_backend_probe const *p)
{
struct vbp_target *vt;
struct vbp_vcl *vcl;
void *ret;
int first;
ASSERT_CLI();
if (p == NULL)
return;
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
ASSERT_CLI();
if (b->probe == NULL)
Lck_Lock(&vbp_mtx);
AN(b->probe);
vt = b->probe;
VTAILQ_FOREACH(vcl, &vt->vcls, list)
if (vcl->probe == p)
break;
AN(vcl);
first = (vcl == VTAILQ_FIRST(&vt->vcls));
VTAILQ_REMOVE(&vt->vcls, vcl, list);
Lck_Unlock(&vbp_mtx);
FREE_OBJ(vcl);
if (!first)
return;
vcl = VTAILQ_FIRST(&vt->vcls);
if (vcl != NULL) {
VBP_Start(b, vcl->probe, vcl->hosthdr);
return;
CHECK_OBJ_NOTNULL(b->probe, VBP_TARGET_MAGIC);
}
/* No more polling for this backend */
vt = b->probe;
vt->stop = 1;
......@@ -493,5 +554,6 @@ void
VBP_Init(void)
{
Lck_New(&vbp_mtx);
CLI_AddFuncs(debug_cmds);
}
......@@ -38,21 +38,6 @@ SVNID("$Id: cache_backend.c 5089 2010-08-11 12:12:47Z phk $")
#include "cache.h"
#include "cache_backend.h"
/*--------------------------------------------------------------------
* Create default Host: header for backend request
*/
void
VDI_AddHostHeader(const struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->wrk->bereq, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbc, VBC_MAGIC);
CHECK_OBJ_NOTNULL(sp->vbc->backend, BACKEND_MAGIC);
http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq,
"Host: %s", sp->vbc->backend->hosthdr);
}
/* Close a connection ------------------------------------------------*/
void
......
......@@ -290,6 +290,7 @@ static void
ccf_config_use(struct cli *cli, const char * const *av, void *priv)
{
struct vcls *vcl;
int i;
(void)av;
(void)priv;
......@@ -302,6 +303,10 @@ ccf_config_use(struct cli *cli, const char * const *av, void *priv)
Lck_Lock(&vcl_mtx);
vcl_active = vcl;
Lck_Unlock(&vcl_mtx);
/* Tickle this VCL's backends to take over health polling */
for(i = 1; i < vcl->conf->ndirector; i++)
VBE_UseHealth(vcl->conf->director[i]);
}
/*--------------------------------------------------------------------*/
......
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