Ejemplo n.º 1
0
unsigned
vdir_remove_backend(struct vdir *vd, VCL_BACKEND be)
{
	unsigned u, n;

	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	if (be == NULL)
		return (vd->n_backend);
	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 (vd->n_backend);
	}
	vd->total_weight -= vd->weight[u];
	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--;
	vdir_unlock(vd);
	return (vd->n_backend);
}
Ejemplo n.º 2
0
unsigned
vdir_any_healthy(struct vdir *vd, const struct busyobj *bo, double *changed)
{
	unsigned retval = 0;
	VCL_BACKEND be;
	unsigned u;
	double c;

	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC);
	vdir_lock(vd);
	if (changed != NULL)
		*changed = 0;
	for (u = 0; u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
		retval = be->healthy(be, bo, &c);
		if (changed != NULL && c > *changed)
			*changed = c;
		if (retval)
			break;
	}
	vdir_unlock(vd);
	return (retval);
}
Ejemplo n.º 3
0
VCL_BACKEND
vdir_pick_be(struct vdir *vd, const struct busyobj *bo, double w,
    unsigned nloops)
{
	struct vbitmap *vbm = NULL;
	unsigned u, v, l;
	VCL_BACKEND be = NULL;
	double tw;
	int nbe;

	tw = vd->total_weight;
	nbe = vd->n_backend;
	assert(w >= 0.0 && w <= 1.0);
	vdir_lock(vd);
	for (l = 0; nbe > 0 && tw > 0.0 && l <nloops; l++) {
		u = vdir_pick_by_weight(vd, w * tw, vbm);
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
		if (be->healthy(be, bo->digest))
			break;
		if (l == 0) {
			vbm = vd->vbm;
			for (v = 0; v < nbe; v++)
				vbit_clr(vbm, v);
		}
		vbit_set(vbm, u);
		nbe--;
		tw -= vd->weight[u];
		be = NULL;
	}
	vdir_unlock(vd);
	return (be);
}
Ejemplo n.º 4
0
VCL_BOOL
vdir_any_healthy(VRT_CTX, struct vdir *vd, VCL_TIME *changed)
{
	unsigned retval = 0;
	VCL_BACKEND be;
	unsigned u;
	vtim_real c;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	vdir_rdlock(vd);
	if (changed != NULL)
		*changed = 0;
	for (u = 0; u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
		retval = VRT_Healthy(ctx, be, &c);
		if (changed != NULL && c > *changed)
			*changed = c;
		if (retval)
			break;
	}
	vdir_unlock(vd);
	return (retval);
}
Ejemplo n.º 5
0
unsigned
vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight)
{
	unsigned u;

	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	AN(be);
	vdir_lock(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;
	vd->total_weight += weight;
	vdir_unlock(vd);
	return (u);
}
Ejemplo n.º 6
0
VCL_BACKEND
vdir_pick_be(VRT_CTX, struct vdir *vd, double w)
{
	unsigned u;
	VCL_BACKEND be = NULL;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	vdir_wrlock(vd);
	vdir_update_health(ctx, vd);
	if (vd->total_weight > 0.0) {
		u = vdir_pick_by_weight(vd, w * vd->total_weight);
		assert(u < vd->n_backend);
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
	}
	vdir_unlock(vd);
	return (be);
}
Ejemplo n.º 7
0
unsigned
vdir_any_healthy(struct vdir *vd, const uint8_t *digest)
{
	unsigned retval = 0;
	VCL_BACKEND be;
	unsigned u;

	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	vdir_lock(vd);
	for (u = 0; u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
		if (be->healthy(be, digest)) {
			retval = 1;
			break;
		}
	}
	vdir_unlock(vd);
	return (retval);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
VCL_BACKEND
vdir_pick_be(struct vdir *vd, double w, const struct busyobj *bo)
{
	unsigned u;
	double tw = 0.0;
	VCL_BACKEND be = NULL;

	vdir_lock(vd);
	for (u = 0; u < vd->n_backend; u++) {
		if (vd->backend[u]->healthy(vd->backend[u], bo, NULL)) {
			vbit_clr(vd->vbm, u);
			tw += vd->weight[u];
		} else
			vbit_set(vd->vbm, u);
	}
	if (tw > 0.0) {
		u = vdir_pick_by_weight(vd, w * tw, vd->vbm);
		assert(u < vd->n_backend);
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
	}
	vdir_unlock(vd);
	return (be);
}
Ejemplo n.º 10
0
void
vdir_list(VRT_CTX, struct vdir *vd, struct vsb *vsb, int pflag, int jflag,
    int weight)
{
	VCL_BACKEND be;
	VCL_BOOL h;
	unsigned u, nh;
	double w;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);

	if (pflag) {
		if (jflag) {
			VSB_cat(vsb, "{\n");
			VSB_indent(vsb, 2);
			if (weight)
				VSB_printf(vsb, "\"total_weight\": %f,\n",
				    vd->total_weight);
			VSB_cat(vsb, "\"backends\": {\n");
			VSB_indent(vsb, 2);
		} else {
			VSB_cat(vsb, "\n\n\tBackend\tWeight\tHealth\n");
		}
	}

	vdir_rdlock(vd);
	vdir_update_health(ctx, vd);
	for (u = 0; pflag && u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);

		h = vbit_test(vd->healthy, u);

		w = h ? vd->weight[u] : 0.0;

		if (jflag) {
			if (u)
				VSB_cat(vsb, ",\n");
			VSB_printf(vsb, "\"%s\": {\n", be->vcl_name);
			VSB_indent(vsb, 2);

			if (weight)
				VSB_printf(vsb, "\"weight\": %f,\n", w);

			if (h)
				VSB_cat(vsb, "\"health\": \"healthy\"\n");
			else
				VSB_cat(vsb, "\"health\": \"sick\"\n");

			VSB_indent(vsb, -2);
			VSB_cat(vsb, "}");
		} else {
			VSB_cat(vsb, "\t");
			VSB_cat(vsb, be->vcl_name);
			if (weight)
				VSB_printf(vsb, "\t%6.2f%%\t",
				    100 * w / vd->total_weight);
			else
				VSB_cat(vsb, "\t-\t");
			VSB_cat(vsb, h ? "healthy" : "sick");
			VSB_cat(vsb, "\n");
		}
	}
	nh = vd->n_healthy;
	u = vd->n_backend;
	vdir_unlock(vd);

	if (jflag && (pflag)) {
		VSB_cat(vsb, "\n");
		VSB_indent(vsb, -2);
		VSB_cat(vsb, "}\n");
		VSB_indent(vsb, -2);
		VSB_cat(vsb, "},\n");
	}

	if (pflag)
		return;

	if (jflag)
		VSB_printf(vsb, "[%u, %u, \"%s\"]", nh, u,
		    nh ? "healthy" : "sick");
	else
		VSB_printf(vsb, "%u/%u\t%s", nh, u, nh ? "healthy" : "sick");
}