exp_thread(struct worker *wrk, void *priv)
{
	struct objcore *oc;
	double t = 0, tnext = 0;
	struct exp_priv *ep;
	unsigned flags = 0;

	CAST_OBJ_NOTNULL(ep, priv, EXP_PRIV_MAGIC);
	ep->wrk = wrk;
	VSL_Setup(&ep->vsl, NULL, 0);
	ep->heap = binheap_new(NULL, object_cmp, object_update);
	AN(ep->heap);
	while (1) {

		Lck_Lock(&ep->mtx);
		oc = VSTAILQ_FIRST(&ep->inbox);
		CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
		if (oc != NULL) {
			assert(oc->refcnt >= 1);
			VSTAILQ_REMOVE(&ep->inbox, oc, objcore, exp_list);
			VSC_C_main->exp_received++;
			tnext = 0;
			flags = oc->exp_flags;
			if (flags & OC_EF_REMOVE)
				oc->exp_flags = 0;
			else
				oc->exp_flags &= OC_EF_REFD;
		} else if (tnext > t) {
			VSL_Flush(&ep->vsl, 0);
			Pool_Sumstat(wrk);
			(void)Lck_CondWait(&ep->condvar, &ep->mtx, tnext);
		}
		Lck_Unlock(&ep->mtx);

		t = VTIM_real();

		if (oc != NULL)
			exp_inbox(ep, oc, flags);
		else
			tnext = exp_expire(ep, t);
	}
	NEEDLESS(return NULL);
}
Beispiel #2
0
static void
cmd_http_rxchunk(CMD_ARGS)
{
	struct http *hp;
	int ll, i;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	ONLY_CLIENT(hp, av);

	i = http_rxchunk(hp);
	if (i == 0) {
		ll = hp->rxbuf + hp->prxbuf - hp->body;
		hp->bodyl = ll;
		sprintf(hp->bodylen, "%d", ll);
		vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen);
	}
}
int
Lck__Trylock(struct lock *lck, const char *p, const char *f, int l)
{
	struct ilck *ilck;
	int r;

	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
	r = pthread_mutex_lock(&ilck->mtx);
	assert(r == 0 || errno == EBUSY);
	if (params->diag_bitmap & 0x8)
		VSL(SLT_Debug, 0,
		    "MTX_TRYLOCK(%s,%s,%d,%s) = %d", p, f, l, ilck->w);
	if (r == 0) {
		AZ(ilck->held);
		ilck->held = 1;
		ilck->owner = pthread_self();
	}
	return (r);
}
Beispiel #4
0
static void
vbe_panic(const struct director *d, struct vsb *vsb)
{
	struct backend *bp;

	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
	CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);

	VSB_printf(vsb, "      display_name = %s\n", bp->display_name);
	if (bp->ipv4_addr != NULL)
		VSB_printf(vsb, "      ipv4 = %s\n", bp->ipv4_addr);
	if (bp->ipv6_addr != NULL)
		VSB_printf(vsb, "      ipv6 = %s\n", bp->ipv6_addr);
	VSB_printf(vsb, "      port = %s\n", bp->port);
	VSB_printf(vsb, "      hosthdr = %s\n", bp->hosthdr);
	VSB_printf(vsb, "      health=%s, admin_health=%s",
	    bp->healthy ? "healthy" : "sick", bp->admin_health);
	VSB_printf(vsb, ", changed=%.1f\n", bp->health_changed);
}
static void
cmd_http_accept(CMD_ARGS)
{
	struct http *hp;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AZ(av[1]);
	assert(hp->sfd != NULL);
	assert(*hp->sfd >= 0);
	if (hp->fd >= 0)
		VTCP_close(&hp->fd);
	vtc_log(vl, 4, "Accepting");
	hp->fd = accept(*hp->sfd, NULL, NULL);
	if (hp->fd < 0)
		vtc_log(vl, 0, "Accepted failed: %s", strerror(errno));
	vtc_log(vl, 3, "Accepted socket fd is %d", hp->fd);
}
Beispiel #6
0
static void
cmd_http_rxreqhdrs(CMD_ARGS)
{
	struct http *hp;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AZ(strcmp(av[0], "rxreqhdrs"));
	av++;

	for(; *av != NULL; av++)
		vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av);
	http_rxhdr(hp);
	http_splitheader(hp, 1);
	if (http_count_header(hp->req, "Content-Length") > 1)
		vtc_log(hp->vl, 0,
		    "Multiple Content-Length headers.\n");
}
Beispiel #7
0
static void
cmd_http_loop(CMD_ARGS)
{
    struct http *hp;
    unsigned n, m;
    char *s;

    CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
    AN(av[1]);
    AN(av[2]);
    AZ(av[3]);
    n = strtoul(av[1], NULL, 0);
    for (m = 1 ; m <= n; m++) {
        vtc_log(vl, 4, "Loop #%u", m);
        s = strdup(av[2]);
        AN(s);
        parse_string(s, cmd, hp, vl);
    }
}
Beispiel #8
0
static enum sess_close
vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
{
	int i;
	enum sess_close retval;
	struct backend *bp;
	struct v1p_acct v1a;
	struct vbc *vbc;

	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);

	memset(&v1a, 0, sizeof v1a);

	/* This is hackish... */
	v1a.req = req->acct.req_hdrbytes;
	req->acct.req_hdrbytes = 0;

	req->res_mode = RES_PIPE;

	vbc = vbe_dir_getfd(req->wrk, bp, bo);

	if (vbc == NULL) {
		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
		retval = SC_TX_ERROR;
	} else {
		i = V1F_SendReq(req->wrk, bo, &v1a.bereq, 1);
		VSLb_ts_req(req, "Pipe", W_TIM_real(req->wrk));
		if (vbc->state == VBC_STATE_STOLEN)
			VBT_Wait(req->wrk, vbc);
		if (i == 0)
			V1P_Process(req, vbc->fd, &v1a);
		VSLb_ts_req(req, "PipeSess", W_TIM_real(req->wrk));
		bo->htc->doclose = SC_TX_PIPE;
		vbe_dir_finish(d, req->wrk, bo);
		retval = SC_TX_PIPE;
	}
	V1P_Charge(req, &v1a, bp->vsc);
	return (retval);
}
Beispiel #9
0
Lck__Trylock(struct lock *lck, const char *p, const char *f, int l)
{
	struct ilck *ilck;
	int r;

	(void)p;
	(void)f;
	(void)l;

	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
	r = pthread_mutex_trylock(&ilck->mtx);
	assert(r == 0 || r == EBUSY);
	if (r == 0) {
		AZ(ilck->held);
		ilck->held = 1;
		ilck->stat->locks++;
		ilck->owner = pthread_self();
	}
	return (r);
}
void
SES_pool_accept_task(struct worker *wrk, void *arg)
{
	struct sesspool *pp;
	struct sess *sp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(pp, arg, SESSPOOL_MAGIC);

	/* Turn accepted socket into a session */
	AN(wrk->aws->r);
	sp = ses_new(pp);
	if (sp == NULL) {
		VCA_FailSess(wrk);
	} else {
		VCA_SetupSess(wrk, sp);
		sp->step = STP_FIRST;
		ses_pool_task(wrk, sp);
	}
}
Beispiel #11
0
mps_mon(struct ocx *ocx, struct todolist *tdl, void *priv)
{
	char buf[256];
	struct ntp_peer *np;
	int i;

	(void)ocx;
	(void)tdl;
	CAST_OBJ_NOTNULL(np, priv, NTP_PEER_MAGIC);
	i = NTP_Peer_Poll(ocx, usc, np, 0.2);
	if (i == 1) {
		NTP_Tool_Format(buf, sizeof buf, np->rx_pkt);
		Put(ocx, OCX_TRACE,
		    "Monitor %s %s %s\n", np->hostname, np->ip, buf);
	} else {
		Put(ocx, OCX_TRACE,
		    "Monitor_err %s %s %d\n", np->hostname, np->ip, i);
	}
	return(TODO_OK);
}
static int
h_addlog(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len,
    unsigned spec, const char *ptr, uint64_t bitmap)
{
	struct varnish *v;
	int type;

	(void) bitmap;

	type = (spec & VSL_S_CLIENT) ? 'c' :
	    (spec & VSL_S_BACKEND) ? 'b' : '-';
	CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC);

	v->vsl_tag_count[tag]++;

	vtc_log(v->vl, 4, "vsl| %5u %-12s %c %.*s", fd,
	    VSL_tags[tag], type, len, ptr);
	v->vsl_sleep = 100;
	return (0);
}
sma_free(struct storage *s)
{
	struct sma_sc *sma_sc;
	struct sma *sma;

	CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC);
	CAST_OBJ_NOTNULL(sma, s->priv, SMA_MAGIC);
	sma_sc = sma->sc;
	assert(sma->sz == sma->s.space);
	Lck_Lock(&sma_sc->sma_mtx);
	sma_sc->sma_alloc -= sma->sz;
	sma_sc->stats->g_alloc--;
	sma_sc->stats->g_bytes -= sma->sz;
	sma_sc->stats->c_freed += sma->sz;
	if (sma_sc->sma_max != SIZE_MAX)
		sma_sc->stats->g_space += sma->sz;
	Lck_Unlock(&sma_sc->sma_mtx);
	free(sma->s.ptr);
	free(sma);
}
Beispiel #14
0
SES_Proto_Req(struct worker *wrk, void *arg)
{
	struct req *req;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(req, arg, REQ_MAGIC);

	THR_SetRequest(req);
	AZ(wrk->aws->r);
	if (req->sp->sess_step < S_STP_H1_LAST) {
		HTTP1_Session(wrk, req);
		AZ(wrk->v1l);
	} else {
		WRONG("Wrong session step");
	}
	WS_Assert(wrk->aws);
	if (DO_DEBUG(DBG_VCLREL) && wrk->vcl != NULL)
		VCL_Rel(&wrk->vcl);
	THR_SetRequest(NULL);
}
Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts)
{
	struct ilck *ilck;
	int retval = 0;

	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
	AN(ilck->held);
	assert(pthread_equal(ilck->owner, pthread_self()));
	ilck->held = 0;
	if (ts == NULL) {
		AZ(pthread_cond_wait(cond, &ilck->mtx));
	} else {
		retval = pthread_cond_timedwait(cond, &ilck->mtx, ts);
		assert(retval == 0 || retval == ETIMEDOUT);
	}
	AZ(ilck->held);
	ilck->held = 1;
	ilck->owner = pthread_self();
	return (retval);
}
Beispiel #16
0
static void
cmd_http_rxreq(CMD_ARGS)
{
    struct http *hp;

    (void)cmd;
    (void)vl;
    CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
    ONLY_SERVER(hp, av);
    assert(!strcmp(av[0], "rxreq"));
    av++;

    for(; *av != NULL; av++)
        vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av);
    http_rxhdr(hp);
    http_splitheader(hp, 1);
    hp->body = hp->rxbuf + hp->prxbuf;
    http_swallow_body(hp, hp->req, 0);
    vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen);
}
Beispiel #17
0
static struct worker *
pool_getidleworker(struct pool *pp)
{
	struct pool_task *pt;
	struct worker *wrk;

	CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
	Lck_AssertHeld(&pp->mtx);
	pt = VTAILQ_FIRST(&pp->idle_queue);
	if (pt == NULL) {
		if (pp->nthr < cache_param->wthread_max) {
			pp->dry++;
			AZ(pthread_cond_signal(&pp->herder_cond));
		}
		return (NULL);
	}
	AZ(pt->func);
	CAST_OBJ_NOTNULL(wrk, pt->priv, WORKER_MAGIC);
	return (wrk);
}
Beispiel #18
0
static void
cmd_http_expect(CMD_ARGS)
{
	struct http *hp;
	const char *lhs;
	char *cmp;
	const char *rhs;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	assert(!strcmp(av[0], "expect"));
	av++;

	AN(av[0]);
	AN(av[1]);
	AN(av[2]);
	AZ(av[3]);
	lhs = cmd_var_resolve(hp, av[0]);
	cmp = av[1];
	rhs = cmd_var_resolve(hp, av[2]);
	if (!strcmp(cmp, "==")) {
		if (strcmp(lhs, rhs))
			vtc_log(hp->vl, 0, "EXPECT %s (%s) %s %s (%s) failed",
			    av[0], lhs, av[1], av[2], rhs);
		else
			vtc_log(hp->vl, 4, "EXPECT %s (%s) %s %s (%s) match",
			    av[0], lhs, av[1], av[2], rhs);
	} else if (!strcmp(cmp, "!=")) {
		if (!strcmp(lhs, rhs))
			vtc_log(hp->vl, 0, "EXPECT %s (%s) %s %s (%s) failed",
			    av[0], lhs, av[1], av[2], rhs);
		else
			vtc_log(hp->vl, 4, "EXPECT %s (%s) %s %s (%s) match",
			    av[0], lhs, av[1], av[2], rhs);
	} else {
		vtc_log(hp->vl, 0,
		    "EXPECT %s (%s) %s %s (%s) test not implemented",
		    av[0], lhs, av[1], av[2], rhs);
	}
}
Beispiel #19
0
vfp_esi_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
   ssize_t *lp)
{
	enum vfp_status vp;
	ssize_t d, l;
	struct vef_priv *vef;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
	CAST_OBJ_NOTNULL(vef, vfe->priv1, VEF_MAGIC);
	AN(p);
	AN(lp);
	*lp = 0;
	l = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf);
	if (DO_DEBUG(DBG_ESI_CHOP)) {
		d = (random() & 3) + 1;
		if (d < l)
			l = d;
	}
	vp = VFP_Suck(vc, vef->ibuf_i, &l);

	if (l > 0) {
		VEP_Parse(vef->vep, vef->ibuf_i, l);
		vef->ibuf_i += l;
		assert(vef->ibuf_o >= vef->ibuf && vef->ibuf_o <= vef->ibuf_i);
		if (vef->error) {
			errno = vef->error;
			return (VFP_ERROR);
		}
		l = vef->ibuf_i - vef->ibuf_o;
		if (l > 0)
			memmove(vef->ibuf, vef->ibuf_o, l);
		vef->ibuf_o = vef->ibuf;
		vef->ibuf_i = vef->ibuf + l;
	}
	if (vp == VFP_END) {
		vp = vfp_esi_end(vc, vef, vp);
		vfe->priv1 = NULL;
	}
	return (vp);
}
void
VRT_Vmod_Fini(void **hdl)
{
	struct vmod *v;

	ASSERT_CLI();

	AN(*hdl);
	CAST_OBJ_NOTNULL(v, *hdl, VMOD_MAGIC);
	*hdl = NULL;
	if (--v->ref != 0)
		return;
#ifndef DONT_DLCLOSE_VMODS
	AZ(dlclose(v->hdl));
#endif
	free(v->nm);
	free(v->path);
	VTAILQ_REMOVE(&vmods, v, list);
	VSC_main->vmods--;
	FREE_OBJ(v);
}
Beispiel #21
0
static void
vbf_fetch_thread(struct worker *wrk, void *priv)
{
	struct busyobj *bo;
	enum fetch_step stp;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);

	THR_SetBusyobj(bo);
	stp = F_STP_MKBEREQ;

	while (stp != F_STP_DONE) {
		CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
		bo->step = stp;
		switch(stp) {
#define FETCH_STEP(l, U, arg)						\
		case F_STP_##U:						\
			stp = vbf_stp_##l arg;				\
			break;
#include "tbl/steps.h"
#undef FETCH_STEP
		default:
			WRONG("Illegal fetch_step");
		}
		VSLb(bo->vsl, SLT_Debug, "%s -> %s",
		    vbf_step_name(bo->step), vbf_step_name(stp));
	}
	assert(WRW_IsReleased(wrk));

	if (bo->state == BOS_FAILED)
		assert(bo->fetch_objcore->flags & OC_F_FAILED);

	if (bo->ims_obj != NULL)
		(void)HSH_DerefObj(&wrk->stats, &bo->ims_obj);

	VBO_DerefBusyObj(wrk, &bo);
	THR_SetBusyobj(NULL);
}
static void
vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now)
{
	struct sess *ss[NEEV], *sp;
	int i, j;

	AN(ep->data.ptr);
	if (ep->data.ptr == vwe->pipes) {
		if (ep->events & EPOLLIN || ep->events & EPOLLPRI) {
			j = 0;
			i = read(vwe->pipes[0], ss, sizeof ss);
			if (i == -1 && errno == EAGAIN)
				return;
			while (i >= sizeof ss[0]) {
				CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC);
				assert(ss[j]->fd >= 0);
				VTAILQ_INSERT_TAIL(&vwe->sesshead, ss[j], list);
				vwe_cond_modadd(vwe, ss[j]->fd, ss[j]);
				j++;
				i -= sizeof ss[0];
			}
			assert(i == 0);
		}
	} else {
		CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC);
		if (ep->events & EPOLLIN || ep->events & EPOLLPRI) {
			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
			SES_Handle(sp, now);
		} else if (ep->events & EPOLLERR) {
			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
			SES_Delete(sp, SC_REM_CLOSE, now);
		} else if (ep->events & EPOLLHUP) {
			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
			SES_Delete(sp, SC_REM_CLOSE, now);
		} else if (ep->events & EPOLLRDHUP) {
			VTAILQ_REMOVE(&vwe->sesshead, sp, list);
			SES_Delete(sp, SC_REM_CLOSE, now);
		}
	}
}
Beispiel #23
0
enum pipe_status
PIE_Session(struct pipe *dp)
{
	enum pipe_status status = PIPE_CONTINUE;
	struct worker *w;

	CHECK_OBJ_NOTNULL(dp, PIPE_MAGIC);
	CAST_OBJ_NOTNULL(w, dp->wrk, WORKER_MAGIC);

	for (;status == PIPE_CONTINUE;) {
		assert(dp->wrk == w);

		if (params->diag_bitmap & 0x00080000)
			WSL(dp->wrk, SLT_PipeSM, dp->vc.vc_fd, "%s",
			    pie_stepstr[dp->step]);

#ifdef VARNISH_DEBUG
		dp->stephist[dp->stephist_cur++] = dp->step;
		if (dp->stephist_cur >= STEPHIST_MAX)
			dp->stephist_cur = 0;
#endif
		switch (dp->step) {
#define PIPESTEP(l,u)				\
		case PIE_##u:			\
			status = pie_##l(dp);	\
			break;
#include "pipesteps.h"
#undef PIPESTEP
		default:
			WRONG("Drainpipe state engine misfire");
		}
		assert(dp->wrk == w);

		if (params->diag_bitmap & 0x00080000)
			WSL(dp->wrk, SLT_PipeSM, dp->vc.vc_fd, "%s",
			    pie_statusstr[status]);
	}
	WSL_Flush(w, 0);
	return (status);
}
Beispiel #24
0
static void
run_vcc(void *priv)
{
	char *csrc;
	struct vsb *sb;
	struct vcc_priv *vp;
	int fd, i, l;

	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
	VJ_subproc(JAIL_SUBPROC_VCC);
	sb = VSB_new_auto();
	XXXAN(sb);
	VCC_VCL_dir(vcc, mgt_vcl_dir);
	VCC_VMOD_dir(vcc, mgt_vmod_dir);
	VCC_Err_Unref(vcc, mgt_vcc_err_unref);
	VCC_Allow_InlineC(vcc, mgt_vcc_allow_inline_c);
	VCC_Unsafe_Path(vcc, mgt_vcc_unsafe_path);
	csrc = VCC_Compile(vcc, sb, vp->src);
	AZ(VSB_finish(sb));
	if (VSB_len(sb))
		printf("%s", VSB_data(sb));
	VSB_delete(sb);
	if (csrc == NULL)
		exit(2);

	fd = open(vp->srcfile, O_WRONLY|O_TRUNC|O_CREAT, 0600);
	if (fd < 0) {
		fprintf(stderr, "Cannot open %s", vp->srcfile);
		exit(2);
	}
	l = strlen(csrc);
	i = write(fd, csrc, l);
	if (i != l) {
		fprintf(stderr, "Cannot write %s", vp->srcfile);
		exit(2);
	}
	AZ(close(fd));
	free(csrc);
	exit(0);
}
h2_bytes(struct req *req, enum vdp_action act, void **priv,
    const void *ptr, ssize_t len)
{
	struct h2_req *r2;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
	(void)priv;

	if (act == VDP_INIT)
		return (0);
	if (r2->error && act != VDP_FINI)
		return (-1);
	H2_Send_Get(req->wrk, r2->h2sess, r2);
	H2_Send(req->wrk, r2,
	    H2_F_DATA,
	    act == VDP_FINI ? H2FF_DATA_END_STREAM : H2FF_NONE,
	    len, ptr);
	req->acct.resp_bodybytes += len;
	H2_Send_Rel(r2->h2sess, r2);
	return (0);
}
VCL_VOID
vmod_file_system__init(const struct vrt_ctx *ctx,
    struct vmod_fsdirector_file_system **fsp,
    const char *vcl_name, VCL_BACKEND be, const char *root)
{
	struct vmod_fsdirector_file_system *fs;
	struct vdi_simple *vs;

	AN(ctx);
	AN(fsp);
	AN(vcl_name);
	AZ(*fsp);

	CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
	CAST_OBJ_NOTNULL(vs, be->priv, VDI_SIMPLE_MAGIC);

	ALLOC_OBJ(fs, VMOD_FSDIRECTOR_MAGIC);
	AN(fs);
	*fsp = fs;
	fs->vs = vs;

	fs->thread_name = malloc(sizeof("fsthread-")    + strlen(vcl_name));
	fs->ws_name     = malloc(sizeof("fsworkspace-") + strlen(vcl_name));

	AN(fs->thread_name);
	AN(fs->ws_name);

	sprintf(fs->thread_name, "fsthread-%s", vcl_name);
	sprintf(fs->ws_name,  "fsworkspace-%s", vcl_name);

	AN(root);
	assert(root[0] == '\0' || root[0] == '/');
	fs->root = root;

	fs->magic_cookie = load_magic_cookie();
	AN(fs->magic_cookie);

	server_start(fs);
}
/*
 * Try the specified number of times to get a backend.
 * First one according to policy, after that, deterministically
 * random by rehashing the key.
 */
