Commit 93a85f58 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Rip out all the old backend refcounting code, and make backends

unique objects for each VCL which instantiate them.  (Instead we
share TCP connection pools, which are a lot simpler)

Spotted one utterly trivial memory leak along the way.
parent 36684de4
......@@ -175,15 +175,18 @@ vbe_dir_finish(const struct director *d, struct worker *wrk,
VSLb(bo->vsl, SLT_BackendClose, "%d %s", bo->htc->vbc->fd,
bp->display_name);
VBT_Close(bp->tcp_pool, &bo->htc->vbc);
VBE_DropRefConn(bp, &bo->acct);
Lck_Lock(&bp->mtx);
} else {
VSLb(bo->vsl, SLT_BackendReuse, "%d %s", bo->htc->vbc->fd,
bp->display_name);
Lck_Lock(&bp->mtx);
VSC_C_main->backend_recycle++;
VBT_Recycle(bp->tcp_pool, &bo->htc->vbc);
VBE_DropRefLocked(bp, &bo->acct);
}
#define ACCT(foo) bp->vsc->foo += bo->acct.foo;
#include "tbl/acct_fields_bereq.h"
#undef ACCT
Lck_Unlock(&bp->mtx);
bo->htc->vbc = NULL;
bo->htc = NULL;
}
......@@ -356,7 +359,7 @@ VRT_fini_vbe(VRT_CTX, struct director **dp, const struct vrt_backend *vrt)
if (vrt->probe != NULL)
VBP_Remove(be, vrt->probe);
VBE_DropRefVcl(be);
VBE_Drop(be);
free(d->vcl_name);
FREE_OBJ(d);
}
......@@ -61,11 +61,11 @@ struct backend {
int refcount;
struct lock mtx;
char *vcl_name;
const char *vcl_name;
char *display_name;
char *ipv4_addr;
char *ipv6_addr;
char *port;
const char *ipv4_addr;
const char *ipv6_addr;
const char *port;
struct suckaddr *ipv4;
struct suckaddr *ipv6;
......@@ -104,12 +104,9 @@ struct vbc {
};
/* cache_backend_cfg.c */
void VBE_DropRefConn(struct backend *, const struct acct_bereq *);
void VBE_DropRefVcl(struct backend *);
void VBE_DropRefLocked(struct backend *b, const struct acct_bereq *);
void VBE_Drop(struct backend *);
unsigned VBE_Healthy(const struct backend *b, double *changed);
struct backend *VBE_AddBackend(const struct vrt_backend *vb);
void VBE_Poll(void);
/* cache_backend_poll.c */
void VBP_Insert(struct backend *b, struct vrt_backend_probe const *p,
......
......@@ -54,97 +54,24 @@ static VTAILQ_HEAD(, backend) backends = VTAILQ_HEAD_INITIALIZER(backends);
/*--------------------------------------------------------------------
*/
static void
VBE_Nuke(struct backend *b)
void
VBE_Drop(struct backend *b)
{
ASSERT_CLI();
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
b->vsc->vcls--;
VTAILQ_REMOVE(&backends, b, list);
free(b->ipv4);
free(b->ipv4_addr);
free(b->ipv6);
free(b->ipv6_addr);
free(b->port);
free(b->display_name);
VSM_Free(b->vsc);
VBT_Rel(&b->tcp_pool);
FREE_OBJ(b);
VSC_C_main->n_backend--;
}
/*--------------------------------------------------------------------
*/
void
VBE_Poll(void)
{
struct backend *b, *b2;
ASSERT_CLI();
VTAILQ_FOREACH_SAFE(b, &backends, list, b2) {
assert(
b->admin_health == ah_healthy ||
b->admin_health == ah_sick ||
b->admin_health == ah_probe
);
if (b->refcount == 0 && b->probe == NULL)
VBE_Nuke(b);
}
}
/*--------------------------------------------------------------------
* Drop a reference to a backend.
* The last reference must come from the watcher in the CLI thread,
* as only that thread is allowed to clean up the backend list.
*/
void
VBE_DropRefLocked(struct backend *b, const struct acct_bereq *acct_bereq)
{
int i;
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
assert(b->refcount > 0);
if (acct_bereq != NULL) {
#define ACCT(foo) \
b->vsc->foo += acct_bereq->foo;
#include "tbl/acct_fields_bereq.h"
#undef ACCT
}
i = --b->refcount;
Lck_Unlock(&b->mtx);
if (i > 0)
return;
ASSERT_CLI();
VBE_Nuke(b);
}
void
VBE_DropRefVcl(struct backend *b)
{
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
Lck_Lock(&b->mtx);
b->vsc->vcls--;
VBE_DropRefLocked(b, NULL);
}
void
VBE_DropRefConn(struct backend *b, const struct acct_bereq *acct_bereq)
{
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
Lck_Lock(&b->mtx);
assert(b->n_conn > 0);
b->n_conn--;
b->vsc->conn--;
VBE_DropRefLocked(b, acct_bereq);
}
/*--------------------------------------------------------------------
* Add a backend/director instance when loading a VCL.
* If an existing backend is matched, grab a refcount and return.
......@@ -161,27 +88,10 @@ VBE_AddBackend(const struct vrt_backend *vb)
AN(vb->vcl_name);
assert(vb->ipv4_suckaddr != NULL || vb->ipv6_suckaddr != NULL);
/* Run through the list and see if we already have this backend */
VTAILQ_FOREACH(b, &backends, list) {
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
if (strcmp(b->vcl_name, vb->vcl_name))
continue;
if (vb->ipv4_suckaddr != NULL &&
VSA_Compare(b->ipv4, vb->ipv4_suckaddr))
continue;
if (vb->ipv6_suckaddr != NULL &&
VSA_Compare(b->ipv6, vb->ipv6_suckaddr))
continue;
b->refcount++;
b->vsc->vcls++;
return (b);
}
/* Create new backend */
ALLOC_OBJ(b, BACKEND_MAGIC);
XXXAN(b);
Lck_New(&b->mtx, lck_backend);
b->refcount = 1;
bprintf(buf, "%s(%s,%s,%s)",
vb->vcl_name,
......@@ -191,16 +101,11 @@ VBE_AddBackend(const struct vrt_backend *vb)
b->vsc = VSM_Alloc(sizeof *b->vsc, VSC_CLASS, VSC_type_vbe, buf);
b->vsc->vcls++;
/*
* This backend may live longer than the VCL that instantiated it
* so we cannot simply reference the VCL's copy of things.
*/
REPLACE(b->vcl_name, vb->vcl_name);
b->vcl_name = vb->vcl_name;
REPLACE(b->display_name, buf);
REPLACE(b->ipv4_addr, vb->ipv4_addr);
REPLACE(b->ipv6_addr, vb->ipv6_addr);
REPLACE(b->port, vb->port);
b->ipv4_addr = vb->ipv4_addr;
b->ipv6_addr = vb->ipv6_addr;
b->port = vb->port;
b->tcp_pool = VBT_Ref(vb->vcl_name,
vb->ipv4_suckaddr, vb->ipv6_suckaddr);
......@@ -365,7 +270,7 @@ do_list(struct cli *cli, struct backend *b, void *priv)
}
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
VCLI_Out(cli, "\n%-30s %-6d", b->display_name, b->refcount);
VCLI_Out(cli, "\n%-30s", b->display_name);
if (b->admin_health == ah_probe)
VCLI_Out(cli, " %-10s", "probe");
......
......@@ -39,7 +39,6 @@
#include "cache.h"
#include "common/heritage.h"
#include "cache_backend.h" // struct vbc
#include "vcli.h"
#include "vcli_common.h"
#include "vcli_priv.h"
......@@ -79,7 +78,6 @@ cli_cb_before(const struct cli *cli)
ASSERT_CLI();
VSL(SLT_CLI, 0, "Rd %s", cli->cmd);
VCL_Poll();
VBE_Poll();
Lck_Lock(&cli_mtx);
}
......
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