Ejemplo n.º 1
0
static int
vsl_ix_arg(struct VSL_data *vd, const char *opt, int arg)
{
	int i, j, l;
	const char *b, *e, *p, *q;

	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
	/* If first option is 'i', set all bits for supression */
	if (arg == 'i' && !(vd->flags & F_SEEN_IX))
		for (i = 0; i < 256; i++)
			vbit_set(vd->vbm_supress, i);
	vd->flags |= F_SEEN_IX;

	for (b = opt; *b; b = e) {
		while (isspace(*b))
			b++;
		e = strchr(b, ',');
		if (e == NULL)
			e = strchr(b, '\0');
		l = e - b;
		if (*e == ',')
			e++;
		while (isspace(b[l - 1]))
			l--;
		for (i = 0; i < 256; i++) {
			if (VSL_tags[i] == NULL)
				continue;
			p = VSL_tags[i];
			q = b;
			for (j = 0; j < l; j++)
				if (tolower(*q++) != tolower(*p++))
					break;
			if (j != l || *p != '\0')
				continue;

			if (arg == 'x')
				vbit_set(vd->vbm_supress, i);
			else
				vbit_clr(vd->vbm_supress, i);
			break;
		}
		if (i == 256) {
			fprintf(stderr,
			    "Could not match \"%*.*s\" to any tag\n", l, l, b);
			return (-1);
		}
	}
	return (1);
}
Ejemplo n.º 2
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.º 3
0
/*
 * iterate backends and update
 * - healthy bitmap
 * - number of healthy backends
 * - total_weight
 * - last change time of the VCL_BACKEND
 *
 * must be called under the vdir lock (read or write).
 *
 * A write lock is required if consistency between the individual attributes is
 * a must, e.g. when total_weight is required to be the exact sum of the weights
 *
 * The read lock is safe because add_backend expands the healthy bitmap and all
 * other members are atomic and may be used if consistency is not required.
 */
