void vdir_remove_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, unsigned *cur) { unsigned u, n; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { VRT_fail(ctx, "%s: NULL backend cannot be removed", VRT_BACKEND_string(vd->dir)); return; } CHECK_OBJ(be, DIRECTOR_MAGIC); vdir_wrlock(vd); for (u = 0; u < vd->n_backend; u++) if (vd->backend[u] == be) break; if (u == vd->n_backend) { vdir_unlock(vd); return; } n = (vd->n_backend - u) - 1; memmove(&vd->backend[u], &vd->backend[u+1], n * sizeof(vd->backend[0])); memmove(&vd->weight[u], &vd->weight[u+1], n * sizeof(vd->weight[0])); vd->n_backend--; if (cur) { assert(*cur <= vd->n_backend); if (u < *cur) (*cur)--; else if (*cur == vd->n_backend) *cur = 0; } vdir_unlock(vd); }
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; }
static inline int onearg(VRT_CTX, const char *f, int nargs) { if (nargs == 1) return (1); VRT_fail(ctx, "std.%s: %s arguments", f, nargs > 1 ? "too many" : "not enough"); return (0); }
static int dyn_uds_init(VRT_CTX, struct xyzzy_debug_dyn_uds *uds, VCL_STRING path) { VCL_BACKEND dir, dir2; struct vrt_backend vrt; struct stat st; if (path == NULL) { VRT_fail(ctx, "path is NULL"); return (-1); } if (*path != '/') { VRT_fail(ctx, "path must be an absolute path: %s", path); return (-1); } errno = 0; if (stat(path, &st) != 0) { VRT_fail(ctx, "Cannot stat path %s: %s", path, strerror(errno)); return (-1); } if (!S_ISSOCK(st.st_mode)) { VRT_fail(ctx, "%s is not a socket", path); return (-1); } INIT_OBJ(&vrt, VRT_BACKEND_MAGIC); vrt.path = path; vrt.vcl_name = uds->vcl_name; vrt.hosthdr = "localhost"; vrt.ipv4_suckaddr = NULL; vrt.ipv6_suckaddr = NULL; if ((dir = VRT_new_backend(ctx, &vrt)) == NULL) return (-1); AZ(pthread_mutex_lock(&uds->mtx)); dir2 = uds->dir; uds->dir = dir; AZ(pthread_mutex_unlock(&uds->mtx)); if (dir2 != NULL) VRT_delete_backend(ctx, &dir2); return (0); }
static void vrt_do_string(VRT_CTX, struct http *hp, int fld, const char *err, const char *p, va_list ap) { const char *b; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); b = VRT_String(hp->ws, NULL, p, ap); if (b == NULL) { VRT_fail(ctx, "Workspace overflow (%s)", err); WS_MarkOverflow(hp->ws); return; } if (*b == '\0') { VRT_fail(ctx, "Setting %s to empty string", err); return; } http_SetH(hp, fld, b); }
void vdir_add_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, double weight) { unsigned u; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { VRT_fail(ctx, "%s: NULL backend cannot be added", VRT_BACKEND_string(vd->dir)); return; } AN(be); vdir_wrlock(vd); if (vd->n_backend >= vd->l_backend) vdir_expand(vd, vd->l_backend + 16); assert(vd->n_backend < vd->l_backend); u = vd->n_backend++; vd->backend[u] = be; vd->weight[u] = weight; vdir_unlock(vd); }