...
 
Commits (4)
......@@ -2,6 +2,8 @@
vmod-weightadjust
============
This version is for varnish 6.2
SYNOPSIS
========
......
......@@ -28,7 +28,7 @@ AC_ARG_WITH([rst2man],
m4_ifndef([VARNISH_PREREQ], AC_MSG_ERROR([Need varnish.m4 -- see README.rst]))
VARNISH_PREREQ([master])
VARNISH_PREREQ([6.2])
VARNISH_VMODS([weightadjust])
VMOD_TESTS="$(cd $srcdir/src && echo tests/*.vtc)"
......
......@@ -35,7 +35,6 @@
#include "vbm.h"
#include "vrnd.h"
#include "vrt.h"
#include "vdir.h"
......@@ -47,35 +46,53 @@
#define vmod_random__init _vmod_random__init
#define vmod_random__fini _vmod_random__fini
static unsigned __match_proto__(vdi_healthy)
vmod_random_healthy(const struct director *dir, const struct busyobj *bo,
double *changed)
static VCL_BOOL
vmod_random_healthy(VRT_CTX, VCL_BACKEND dir, VCL_TIME *changed)
{
struct vmod_directors_random *rr;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
return (vdir_any_healthy(rr->vd, bo, changed));
return (vdir_any_healthy(ctx, rr->vd, changed));
}
static const struct director * __match_proto__(vdi_resolve_f)
vmod_random_resolve(const struct director *dir, struct worker *wrk,
struct busyobj *bo)
static VCL_BACKEND
vmod_random_resolve(VRT_CTX, VCL_BACKEND dir)
{
struct vmod_directors_random *rr;
VCL_BACKEND be;
double r;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
r = scalbn(VRND_RandomTestable(), -31);
assert(r >= 0 && r < 1.0);
be = vdir_pick_be(rr->vd, r, bo);
be = vdir_pick_be(ctx, rr->vd, r);
return (be);
}
VCL_VOID __match_proto__()
static void v_matchproto_(vdi_destroy_f)
vmod_random_destroy(VCL_BACKEND dir)
{
struct vmod_directors_random *rr;
CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
vdir_delete(&rr->vd);
FREE_OBJ(rr);
}
static const struct vdi_methods vmod_random_methods[1] = {{
.magic = VDI_METHODS_MAGIC,
.type = "random",
.healthy = vmod_random_healthy,
.resolve = vmod_random_resolve,
.destroy = vmod_random_destroy
}};
VCL_VOID
vmod_random__init(VRT_CTX, struct vmod_directors_random **rrp,
const char *vcl_name)
{
......@@ -87,43 +104,43 @@ vmod_random__init(VRT_CTX, struct vmod_directors_random **rrp,
ALLOC_OBJ(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
AN(rr);
*rrp = rr;
vdir_new(&rr->vd, "random", vcl_name, vmod_random_healthy,
vmod_random_resolve, rr);
vdir_new(ctx, &rr->vd, vcl_name, vmod_random_methods, rr);
}
VCL_VOID __match_proto__()
VCL_VOID
vmod_random__fini(struct vmod_directors_random **rrp)
{
struct vmod_directors_random *rr;
rr = *rrp;
*rrp = NULL;
CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
vdir_delete(&rr->vd);
FREE_OBJ(rr);
// XXX 2297
if (*rrp == NULL)
return;
TAKE_OBJ_NOTNULL(rr, rrp, VMOD_DIRECTORS_RANDOM_MAGIC);
VRT_DelDirector(&rr->vd->dir);
}
#ifdef UNUSED
VCL_VOID __match_proto__()
VCL_VOID
vmod_random_add_backend(VRT_CTX,
struct vmod_directors_random *rr, VCL_BACKEND be, double w)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
(void)vdir_add_backend(rr->vd, be, w);
vdir_add_backend(ctx, rr->vd, be, w);
}
VCL_VOID vmod_random_remove_backend(VRT_CTX,
struct vmod_directors_random *rr, VCL_BACKEND be) __match_proto__()
struct vmod_directors_random *rr, VCL_BACKEND be) v_matchproto_()
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
vdir_remove_backend(rr->vd, be, NULL);
vdir_remove_backend(ctx, rr->vd, be, NULL);
}
#endif
VCL_BACKEND __match_proto__()
VCL_BACKEND
vmod_random_backend(VRT_CTX, struct vmod_directors_random *rr)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
......
......@@ -80,15 +80,15 @@ Host: weighthost
} -start
logexpect l1 -v v1 -g raw -d 1 {
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s1 starting}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s1 set to 11.345000 total 11.345000}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s1_hosthdr starting}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s1_hosthdr set to 12.345000 total 23.690000}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s1 stopping}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s2 starting}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s2 set to 3.789000 total 16.134000}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s3 starting}
expect * * Debug {^vmod weightadjust: poke foo.vcl1.s3 set to 42.000000 total 58.134000}
expect * * Debug {^vmod weightadjust: poke foo.s1 starting}
expect * * Debug {^vmod weightadjust: poke foo.s1 set to 11.345000 total 11.345000}
expect * * Debug {^vmod weightadjust: poke foo.s1_hosthdr starting}
expect * * Debug {^vmod weightadjust: poke foo.s1_hosthdr set to 12.345000 total 23.690000}
expect * * Debug {^vmod weightadjust: poke foo.s1 stopping}
expect * * Debug {^vmod weightadjust: poke foo.s2 starting}
expect * * Debug {^vmod weightadjust: poke foo.s2 set to 3.789000 total 16.134000}
expect * * Debug {^vmod weightadjust: poke foo.s3 starting}
expect * * Debug {^vmod weightadjust: poke foo.s3 set to 42.000000 total 58.134000}
} -start
client c1 {
......
......@@ -31,9 +31,7 @@
#include <stdlib.h>
#include "cache/cache.h"
#include "cache/cache_director.h"
#include "vrt.h"
#include "vbm.h"
#include "vdir.h"
......@@ -51,12 +49,13 @@ vdir_expand(struct vdir *vd, unsigned n)
}
void
vdir_new(struct vdir **vdp, const char *name, const char *vcl_name,
vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv)
vdir_new(VRT_CTX, struct vdir **vdp, const char *vcl_name,
const struct vdi_methods *m, void *priv)
{
struct vdir *vd;
AN(name);
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(m, VDI_METHODS_MAGIC);
AN(vcl_name);
AN(vdp);
AZ(*vdp);
......@@ -64,14 +63,7 @@ vdir_new(struct vdir **vdp, const char *name, const char *vcl_name,
AN(vd);
*vdp = vd;
AZ(pthread_rwlock_init(&vd->mtx, NULL));
ALLOC_OBJ(vd->dir, DIRECTOR_MAGIC);
AN(vd->dir);
vd->dir->name = name;
REPLACE(vd->dir->vcl_name, vcl_name);
vd->dir->priv = priv;
vd->dir->healthy = healthy;
vd->dir->resolve = resolve;
vd->dir = VRT_AddDirector(ctx, m, priv, "%s", vcl_name);
vd->vbm = vbit_new(8);
AN(vd->vbm);
}
......@@ -83,11 +75,10 @@ vdir_delete(struct vdir **vdp)
TAKE_OBJ_NOTNULL(vd, vdp, VDIR_MAGIC);
AZ(vd->dir);
free(vd->backend);
free(vd->weight);
AZ(pthread_rwlock_destroy(&vd->mtx));
free(vd->dir->vcl_name);
FREE_OBJ(vd->dir);
vbit_destroy(vd->vbm);
FREE_OBJ(vd);
}
......@@ -114,12 +105,18 @@ vdir_unlock(struct vdir *vd)
}
unsigned
vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight)
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)
......@@ -130,17 +127,20 @@ vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight)
vd->weight[u] = weight;
vd->total_weight += weight;
vdir_unlock(vd);
return (u);
}
void
vdir_remove_backend(struct vdir *vd, VCL_BACKEND be, unsigned *cur)
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)
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++)
......@@ -166,23 +166,23 @@ vdir_remove_backend(struct vdir *vd, VCL_BACKEND be, unsigned *cur)
vdir_unlock(vd);
}
unsigned
vdir_any_healthy(struct vdir *vd, const struct busyobj *bo, double *changed)
VCL_BOOL
vdir_any_healthy(VRT_CTX, struct vdir *vd, VCL_TIME *changed)
{
unsigned retval = 0;
VCL_BACKEND be;
unsigned u;
double c;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
CHECK_OBJ_ORNULL(bo, BUSYOBJ_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 = be->healthy(be, bo, &c);
retval = VRT_Healthy(ctx, be, &c);
if (changed != NULL && c > *changed)
*changed = c;
if (retval)
......@@ -214,15 +214,17 @@ vdir_pick_by_weight(const struct vdir *vd, double w,
}
VCL_BACKEND
vdir_pick_be(struct vdir *vd, double w, const struct busyobj *bo)
vdir_pick_be(VRT_CTX, struct vdir *vd, double w)
{
unsigned u;
double tw = 0.0;
VCL_BACKEND be = NULL;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);
vdir_wrlock(vd);
for (u = 0; u < vd->n_backend; u++) {
if (vd->backend[u]->healthy(vd->backend[u], bo, NULL)) {
if (VRT_Healthy(ctx, vd->backend[u], NULL)) {
vbit_clr(vd->vbm, u);
tw += vd->weight[u];
} else
......
......@@ -37,18 +37,17 @@ struct vdir {
VCL_BACKEND *backend;
double *weight;
double total_weight;
struct director *dir;
VCL_BACKEND dir;
struct vbitmap *vbm;
};
void vdir_new(struct vdir **vdp, const char *name, const char *vcl_name,
vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv);
void vdir_new(VRT_CTX, struct vdir **vdp, const char *vcl_name,
const struct vdi_methods *, void *priv);
void vdir_delete(struct vdir **vdp);
void vdir_rdlock(struct vdir *vd);
void vdir_wrlock(struct vdir *vd);
void vdir_unlock(struct vdir *vd);
unsigned vdir_add_backend(struct vdir *, VCL_BACKEND be, double weight);
void vdir_remove_backend(struct vdir *, VCL_BACKEND be, unsigned *cur);
unsigned vdir_any_healthy(struct vdir *, const struct busyobj *,
double *changed);
VCL_BACKEND vdir_pick_be(struct vdir *, double w, const struct busyobj *);
void vdir_add_backend(VRT_CTX, struct vdir *, VCL_BACKEND, double weight);
void vdir_remove_backend(VRT_CTX, struct vdir *, VCL_BACKEND, unsigned *cur);
VCL_BOOL vdir_any_healthy(VRT_CTX, struct vdir *, VCL_TIME *);
VCL_BACKEND vdir_pick_be(VRT_CTX, struct vdir *, double w);
......@@ -46,7 +46,6 @@
#include "cache/cache.h"
#include "vrt.h"
#include "vcl.h"
#include "vre.h"
#include "vsa.h"
......@@ -63,20 +62,13 @@
#include "vmod_weightadjust.h"
#include "wadj_thread.h"
#if 1
#define ERR(ctx, str) \
msg((ctx), 1, "vmod weightadjust error: " str)
#define VERR(ctx, fmt, ...) \
msg((ctx), 1, "vmod weightadjust error: " fmt, __VA_ARGS__)
#else
#define ERR(ctx, msg) \
VRT_fail((ctx), "vmod weightadjust error: " str)
VRT_fail((ctx), "vmod weightadjust error: " msg)
#define VERR(ctx, fmt, ...) \
VRT_fail((ctx), "vmod weightadjust error: " fmt, __VA_ARGS__)
#endif
static void
msg(VRT_CTX, int fail, const char *fmt, ...)
msg(VRT_CTX, const char *fmt, ...)
{
va_list args;
......@@ -84,8 +76,6 @@ msg(VRT_CTX, int fail, const char *fmt, ...)
if (ctx->method == VCL_MET_INIT) {
AN(ctx->msg);
VSB_vprintf(ctx->msg, fmt, args);
if (fail)
VRT_handling(ctx, VCL_RET_FAIL);
}
else if (ctx->vsl)
VSLbv(ctx->vsl, SLT_VCL_Error, fmt, args);
......@@ -95,7 +85,7 @@ msg(VRT_CTX, int fail, const char *fmt, ...)
va_end(args);
}
static void __match_proto__(vmod_priv_free_f)
static void
priv_vcl_free(void *priv)
{
struct vmod_wadj_vcl *wa_vcl;
......@@ -108,8 +98,8 @@ priv_vcl_free(void *priv)
AZ(wa_vcl);
}
int __match_proto__(vmod_event_f)
event_function(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
int
vmod_event_function(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
{
struct vmod_wadj_vcl *wa_vcl;
......@@ -154,7 +144,7 @@ wadj_cfg_re(VRT_CTX, struct vmod_weightadjust_random *rr, VCL_BACKEND be,
if (vre == NULL) {
VERR(ctx, "%s.%s regex errror (%s) for %s pos %d",
rr->vd->dir->vcl_name, be->name, err,
rr->vd->dir->vcl_name, be->vcl_name, err,
weight_update, erroff);
}
......@@ -207,7 +197,7 @@ wadj_cfg_req(const struct backend *be, VCL_STRING url, VCL_STRING request,
return (ret);
}
VCL_VOID __match_proto__()
VCL_VOID
vmod_random__init(VRT_CTX, struct vmod_weightadjust_random **rrp,
const char *vcl_name, struct vmod_priv *priv)
{
......@@ -224,7 +214,7 @@ vmod_random__init(VRT_CTX, struct vmod_weightadjust_random **rrp,
VTAILQ_INIT(&rr->extra.props);
}
VCL_VOID __match_proto__()
VCL_VOID
vmod_random__fini(struct vmod_weightadjust_random **rrp)
{
struct vmod_weightadjust_random *rr;
......@@ -244,7 +234,7 @@ vmod_random__fini(struct vmod_weightadjust_random **rrp)
AZ(rr);
}
VCL_VOID __match_proto__()
VCL_VOID
vmod_random_add_backend(VRT_CTX, struct vmod_weightadjust_random *rr,
VCL_BACKEND vcl_be, VCL_REAL w, VCL_STRING weight_update, VCL_STRING url,
VCL_STRING request, VCL_DURATION timeout, VCL_DURATION interval,
......@@ -269,10 +259,10 @@ vmod_random_add_backend(VRT_CTX, struct vmod_weightadjust_random *rr,
CAST_OBJ_NOTNULL(be, vcl_be->priv, BACKEND_MAGIC);
if (weight_update == NULL || weight_update[0] == '\0') {
msg(ctx, 0, "vmod weightadjust director %s "
msg(ctx, "vmod weightadjust director %s "
"add_backend(%s) without weight update falls back "
"to standard behaviour",
rr->vd->dir->vcl_name, vcl_be->name);
rr->vd->dir->vcl_name, vcl_be->vcl_name);
goto no_weightadjust;
}
......@@ -285,7 +275,7 @@ vmod_random_add_backend(VRT_CTX, struct vmod_weightadjust_random *rr,
vdir_unlock(rr->vd);
if (u < nb) {
VERR(ctx, "director %s add_backend(%s): already exists",
rr->vd->dir->vcl_name, be->display_name);
rr->vd->dir->vcl_name, be->vcl_name);
return;
}
......@@ -322,14 +312,14 @@ vmod_random_add_backend(VRT_CTX, struct vmod_weightadjust_random *rr,
AZ(pthread_mutex_unlock(&wa_vcl->mtx));
no_weightadjust:
vdir_add_backend(rr->vd, vcl_be, w);
vdir_add_backend(ctx, rr->vd, vcl_be, w);
return;
err:
FREE_OBJ(prop);
}
VCL_VOID __match_proto__()
VCL_VOID
vmod_random_remove_backend(VRT_CTX,
struct vmod_weightadjust_random *rr, VCL_BACKEND vcl_be)
{
......@@ -375,5 +365,5 @@ vmod_random_remove_backend(VRT_CTX,
vdir_unlock(rr->vd);
no_weightadjust:
vdir_remove_backend(rr->vd, vcl_be, NULL);
vdir_remove_backend(ctx, rr->vd, vcl_be, NULL);
}
......@@ -2,7 +2,7 @@
# This document is copyright and licensed under the same conditions as
# the libvmod-weightadjust project. See LICENSE for details.
$Module weightadjust 3 Weightadjust VMOD
$Module weightadjust 3 "random director with runtime adjustable weight"
DESCRIPTION
===========
......
......@@ -45,7 +45,6 @@
#include "cache/cache.h"
#include "vrt.h"
#include "vre.h"
#include "vsa.h"
#include "vtim.h"
......@@ -58,7 +57,7 @@
#ifdef FIXME
#include "cache/cache_tcp_pool.h"
#else
int VTP_Open(const struct tcp_pool *, double tmo, const struct suckaddr **);
int VTP_Open(struct tcp_pool *, vtim_dur tmo, const void **, int*);
#endif
#include "vdir.h"
......@@ -68,24 +67,24 @@ int VTP_Open(const struct tcp_pool *, double tmo, const struct suckaddr **);
#define POKE_ERR(prop, fmt, ...) \
VSL(SLT_VCL_Error, 0, "vmod weightadjust error: poke %s.%s " fmt, \
(prop)->vd->dir->vcl_name, (prop)->be->display_name, \
(prop)->vd->dir->vcl_name, (prop)->be->vcl_name, \
__VA_ARGS__)
#define VPOKE_TRACE(prop, fmt, ...) \
VSL(SLT_Debug, 0, "vmod weightadjust: poke %s.%s " fmt, \
(prop)->vd->dir->vcl_name, (prop)->be->display_name, \
(prop)->vd->dir->vcl_name, (prop)->be->vcl_name, \
__VA_ARGS__)
#define POKE_TRACE(prop, str) \
VSL(SLT_Debug, 0, "vmod weightadjust: poke %s.%s " str, \
(prop)->vd->dir->vcl_name, (prop)->be->display_name)
(prop)->vd->dir->vcl_name, (prop)->be->vcl_name)
/* largely copied from vbp_poke */
static void
wadj_poke(const struct wadj_prop *prop, char *buf,
unsigned *len)
{
int s, tmo, i;
int s, tmo, i, err;
double t_start, t_now, t_end;
unsigned rlen;
struct pollfd pfda[1], *pfd = pfda;
......@@ -99,10 +98,11 @@ wadj_poke(const struct wadj_prop *prop, char *buf,
*buf = '\0';
*len = 0;
s = VTP_Open(prop->be->tcp_pool, t_end - t_now, &sa);
s = VTP_Open(prop->be->tcp_pool, t_end - t_now,
(const void **)&sa, &err);
if (s < 0) {
POKE_ERR(prop, "no connection %s", strerror(errno));
POKE_ERR(prop, "Open error %d (%s)", err, strerror(err));
return;
}
......