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