void
vdir_update_health(VRT_CTX, struct vdir *vd)
{
	VCL_TIME c, changed = 0;
	VCL_BOOL h;
	VCL_BACKEND be;
	unsigned u, nh = 0;
	double tw = 0.0;
	struct vbitmap *healthy;

	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
	healthy = vd->healthy;
	for (u = 0; u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
		c = 0;
		h = VRT_Healthy(ctx, vd->backend[u], &c);
		if (h) {
			nh++;
			tw += vd->weight[u];
		}
		if (c > changed)
			changed = c;
		if (h != vbit_test(healthy, u)) {
			if (h)
				vbit_set(healthy, u);
			else
				vbit_clr(healthy, u);
		}
	}
	VRT_SetChanged(vd->dir, changed);
	vd->total_weight = tw;
	vd->n_healthy = nh;
}
Ejemplo n.º 4
0
void
VSL_Select(struct VSL_data *vd, unsigned tag)
{

	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
	vbit_set(vd->vbm_select, tag);
}
Ejemplo n.º 5
0
static int
vsl_ix_arg(struct VSL_data *vsl, int opt, const char *arg)
{
    int i, l;
    const char *b, *e;

    CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
    /* If first option is 'i', set all bits for supression */
    if (opt == 'i' && !(vsl->flags & F_SEEN_ix))
        for (i = 0; i < 256; i++)
            vbit_set(vsl->vbm_supress, i);
    vsl->flags |= F_SEEN_ix;

    for (b = arg; *b; b = e) {
        while (isspace(*b))
            b++;
        e = strchr(b, ',');
        if (e == NULL)
            e = strchr(b, '\0');
        l = e - b;
        if (*e == ',')
            e++;
        while (isspace(b[l - 1]))
            l--;
        i = VSL_Name2Tag(b, l);
        if (i >= 0) {
            if (opt == 'x')
                vbit_set(vsl->vbm_supress, i);
            else
                vbit_clr(vsl->vbm_supress, i);
        } else if (i == -2) {
            return (vsl_diag(vsl,
                             "-%c: \"%*.*s\" matches multiple tags\n",
                             (char)opt, l, l, b));
        } else {
            return (vsl_diag(vsl,
                             "-%c: Could not match \"%*.*s\" to any tag\n",
                             (char)opt, l, l, b));
        }
    }
    return (1);
}
Ejemplo n.º 6
0
void
mgt_child_inherit(int fd, const char *what)
{

	assert(fd >= 0);
	if (fd_map == NULL)
		fd_map = vbit_init(128);
	AN(fd_map);
	if (what != NULL)
		vbit_set(fd_map, fd);
	else
		vbit_clr(fd_map, fd);
}
Ejemplo n.º 7
0
int
VSL_Arg(struct VSL_data *vsl, int opt, const char *arg)
{
	int i;
	char *p;
	double d;
	long l;

	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
	/* If first option is 'i', set all bits for supression */
	if ((opt == 'i' || opt == 'I') && !(vsl->flags & F_SEEN_ixIX))
		for (i = 0; i < SLT__MAX; i++)
			vbit_set(vsl->vbm_supress, i);

	switch (opt) {
	case 'b': vsl->b_opt = 1; return (1);
	case 'c': vsl->c_opt = 1; return (1);
	case 'C':
		/* Caseless regular expressions */
		vsl->C_opt = 1;
		return (1);
	case 'i': case 'x': return (vsl_ix_arg(vsl, opt, arg));
	case 'I': case 'X': return (vsl_IX_arg(vsl, opt, arg));
	case 'L':
		l = strtol(arg, &p, 0);
		while (isspace(*p))
			p++;
		if (*p != '\0')
			return (vsl_diag(vsl, "-L: Syntax error"));
		if (l < 0 || l > INT_MAX)
			return (vsl_diag(vsl, "-L: Range error"));
		vsl->L_opt = (int)l;
		return (1);
	case 'T':
		d = strtod(arg, &p);
		while (isspace(*p))
			p++;
		if (*p != '\0')
			return (vsl_diag(vsl, "-P: Syntax error"));
		if (d < 0.)
			return (vsl_diag(vsl, "-L: Range error"));
		vsl->T_opt = d;
		return (1);
	case 'v': vsl->v_opt = 1; return (1);
	default:
		return (0);
	}
}
Ejemplo n.º 8
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.º 9
0
vsl_vbm_bitset(int bit, void *priv)
{

	vbit_set((struct vbitmap *)priv, bit);
}
Ejemplo n.º 10
0
static int
shard_next(struct shard_state *state, VCL_INT skip, VCL_BOOL healthy)
{
	int c, chosen = -1;
	uint32_t ringsz;
	VCL_BACKEND be;
	double changed;
	struct shard_be_info *sbe;

	AN(state);
	assert(state->idx >= 0);
	CHECK_OBJ_NOTNULL(state->shardd, SHARDDIR_MAGIC);

	if (state->pickcount >= state->shardd->n_backend)
		return -1;

	ringsz = state->shardd->n_backend * state->shardd->replicas;

	while (state->pickcount < state->shardd->n_backend && skip >= 0) {

		c = state->shardd->hashcircle[state->idx].host;

		if (! vbit_test(state->picklist, c)) {

			vbit_set(state->picklist, c);
			state->pickcount++;

			sbe = NULL;
			be = state->shardd->backend[c].backend;
			AN(be);
			if (be->healthy(be, state->ctx->bo, &changed)) {
				if (skip-- == 0) {
					chosen = c;
					sbe = &state->last;
				} else {
					sbe = &state->previous;
				}

			} else if (!healthy && skip-- == 0) {
				chosen = c;
				sbe = &state->last;
			}
			if (sbe == &state->last &&
			    state->last.hostid != -1)
				memcpy(&state->previous, &state->last,
				    sizeof(state->previous));

			if (sbe) {
				sbe->hostid = c;
				sbe->healthy = 1;
				sbe->changed = changed;
			}
			if (chosen != -1)
				break;
		}

		if (++(state->idx) == ringsz)
			state->idx = 0;
	}
	return chosen;
}
Ejemplo n.º 11
0
int
VSL_NextLog(struct VSL_data *vd, unsigned char **pp)
{
	unsigned char *p, t;
	unsigned u, l;
	int i;

	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
	while (1) {
		i = vsl_nextlog(vd, &p);
		if (i != 1)
			return (i);
		u = SHMLOG_ID(p);
		l = SHMLOG_LEN(p);
		(void)l;
		switch(p[SHMLOG_TAG]) {
		case SLT_SessionOpen:
		case SLT_ReqStart:
			vbit_set(vd->vbm_client, u);
			vbit_clr(vd->vbm_backend, u);
			break;
		case SLT_BackendOpen:
		case SLT_BackendXID:
			vbit_clr(vd->vbm_client, u);
			vbit_set(vd->vbm_backend, u);
			break;
		default:
			break;
		}
		if (vd->skip) {
			--vd->skip;
			continue;
		} else if (vd->keep) {
			if (--vd->keep == 0)
				return (-1);
		}
		t = p[SHMLOG_TAG];
		if (vbit_test(vd->vbm_select, t)) {
			*pp = p;
			return (1);
		}
		if (vbit_test(vd->vbm_supress, t))
			continue;
		if (vd->b_opt && !vbit_test(vd->vbm_backend, u))
			continue;
		if (vd->c_opt && !vbit_test(vd->vbm_client, u))
			continue;
		if (vd->regincl != NULL) {
			i = VRE_exec(vd->regincl,
				     (char *)p + SHMLOG_DATA,
				     SHMLOG_LEN(p), /* Length */
				     0, 0, NULL, 0);
			if (i == VRE_ERROR_NOMATCH)
				continue;
		}
		if (vd->regexcl != NULL) {
			i = VRE_exec(vd->regexcl,
				     (char *)p + SHMLOG_DATA,
				     SHMLOG_LEN(p), /* Length */
				     0, 0, NULL, 0);
			if (i != VRE_ERROR_NOMATCH)
				continue;
		}
		*pp = p;
		return (1);
	}
}