예제 #1
0
struct vclref *
VRT_ref_vcl(VRT_CTX, const char *desc)
{
	struct vcl *vcl;
	struct vclref* ref;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AN(desc);
	AN(*desc);

	vcl = ctx->vcl;
	CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
	assert(VCL_WARM(vcl));

	ALLOC_OBJ(ref, VCLREF_MAGIC);
	AN(ref);
	ref->vcl = vcl;
	bprintf(ref->desc, "%s", desc);

	Lck_Lock(&vcl_mtx);
	VTAILQ_INSERT_TAIL(&vcl->ref_list, ref, list);
	vcl->nrefs++;
	Lck_Unlock(&vcl_mtx);

	return (ref);
}
예제 #2
0
VCL_VOID
xyzzy_dyn__init(VRT_CTX, struct xyzzy_debug_dyn **dynp,
    const char *vcl_name, VCL_STRING addr, VCL_STRING port, VCL_PROBE probe)
{
	struct xyzzy_debug_dyn *dyn;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AN(dynp);
	AZ(*dynp);
	AN(vcl_name);

	if (*addr == '\0' || *port == '\0') {
		AN(ctx->handling);
		AZ(*ctx->handling);
		VRT_fail(ctx, "Missing dynamic backend address or port");
		return;
	}

	ALLOC_OBJ(dyn, VMOD_DEBUG_DYN_MAGIC);
	AN(dyn);
	REPLACE(dyn->vcl_name, vcl_name);

	AZ(pthread_mutex_init(&dyn->mtx, NULL));

	dyn_dir_init(ctx, dyn, addr, port, probe);
	XXXAN(dyn->dir);
	*dynp = dyn;
}
예제 #3
0
void
VRT_Vmod_Fini(void **hdl)
{
	struct vmod *v;

	ASSERT_CLI();

	AN(*hdl);
	CAST_OBJ_NOTNULL(v, *hdl, VMOD_MAGIC);
	*hdl = NULL;

#ifndef DONT_DLCLOSE_VMODS
	/*
	 * atexit(3) handlers are not called during dlclose(3).  We don't
	 * normally use them, but we do when running GCOV.  This option
	 * enables us to do that.
	 */
	AZ(dlclose(v->hdl));
#endif
	if (--v->ref != 0)
		return;
	free(v->nm);
	free(v->path);
	VTAILQ_REMOVE(&vmods, v, list);
	VSC_C_main->vmods--;
	FREE_OBJ(v);
}
예제 #4
0
void
VRT_init_dir(struct cli *cli, struct director **bp, int idx, const void *priv)
{
	const struct vrt_backend *t;
	struct vdi_simple *vs;

	ASSERT_CLI();
	(void)cli;
	t = priv;

	ALLOC_OBJ(vs, VDI_SIMPLE_MAGIC);
	XXXAN(vs);
	vs->dir.magic = DIRECTOR_MAGIC;
	vs->dir.priv = vs;
	vs->dir.name = "simple";
	REPLACE(vs->dir.vcl_name, t->vcl_name);
	vs->dir.getfd = vdi_simple_getfd;
	vs->dir.healthy = vdi_simple_healthy;

	vs->vrt = t;

	vs->backend = VBE_AddBackend(cli, t);
	if (vs->vrt->probe != NULL)
		VBP_Insert(vs->backend, vs->vrt->probe, vs->vrt->hosthdr);

	bp[idx] = &vs->dir;
}
예제 #5
0
static void
cli_cb_after(const struct cli *cli)
{

	ASSERT_CLI();
	Lck_Unlock(&cli_mtx);
	VSL(SLT_CLI, 0, "Wr %03u %u %s",
	    cli->result, vsb_len(cli->sb), vsb_data(cli->sb));
}
예제 #6
0
static void
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);
}
예제 #7
0
static void
ccf_debug_vmod(struct cli *cli, const char * const *av, void *priv)
{
	struct vmod *v;

	(void)av;
	(void)priv;
	ASSERT_CLI();
	VTAILQ_FOREACH(v, &vmods, list)
		cli_out(cli, "%5d %s (%s)\n", v->ref, v->nm, v->path);
}
예제 #8
0
static void
vdi_simple_fini(const struct director *d)
{
	struct vdi_simple *vs;

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

	VBE_DropRefVcl(vs->backend);
	free(vs->dir.vcl_name);
	vs->dir.magic = 0;
	FREE_OBJ(vs);
}
예제 #9
0
void
VBE_DiscardHealth(const struct director *vdi)
{
	struct vdi_simple *vs;

	ASSERT_CLI();

	if (strcmp(vdi->name, "simple"))
		return;
	CAST_OBJ_NOTNULL(vs, vdi->priv, VDI_SIMPLE_MAGIC);
	if (vs->vrt->probe == NULL)
		return;
	VBP_Remove(vs->backend, vs->vrt->probe);
}
예제 #10
0
void
STV_close(void)
{
	struct stevedore *stv;
	int i;

	ASSERT_CLI();
	for (i = 1; i >= 0; i--) {
		/* First send close warning */
		STV_Foreach(stv)
			if (stv->close != NULL)
				stv->close(stv, i);
	}
}
예제 #11
0
void
STV_open(void)
{
	struct stevedore *stv;
	char buf[1024];

	ASSERT_CLI();
	STV_Foreach(stv) {
		bprintf(buf, "storage.%s", stv->ident);
		stv->vclname = strdup(buf);
		AN(stv->vclname);
		if (stv->open != NULL)
			stv->open(stv);
	}
}
예제 #12
0
static void
sma_open(const struct stevedore *st)
{
	struct sma_sc *sma_sc;

	ASSERT_CLI();
	if (lck_sma == NULL)
		lck_sma = Lck_CreateClass("sma");
	CAST_OBJ_NOTNULL(sma_sc, st->priv, SMA_SC_MAGIC);
	Lck_New(&sma_sc->sma_mtx, lck_sma);
	sma_sc->stats = VSM_Alloc(sizeof *sma_sc->stats,
	    VSC_CLASS, VSC_type_sma, st->ident);
	memset(sma_sc->stats, 0, sizeof *sma_sc->stats);
	if (sma_sc->sma_max != SIZE_MAX)
		sma_sc->stats->g_space = sma_sc->sma_max;
}
예제 #13
0
void
VRT_fini_dir(struct cli *cli, struct director *d)
{
	struct vdi_simple *vs;

	(void)cli;
	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
	CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC);

	VBE_DropRefVcl(vs->backend);
	free(vs->dir.vcl_name);
	vs->dir.magic = 0;
	FREE_OBJ(vs);
	d->priv = NULL;
}
예제 #14
0
void
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm, const char *path)
{
	struct vmod *v;
	void *x;
	const int *i;

	ASSERT_CLI();

	VTAILQ_FOREACH(v, &vmods, list)
		if (!strcmp(v->nm, nm))
			break;
	if (v == NULL) {
		ALLOC_OBJ(v, VMOD_MAGIC);
		AN(v);

		VTAILQ_INSERT_TAIL(&vmods, v, list);
		VSC_main->vmods++;

		REPLACE(v->nm, nm);
		REPLACE(v->path, path);

		v->hdl = dlopen(v->path, RTLD_NOW | RTLD_LOCAL);
		AN(v->hdl);

		x = dlsym(v->hdl, "Vmod_Name");
		AN(x);
		/* XXX: check that name is correct */

		x = dlsym(v->hdl, "Vmod_Len");
		AN(x);
		i = x;
		v->funclen = *i;

		x = dlsym(v->hdl, "Vmod_Func");
		AN(x);
		v->funcs = x;
	}

	assert(len == v->funclen);
	memcpy(ptr, v->funcs, v->funclen);
	v->ref++;

	*hdl = v;
}
예제 #15
0
void
VBP_Remove(struct backend *be)
{
	struct vbp_target *vt;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
	vt = be->probe;
	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);

	Lck_Lock(&vt->mtx);
	vt->stop = 1;
	vt->backend = NULL;
	Lck_Unlock(&vt->mtx);

	be->healthy = 1;
	be->probe = NULL;
}
static void
vrt_init(struct cli *cli, struct director **bp, int idx,
         const void *priv, enum crit_e criteria)
{
    const struct vrt_dir_random *t;
    struct vdi_random *vs;
    const struct vrt_dir_random_entry *te;
    struct vdi_random_host *vh;
    int i;

    ASSERT_CLI();
    (void)cli;
    t = priv;

    ALLOC_OBJ(vs, VDI_RANDOM_MAGIC);
    XXXAN(vs);
    vs->hosts = calloc(sizeof *vh, t->nmember);
    XXXAN(vs->hosts);

    vs->dir.magic = DIRECTOR_MAGIC;
    vs->dir.priv = vs;
    vs->dir.name = "random";
    REPLACE(vs->dir.vcl_name, t->name);
    vs->dir.getfd = vdi_random_getfd;
    vs->dir.fini = vdi_random_fini;
    vs->dir.healthy = vdi_random_healthy;

    vs->criteria = criteria;
    vs->retries = t->retries;
    if (vs->retries == 0)
        vs->retries = t->nmember;
    vh = vs->hosts;
    te = t->members;
    vs->tot_weight = 0.;
    for (i = 0; i < t->nmember; i++, vh++, te++) {
        assert(te->weight > 0.0);
        vh->weight = te->weight;
        vs->tot_weight += vh->weight;
        vh->backend = bp[te->host];
        AN(vh->backend);
    }
    vs->nhosts = t->nmember;
    bp[idx] = &vs->dir;
}
예제 #17
0
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);
}
예제 #18
0
void
VBP_Control(const struct backend *be, int stop)
{
	struct vbp_target *vt;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
	vt = be->probe;
	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);