static struct vbc *
vdi_random_getfd(const struct director *d, struct sess *sp)
{
    int k;
    struct vdi_random *vs;
    double r;
    struct vbc *vbe;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
    CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC);

    r = vdi_random_init_seed(vs, sp);

    for (k = 0; k < vs->retries; k++) {
        vbe = vdi_random_pick_one(sp, vs, r);
        if (vbe != NULL)
            return (vbe);
        r = vdi_random_sha((void *)&r, sizeof(r));
    }
    return (NULL);
}
Beispiel #28
0
static int
event_cold(VRT_CTX, const struct vmod_priv *priv)
{
	pthread_t thread;
	struct priv_vcl *priv_vcl;

	CAST_OBJ_NOTNULL(priv_vcl, priv->priv, PRIV_VCL_MAGIC);
	AN(priv_vcl->vcl);
	AN(priv_vcl->vclref);

	VSL(SLT_Debug, 0, "%s: VCL_EVENT_COLD", VCL_Name(ctx->vcl));

	if (vcl_release_delay == 0.0) {
		VRT_rel_vcl(ctx, &priv_vcl->vclref);
		priv_vcl->vcl = NULL;
		return (0);
	}

	AZ(pthread_create(&thread, NULL, cooldown_thread, priv_vcl));
	AZ(pthread_detach(thread));
	return (0);
}
Beispiel #29
0
static void
cmd_http_rxreq(CMD_ARGS)
{
	struct http *hp;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	ONLY_SERVER(hp, av);
	AZ(strcmp(av[0], "rxreq"));
	av++;

	for(; *av != NULL; av++)
		vtc_log(hp->vl, 0, "Unknown http rxreq spec: %s\n", *av);
	http_rxhdr(hp);
	http_splitheader(hp, 1);
	if (http_count_header(hp->req, "Content-Length") > 1)
		vtc_log(hp->vl, 0,
		    "Multiple Content-Length headers.\n");
	http_swallow_body(hp, hp->req, 0);
	vtc_log(hp->vl, 4, "bodylen = %s", hp->bodylen);
}
Lck__Unlock(struct lock *lck, const char *p, const char *f, int l)
{
	struct ilck *ilck;

	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
	assert(pthread_equal(ilck->owner, pthread_self()));
	AN(ilck->held);
	ilck->held = 0;
	/*
	 * #ifdef POSIX_STUPIDITY:
	 * The pthread_t type has no defined assignment or comparison
	 * operators, this is why pthread_equal() is necessary.
	 * Unfortunately POSIX forgot to define a NULL value for pthread_t
	 * so you can never unset a pthread_t variable.
	 * We hack it and fill it with zero bits, hoping for sane
	 * implementations of pthread.
	 * #endif
	 */
	memset(&ilck->owner, 0, sizeof ilck->owner);
	AZ(pthread_mutex_unlock(&ilck->mtx));
	if (cache_param->diag_bitmap & 0x8)
		VSL(SLT_Debug, 0, "MTX_UNLOCK(%s,%s,%d,%s)", p, f, l, ilck->w);
}