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); }
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); } }
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); }
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); }