VSL(SLT_Debug, 0, "VBP_CONTROL %d", stop);
	Lck_Lock(&vt->mtx);
	if (vt->disable == -1 && !stop) {
		vt->disable = stop;
		AZ(pthread_create(&vt->thread, NULL, vbp_wrk_poll_backend, vt));
		AZ(pthread_detach(vt->thread));
	} else {
		assert(vt->disable != -1);
		vt->disable = stop;
	}
	Lck_Unlock(&vt->mtx);
}
예제 #19
0
static void
vrt_init_dir(struct cli *cli, struct director **bp, int idx,
    const void *priv, enum mode_e mode)
{
	const struct vrt_dir_round_robin *t;
	struct vdi_round_robin *vs;
	const struct vrt_dir_round_robin_entry *te;
	struct vdi_round_robin_host *vh;
	int i;

	ASSERT_CLI();
	(void)cli;
	t = priv;

	ALLOC_OBJ(vs, VDI_ROUND_ROBIN_MAGIC);
	XXXAN(vs);
	vs->hosts = calloc(sizeof *vh, t->nmember);
	XXXAN(vs->hosts);

	vs->dir.magic = DIRECTOR_MAGIC;
	vs->dir.priv = vs;
	vs->dir.name = "round_robin";
	REPLACE(vs->dir.vcl_name, t->name);
	vs->dir.getfd = vdi_round_robin_getfd;
	vs->dir.fini = vdi_round_robin_fini;
	vs->dir.healthy = vdi_round_robin_healthy;

	vs->mode = mode;
	vh = vs->hosts;
	te = t->members;
	for (i = 0; i < t->nmember; i++, vh++, te++) {
		vh->backend = bp[te->host];
		AN (vh->backend);
	}
	vs->nhosts = t->nmember;
	vs->next_host = 0;

	bp[idx] = &vs->dir;
}
예제 #20
0
void
VBP_Insert(struct backend *b, const struct vrt_backend_probe *p,
    const char *hosthdr)
{
	struct vbp_target *vt;
	unsigned u;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
	CHECK_OBJ_NOTNULL(p, VRT_BACKEND_PROBE_MAGIC);

	AZ(b->probe);

	ALLOC_OBJ(vt, VBP_TARGET_MAGIC);
	XXXAN(vt);
	VTAILQ_INSERT_TAIL(&vbp_list, vt, list);
	Lck_New(&vt->mtx, lck_backend);
	vt->disable = -1;

	vt->tcp_pool = VBT_Ref(b->ipv4, b->ipv6);
	AN(vt->tcp_pool);

	vt->probe = *p;

	vbp_set_defaults(vt);
	vbp_build_req(vt, hosthdr);

	for (u = 0; u < vt->probe.initial; u++) {
		if (u)
			vbp_has_poked(vt);
		vbp_start_poke(vt);
		vt->happy |= 1;
		vbp_has_poked(vt);
	}
	vt->backend = b;
	b->probe = vt;
	vbp_has_poked(vt);
}
예제 #21
0
int
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
    const char *path, struct cli *cli)
{
	struct vmod *v;
	void *x, *y, *z, *w;

	ASSERT_CLI();

	VTAILQ_FOREACH(v, &vmods, list)
		if (!strcmp(v->nm, nm))	// Also path, len ?
			break;
	if (v == NULL) {
		ALLOC_OBJ(v, VMOD_MAGIC);
		AN(v);

		v->hdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
		if (v->hdl == NULL) {
			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
			VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
			VCLI_Out(cli, "Check child process permissions.\n");
			FREE_OBJ(v);
			return (1);
		}

		x = dlsym(v->hdl, "Vmod_Name");
		y = dlsym(v->hdl, "Vmod_Len");
		z = dlsym(v->hdl, "Vmod_Func");
		w = dlsym(v->hdl, "Vmod_Id");
		if (x == NULL || y == NULL || z == NULL || w == NULL) {
			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
			VCLI_Out(cli, "VMOD symbols not found\n");
			VCLI_Out(cli, "Check relative pathnames.\n");
			(void)dlclose(v->hdl);
			FREE_OBJ(v);
			return (1);
		}
		AN(x);
		AN(y);
		AN(z);
		AN(w);
		if (strcmp(x, nm)) {
			VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
			VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n", x);
			VCLI_Out(cli, "Check relative pathnames ?.\n");
			(void)dlclose(v->hdl);
			FREE_OBJ(v);
			return (1);
		}

		v->funclen = *(const int *)y;
		v->funcs = z;

		REPLACE(v->nm, nm);
		REPLACE(v->path, path);

		VSC_C_main->vmods++;
		VTAILQ_INSERT_TAIL(&vmods, v, list);
		v->idptr = w;
	}

	assert(len == v->funclen);
	memcpy(ptr, v->funcs, v->funclen);
	v->ref++;

	*hdl = v;
	return (0);
}
예제 #22
0
int
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
              const char *path, struct cli *cli)
{
    struct vmod *v;
    void *x, *y, *z, *w;
    char buf[256];
    void *dlhdl;

    ASSERT_CLI();

    dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
    if (dlhdl == NULL) {
        VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
        VCLI_Out(cli, "dlopen() failed: %s\n", dlerror());
        VCLI_Out(cli, "Check child process permissions.\n");
        return (1);
    }

    VTAILQ_FOREACH(v, &vmods, list)
    if (v->hdl == dlhdl)
        break;
    if (v == NULL) {
        ALLOC_OBJ(v, VMOD_MAGIC);
        AN(v);

        v->hdl = dlhdl;

        bprintf(buf, "Vmod_%s_Name", nm);
        x = dlsym(v->hdl, buf);
        bprintf(buf, "Vmod_%s_Len", nm);
        y = dlsym(v->hdl, buf);
        bprintf(buf, "Vmod_%s_Func", nm);
        z = dlsym(v->hdl, buf);
        bprintf(buf, "Vmod_%s_ABI", nm);
        w = dlsym(v->hdl, buf);
        if (x == NULL || y == NULL || z == NULL || w == NULL) {
            VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
            VCLI_Out(cli, "VMOD symbols not found\n");
            VCLI_Out(cli, "Check relative pathnames.\n");
            (void)dlclose(v->hdl);
            FREE_OBJ(v);
            return (1);
        }
        AN(x);
        AN(y);
        AN(z);
        AN(w);
        if (strcmp(x, nm)) {
            VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
            VCLI_Out(cli, "File contain wrong VMOD (\"%s\")\n",
                     (char *) x);
            VCLI_Out(cli, "Check relative pathnames ?.\n");
            (void)dlclose(v->hdl);
            FREE_OBJ(v);
            return (1);
        }

        if (strcmp(w, VMOD_ABI_Version)) {
            VCLI_Out(cli, "Loading VMOD %s from %s:\n", nm, path);
            VCLI_Out(cli, "VMOD ABI (%s)", (char*)w);
            VCLI_Out(cli, " incompatible with varnish ABI (%s)\n",
                     VMOD_ABI_Version);
            (void)dlclose(v->hdl);
            FREE_OBJ(v);
            return (1);
        }

        // XXX: Check w for ABI version compatibility

        v->funclen = *(const int *)y;
        v->funcs = z;

        REPLACE(v->nm, nm);
        REPLACE(v->path, path);

        VSC_C_main->vmods++;
        VTAILQ_INSERT_TAIL(&vmods, v, list);
    }

    assert(len == v->funclen);
    memcpy(ptr, v->funcs, v->funclen);
    v->ref++;

    *hdl = v;
    return (0);
}
예제 #23
0
int
VRT_Vmod_Init(void **hdl, void *ptr, int len, const char *nm,
    const char *path, const char *file_id, VRT_CTX)
{
	struct vmod *v;
	const struct vmod_data *d;
	char buf[256];
	void *dlhdl;

	ASSERT_CLI();
	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AN(ctx->cli);

	dlhdl = dlopen(path, RTLD_NOW | RTLD_LOCAL);
	if (dlhdl == NULL) {
		VCLI_Out(ctx->cli, "Loading VMOD %s from %s:\n", nm, path);
		VCLI_Out(ctx->cli, "dlopen() failed: %s\n", dlerror());
		VCLI_Out(ctx->cli, "Check child process permissions.\n");
		return (1);
	}

	VTAILQ_FOREACH(v, &vmods, list)
		if (v->hdl == dlhdl)
			break;
	if (v == NULL) {
		ALLOC_OBJ(v, VMOD_MAGIC);
		AN(v);

		v->hdl = dlhdl;

		bprintf(buf, "Vmod_%s_Data", nm);
		d = dlsym(v->hdl, buf);
		if (d == NULL ||
		    d->file_id == NULL ||
		    strcmp(d->file_id, file_id)) {
			VCLI_Out(ctx->cli,
			    "Loading VMOD %s from %s:\n", nm, path);
			VCLI_Out(ctx->cli,
			    "This is no longer the same file seen by"
			    " the VCL-compiler.\n");
			(void)dlclose(v->hdl);
			FREE_OBJ(v);
			return (1);
		}
		if (d->vrt_major != VRT_MAJOR_VERSION ||
		    d->vrt_minor > VRT_MINOR_VERSION ||
		    d->name == NULL ||
		    strcmp(d->name, nm) ||
		    d->func == NULL ||
		    d->func_len <= 0 ||
		    d->proto == NULL ||
		    d->spec == NULL ||
		    d->abi == NULL) {
			VCLI_Out(ctx->cli,
			    "Loading VMOD %s from %s:\n", nm, path);
			VCLI_Out(ctx->cli, "VMOD data is mangled.\n");
			(void)dlclose(v->hdl);
			FREE_OBJ(v);
			return (1);
		}

		v->funclen = d->func_len;
		v->funcs = d->func;

		REPLACE(v->nm, nm);
		REPLACE(v->path, path);

		VSC_C_main->vmods++;
		VTAILQ_INSERT_TAIL(&vmods, v, list);
	}

	assert(len == v->funclen);
	memcpy(ptr, v->funcs, v->funclen);
	v->ref++;

	*hdl = v;
	return (0);
}