[master] eb8f35b Close a race condition in the backend/tcp_pools interface.
Poul-Henning Kamp
phk at FreeBSD.org
Fri May 15 23:41:22 CEST 2015
commit eb8f35bd79206ff489b895ffb2dc3fb07cabfce5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri May 15 21:40:59 2015 +0000
Close a race condition in the backend/tcp_pools interface.
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 9aac126..858ade7 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -135,7 +135,7 @@ vbe_dir_getfd(const struct director *d, struct busyobj *bo)
VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s",
vc->fd, bp->display_name, abuf2, pbuf2, abuf1, pbuf1);
- vc->backend->vsc->req++;
+ bp->vsc->req++;
INIT_OBJ(bo->htc, HTTP_CONN_MAGIC);
bo->htc->vbc = vc;
bo->htc->fd = vc->fd;
@@ -167,11 +167,12 @@ vbe_dir_finish(const struct director *d, struct worker *wrk,
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+ CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
if (bo->htc->vbc == NULL)
return;
- bp = bo->htc->vbc->backend;
+ bo->htc->vbc->backend = NULL;
if (bo->doclose != SC_NULL) {
VSLb(bo->vsl, SLT_BackendClose, "%d %s", bo->htc->vbc->fd,
bp->display_name);
@@ -187,8 +188,8 @@ vbe_dir_finish(const struct director *d, struct worker *wrk,
#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;
+ Lck_Unlock(&bp->mtx);
bo->htc = NULL;
}
diff --git a/bin/varnishd/cache/cache_backend.h b/bin/varnishd/cache/cache_backend.h
index 48dffa4..38a979f 100644
--- a/bin/varnishd/cache/cache_backend.h
+++ b/bin/varnishd/cache/cache_backend.h
@@ -100,6 +100,7 @@ struct vbc {
uint8_t in_waiter;
uint8_t have_been_in_waiter;
struct waited waited[1];
+ struct tcp_pool *tcp_pool;
struct backend *backend;
};
diff --git a/bin/varnishd/cache/cache_backend_tcp.c b/bin/varnishd/cache/cache_backend_tcp.c
index 5b73e57..518870e 100644
--- a/bin/varnishd/cache/cache_backend_tcp.c
+++ b/bin/varnishd/cache/cache_backend_tcp.c
@@ -85,7 +85,8 @@ tcp_handle(struct waited *w, enum wait_event ev, double now)
CAST_OBJ_NOTNULL(vbc, w->ptr, VBC_MAGIC);
(void)ev;
(void)now;
- tp = vbc->backend->tcp_pool; // NB: Incestous
+ CHECK_OBJ_NOTNULL(vbc->tcp_pool, TCP_POOL_MAGIC);
+ tp = vbc->tcp_pool;
Lck_Lock(&tp->mtx);
VSL(SLT_Debug, 0,
@@ -388,6 +389,7 @@ VBT_Get(struct tcp_pool *tp, double tmo)
tp->n_conn--;
VSC_C_main->backend_reuse += 1;
vbc->state = VBC_STATE_USED;
+ assert(vbc->tcp_pool == tp);
}
tp->n_used++; // Opening mostly works
Lck_Unlock(&tp->mtx);
@@ -399,6 +401,7 @@ VBT_Get(struct tcp_pool *tp, double tmo)
AN(vbc);
INIT_OBJ(vbc->waited, WAITED_MAGIC);
vbc->state = VBC_STATE_USED;
+ vbc->tcp_pool = tp;
vbc->fd = VBT_Open(tp, tmo, &vbc->addr);
if (vbc->fd < 0)
FREE_OBJ(vbc);
More information about the varnish-commit
mailing list