예제 #1
0
void
VDI_CloseFd(struct vbc **vbp)
{
	struct backend *bp;
	struct vbc *vc;

	AN(vbp);
	vc = *vbp;
	*vbp = NULL;
	CHECK_OBJ_NOTNULL(vc, VBC_MAGIC);
	CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
	assert(vc->fd >= 0);

	bp = vc->backend;

	VSLb(vc->vsl, SLT_BackendClose, "%s", bp->display_name);

	/*
	 * Checkpoint log to flush all info related to this connection
	 * before the OS reuses the FD
	 */
	VSL_Flush(vc->vsl, 0);
	vc->vsl = NULL;

	VTCP_close(&vc->fd);
	VBE_DropRefConn(bp);
	vc->backend = NULL;
	VBE_ReleaseConn(vc);
}
struct vbe_conn *
VBE_GetVbe(struct sess *sp, struct backend *bp)
{
	struct vbe_conn *vc;

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);

	/* first look for vbe_conn's we can recycle */
	while (1) {
		Lck_Lock(&bp->mtx);
		vc = VTAILQ_FIRST(&bp->connlist);
		if (vc != NULL) {
			bp->refcount++;
			assert(vc->backend == bp);
			assert(vc->fd >= 0);
			VTAILQ_REMOVE(&bp->connlist, vc, list);
		}
		Lck_Unlock(&bp->mtx);
		if (vc == NULL)
			break;
		if (VBE_CheckFd(vc->fd)) {
			/* XXX locking of stats */
			VSL_stats->backend_reuse += 1;
			VSL_stats->backend_conn++;
			WSP(sp, SLT_Backend, "%d %s %s",
			    vc->fd, sp->director->vcl_name, bp->vcl_name);
			return (vc);
		}
		sp->vbe = vc;
		VBE_ClosedFd(sp);
	}

	if (!bp->healthy) {
		VSL_stats->backend_unhealthy++;
		return (NULL);
	}

	if (bp->max_conn > 0 && bp->n_conn >= bp->max_conn) {
		VSL_stats->backend_busy++;
		return (NULL);
	}

	vc = VBE_NewConn();
	assert(vc->fd == -1);
	AZ(vc->backend);
	vc->fd = bes_conn_try(sp, bp);
	if (vc->fd < 0) {
		VBE_ReleaseConn(vc);
		VSL_stats->backend_fail++;
		return (NULL);
	}
	vc->backend = bp;
	VSL_stats->backend_conn++;
	WSP(sp, SLT_Backend, "%d %s %s",
	    vc->fd, sp->director->vcl_name, bp->vcl_name);
	return (vc);
}
void
VBE_ClosedFd(struct sess *sp)
{
	struct backend *bp;

	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_DropRefConn(bp);
	sp->vbe->backend = NULL;
	VBE_ReleaseConn(sp->vbe);
	sp->vbe = NULL;
}
예제 #4
0
void
VBE_CloseFd(struct vbc **vbp, const struct acct_bereq *acct_bereq)
{
	struct backend *bp;
	struct vbc *vc;

	AN(vbp);
	vc = *vbp;
	*vbp = NULL;
	CHECK_OBJ_NOTNULL(vc, VBC_MAGIC);
	CHECK_OBJ_NOTNULL(vc->backend, BACKEND_MAGIC);
	assert(vc->fd >= 0);

	bp = vc->backend;

	VSLb(vc->vsl, SLT_BackendClose, "%d %s", vc->fd, bp->display_name);

	vc->vsl = NULL;
	VTCP_close(&vc->fd);
	VBE_DropRefConn(bp, acct_bereq);
	vc->backend = NULL;
	VBE_ReleaseConn(vc);
}
예제 #5
0
static struct vbc *
vbe_GetVbe(struct busyobj *bo, struct vdi_simple *vs)
{
	struct vbc *vc;
	struct backend *bp;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_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 */
	while (1) {
		Lck_Lock(&bp->mtx);
		vc = VTAILQ_FIRST(&bp->connlist);
		if (vc != NULL) {
			bp->refcount++;
			assert(vc->backend == bp);
			assert(vc->fd >= 0);
			AN(vc->addr);
			VTAILQ_REMOVE(&bp->connlist, vc, list);
		}
		Lck_Unlock(&bp->mtx);
		if (vc == NULL)
			break;
		if (vbe_CheckFd(vc->fd)) {
			/* XXX locking of stats */
			VSC_C_main->backend_reuse += 1;
			VSLb(bo->vsl, SLT_Backend, "%d %s %s",
			    vc->fd, bo->director->vcl_name,
			    bp->display_name);
			vc->vdis = vs;
			vc->recycled = 1;
			return (vc);
		}
		VSC_C_main->backend_toolate++;
		VSLb(bo->vsl, SLT_BackendClose, "%d %s toolate",
		    vc->fd, bp->display_name);

		/* Checkpoint log to flush all info related to this connection
		   before the OS reuses the FD */
		VSL_Flush(bo->vsl, 0);

		VTCP_close(&vc->fd);
		VBE_DropRefConn(bp);
		vc->backend = NULL;
		VBE_ReleaseConn(vc);
	}

	if (!VBE_Healthy(bp, NULL)) {
		VSC_C_main->backend_unhealthy++;
		return (NULL);
	}

	if (vs->vrt->max_connections > 0 &&
	    bp->n_conn >= vs->vrt->max_connections) {
		VSC_C_main->backend_busy++;
		return (NULL);
	}

	vc = vbe_NewConn();
	assert(vc->fd == -1);
	AZ(vc->backend);
	bes_conn_try(bo, vc, vs);
	if (vc->fd < 0) {
		VBE_ReleaseConn(vc);
		VSC_C_main->backend_fail++;
		return (NULL);
	}
	vc->backend = bp;
	VSC_C_main->backend_conn++;
	VSLb(bo->vsl, SLT_Backend, "%d %s %s",
	    vc->fd, bo->director->vcl_name, bp->display_name);
	vc->vdis = vs;
	return (vc);
}