Example #1
0
VCL_BACKEND
VRT_AddDirector(VRT_CTX, const struct vdi_methods *m, void *priv,
    const char *fmt, ...)
{
	struct vsb *vsb;
	struct vcl *vcl;
	struct vcldir *vdir;
	struct director *d;
	va_list ap;
	int i;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(m, VDI_METHODS_MAGIC);
	AN(fmt);
	vcl = ctx->vcl;
	CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
	AZ(errno=pthread_rwlock_rdlock(&vcl->temp_rwl));
	if (vcl->temp == VCL_TEMP_COOLING) {
		AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl));
		return (NULL);
	}

	ALLOC_OBJ(d, DIRECTOR_MAGIC);
	AN(d);
	ALLOC_OBJ(vdir, VCLDIR_MAGIC);
	AN(vdir);
	vdir->dir = d;
	d->vdir = vdir;

	vdir->methods = m;
	d->priv = priv;
	vsb = VSB_new_auto();
	AN(vsb);
	VSB_printf(vsb, "%s.", VCL_Name(vcl));
	i = VSB_len(vsb);
	va_start(ap, fmt);
	VSB_vprintf(vsb, fmt, ap);
	va_end(ap);
	AZ(VSB_finish(vsb));
	REPLACE((vdir->cli_name), VSB_data(vsb));
	VSB_destroy(&vsb);
	d->vcl_name = vdir->cli_name + i;

	vdir->vcl = vcl;
	d->sick = 0;
	vdir->admin_health = VDI_AH_PROBE;
	vdir->health_changed = VTIM_real();

	Lck_Lock(&vcl_mtx);
	VTAILQ_INSERT_TAIL(&vcl->director_list, vdir, list);
	Lck_Unlock(&vcl_mtx);

	if (VCL_WARM(vcl))
		/* Only when adding backend to already warm VCL */
		VDI_Event(d, VCL_EVENT_WARM);
	else if (vcl->temp != VCL_TEMP_INIT)
		WRONG("Dynamic Backends can only be added to warm VCLs");
	AZ(errno=pthread_rwlock_unlock(&vcl->temp_rwl));

	return (d);
}
Example #2
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);
}
static void
ban_lurker_test_ban(struct worker *wrk, struct vsl_log *vsl, struct ban *bt,
    struct banhead_s *obans, struct ban *bd)
{
	struct ban *bl, *bln;
	struct objcore *oc;
	unsigned tests;
	int i;

	/*
	 * First see if there is anything to do, and if so, insert marker
	 */
	Lck_Lock(&ban_mtx);
	oc = VTAILQ_FIRST(&bt->objcore);
	if (oc != NULL)
		VTAILQ_INSERT_TAIL(&bt->objcore, &oc_marker, ban_list);
	Lck_Unlock(&ban_mtx);
	if (oc == NULL)
		return;

	while (1) {
		if (++ban_batch > cache_param->ban_lurker_batch) {
			VTIM_sleep(cache_param->ban_lurker_sleep);
			ban_batch = 0;
		}
		oc = ban_lurker_getfirst(vsl, bt);
		if (oc == NULL)
			return;
		i = 0;
		VTAILQ_FOREACH_REVERSE_SAFE(bl, obans, banhead_s, l_list, bln) {
			if (bl->flags & BANS_FLAG_COMPLETED) {
				/* Ban was overtaken by new (dup) ban */
				VTAILQ_REMOVE(obans, bl, l_list);
				continue;
			}
			tests = 0;
			i = ban_evaluate(wrk, bl->spec, oc, NULL, &tests);
			VSC_C_main->bans_lurker_tested++;
			VSC_C_main->bans_lurker_tests_tested += tests;
			if (i)
				break;
		}
		if (i) {
			VSLb(vsl, SLT_ExpBan, "%u banned by lurker",
			    ObjGetXID(wrk, oc));

			EXP_Rearm(oc, oc->exp.t_origin, 0, 0, 0);
					// XXX ^ fake now
			VSC_C_main->bans_lurker_obj_killed++;
		} else {
			if (oc->ban != bd) {
				Lck_Lock(&ban_mtx);
				oc->ban->refcount--;
				VTAILQ_REMOVE(&oc->ban->objcore, oc, ban_list);
				oc->ban = bd;
				bd->refcount++;
				VTAILQ_INSERT_TAIL(&bd->objcore, oc, ban_list);
				Lck_Unlock(&ban_mtx);
				ObjUpdateMeta(wrk, oc);
			}
		}
		(void)HSH_DerefObjCore(wrk, &oc);
	}
}
Example #4
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);
}
Example #5
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);
}