Hi, It turned out you couldn't properly create backends dynamically, or at least remove them. Please find attached a patch set that fixes that, and adds a "director" capability to the debug vmod with an initial test case. This is still incomplete, and I want to push this further. For example I've created a Backend_added log record, but nothing for deletion.
Before I do anything else, I'll wait for feedback :) Cheers, Dridi PS. today I'm doing training and the customer is blocking IRC On Thu, Mar 19, 2015 at 12:26 AM, Dridi Boukelmoune <[email protected]> wrote: > Hi, > > As discussed briefly during the last VDD in Hamburg, phk said that > everything should be in place to allow dynamic backend allocations > (ie. outside of pure VCL). > > I looked quickly at the code right after the VDD with fgs, and at the > time there was a couple backend-related commits that had just showed > up. But I came to the conclusion that you could only add/remove a > backend and a tcp pool in vcl_init and vcl_fini. > > Those operations can only be triggered by the CLI thread right now, so > it's not possible to programmatically add a backend at any arbitrary > time and still benefit from the existing facilities (stats, probes, > connection pools, etc). > > I haven't made any progress since then, so I'm asking first what the > comment was about. I think I misunderstood what it was supposed to > mean at the time. > > Also please find attached a tiny patch removing leftovers I found after the > VDD. > > Regards, > Dridi
From 291a80a90ce8eed2eedcdca3b3ba5a7a118400be Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune <[email protected]> Date: Mon, 13 Apr 2015 09:31:09 +0200 Subject: [PATCH 1/3] Remove unsused context from VRT backend functions --- bin/varnishd/cache/cache_backend.c | 6 ++---- include/vrt.h | 4 ++-- lib/libvcc/vcc_backend.c | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index a02a7d8..3ec17d7 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -319,14 +319,13 @@ VRT_init_vbe(VRT_CTX, struct director **dp, const struct vrt_backend *vrt) } void -VRT_event_vbe(VRT_CTX, enum vcl_event_e ev, const struct director *d, +VRT_event_vbe(enum vcl_event_e ev, const struct director *d, const struct vrt_backend *vrt) { struct backend *be; ASSERT_CLI(); (void)ev; - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC); assert(d->priv2 == vrt); @@ -351,13 +350,12 @@ VRT_event_vbe(VRT_CTX, enum vcl_event_e ev, const struct director *d, } void -VRT_fini_vbe(VRT_CTX, struct director **dp, const struct vrt_backend *vrt) +VRT_fini_vbe(struct director **dp, const struct vrt_backend *vrt) { struct director *d; struct backend *be; ASSERT_CLI(); - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(dp); AN(*dp); CHECK_OBJ_NOTNULL(vrt, VRT_BACKEND_MAGIC); diff --git a/include/vrt.h b/include/vrt.h index e034f91..b5442d8 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -234,10 +234,10 @@ void VRT_synth_page(VRT_CTX, const char *, ...); /* Backend related */ void VRT_init_vbe(VRT_CTX, struct director **, const struct vrt_backend *); #ifdef VCL_RET_MAX -void VRT_event_vbe(VRT_CTX, enum vcl_event_e, const struct director *, +void VRT_event_vbe(enum vcl_event_e, const struct director *, const struct vrt_backend *); #endif -void VRT_fini_vbe(VRT_CTX, struct director **, const struct vrt_backend *); +void VRT_fini_vbe(struct director **, const struct vrt_backend *); /* Suckaddr related */ int VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst); diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index b937404..d475dc6 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -418,10 +418,10 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be) "\tVRT_init_vbe(ctx, &VGCDIR(%s), &vgc_dir_priv_%s);", vgcname, vgcname); VSB_printf(ifp->fin, - "\tVRT_fini_vbe(ctx, &VGCDIR(%s), &vgc_dir_priv_%s);", + "\tVRT_fini_vbe(&VGCDIR(%s), &vgc_dir_priv_%s);", vgcname, vgcname); VSB_printf(ifp->event, - "\tVRT_event_vbe(ctx, ev, VGCDIR(%s), &vgc_dir_priv_%s);", + "\tVRT_event_vbe(ev, VGCDIR(%s), &vgc_dir_priv_%s);", vgcname, vgcname); tl->ndirector++; } -- 2.1.0
From a81e99559417bd9f3cc86fbe5cfd99c1a78943cc Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune <[email protected]> Date: Mon, 13 Apr 2015 09:31:53 +0200 Subject: [PATCH 2/3] Add a new Backend_added log event --- bin/varnishd/cache/cache_backend_cfg.c | 3 +++ include/tbl/vsl_tags.h | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c index 08b58d3..8058b6c 100644 --- a/bin/varnishd/cache/cache_backend_cfg.c +++ b/bin/varnishd/cache/cache_backend_cfg.c @@ -120,6 +120,9 @@ VBE_AddBackend(const char *vcl, const struct vrt_backend *vb) VTAILQ_INSERT_TAIL(&backends, b, list); VSC_C_main->n_backend++; + + VSL(SLT_Backend_added, 0, "%s %s", b->vcl_name, b->display_name); + return (b); } diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h index ecb2683..e5aaa22 100644 --- a/include/tbl/vsl_tags.h +++ b/include/tbl/vsl_tags.h @@ -373,6 +373,16 @@ SLTM(Backend_health, 0, "Backend health check", "\n" ) +SLTM(Backend_added, 0, "Backend added", + "Logged when a backend is created.\n\n" + "The format is::\n\n" + "\t%s %s\n" + "\t| |\n" + "\t| +- Backend display name\n" + "\t+---- VCL name\n" + "\n" +) + SLTM(VCL_Log, 0, "Log statement from VCL", "User generated log messages insert from VCL through std.log()" ) -- 2.1.0
From ca0a47eb4da3d46889f7a1ecf6ee0d167f361bd0 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune <[email protected]> Date: Mon, 13 Apr 2015 09:34:12 +0200 Subject: [PATCH 3/3] Add a single-backend director to the debug vmod And test dynamic backend creation. --- bin/varnishtest/tests/d00007.vtc | 37 ++++++++++++ lib/libvmod_debug/Makefile.am | 3 +- lib/libvmod_debug/vmod.vcc | 8 +++ lib/libvmod_debug/vmod_debug_dyn.c | 116 +++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 bin/varnishtest/tests/d00007.vtc create mode 100644 lib/libvmod_debug/vmod_debug_dyn.c diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc new file mode 100644 index 0000000..4695514 --- /dev/null +++ b/bin/varnishtest/tests/d00007.vtc @@ -0,0 +1,37 @@ +varnishtest "Test dynamic backends" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl { + import ${vmod_debug}; + + backend dummy { + .host = "${bad_ip}"; + } + + sub vcl_init { + new s1 = debug.dyn("${s1_addr}", "${s1_port}"); + } + + sub vcl_recv { + set req.backend_hint = s1.backend(); + } +} -start + +logexpect l1 -v v1 -g raw -d { + expect * 0 Backend_added "dummy vcl1.dummy" + expect * 0 Backend_added "s1 vcl1.s1" +} -start + +varnish v1 -expect MAIN.n_backend == 2 + +logexpect l1 -wait + +client c1 { + txreq + rxresp + expect resp.status == 200 +} -run diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am index d189102..c9e05f5 100644 --- a/lib/libvmod_debug/Makefile.am +++ b/lib/libvmod_debug/Makefile.am @@ -17,6 +17,7 @@ libvmod_debug_la_LDFLAGS = $(AM_LDFLAGS) -module -export-dynamic -avoid-version libvmod_debug_la_SOURCES = \ vmod_debug.c \ + vmod_debug_dyn.c \ vmod_debug_obj.c nodist_libvmod_debug_la_SOURCES = \ @@ -24,7 +25,7 @@ nodist_libvmod_debug_la_SOURCES = \ vcc_if.h # BUILT_SOURCES is only a hack and dependency tracking does not help for the first build -vmod_debug.lo vmod_debug_obj.lo: vcc_if.h +vmod_debug.lo vmod_debug_dyn.lo vmod_debug_obj.lo: vcc_if.h vcc_if.c vcc_if.h vmod_debug.rst vmod_debug.man.rst: $(vmodtool) $(vmod_srcdir)/vmod.vcc @PYTHON@ $(vmodtool) $(vmodtoolargs) $(vmod_srcdir)/vmod.vcc diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc index 434ee78..dedddff 100644 --- a/lib/libvmod_debug/vmod.vcc +++ b/lib/libvmod_debug/vmod.vcc @@ -101,3 +101,11 @@ $Function INT vre_limit() $Function VOID register_exp_callback(PRIV_VCL) Register the vmod to receive expiry callbacks + +$Object dyn(STRING addr, STRING port) + +Dynamically create a single-backend director + +$Method BACKEND .backend() + +Return the dynamic backend. diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c new file mode 100644 index 0000000..342ca5e --- /dev/null +++ b/lib/libvmod_debug/vmod_debug_dyn.c @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2015 Varnish Software AS + * All rights reserved. + * + * Author: Poul-Henning Kamp <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" + +#include <stdlib.h> + +#include "cache/cache.h" +#include "cache/cache_backend.h" + +#include "vcl.h" +#include "vrt.h" +#include "vsa.h" +#include "vss.h" +#include "vcc_if.h" + +struct vmod_debug_dyn { + unsigned magic; +#define VMOD_DEBUG_DYN_MAGIC 0x9b77ccbd + struct suckaddr *addr; + char *port; + struct director *dir; + struct vrt_backend vrt; +}; + +static int __match_proto__(vss_resolved_f) +vmod_dyn_cb(void *priv, const struct suckaddr *sa) +{ + struct vmod_debug_dyn *o; + + CAST_OBJ_NOTNULL(o, priv, VMOD_DEBUG_DYN_MAGIC); + AN(o->addr = VSA_Clone(sa)); + o->vrt.ipv4_suckaddr = o->addr; + return 1; +} + +VCL_VOID +vmod_dyn__init(VRT_CTX, struct vmod_debug_dyn **op, + const char *vcl_name, VCL_STRING addr, VCL_STRING port) +{ + struct vmod_debug_dyn *o; + const char *err; + + ASSERT_CLI(); + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + AN(op); + AZ(*op); + AN(addr); + AN(port); + + ALLOC_OBJ(o, VMOD_DEBUG_DYN_MAGIC); + AN(o); + o->port = strdup(port); + o->vrt.magic = VRT_BACKEND_MAGIC; + o->vrt.vcl_name = vcl_name; + o->vrt.ipv4_addr = addr; + o->vrt.port = o->port; + assert(VSS_resolver(addr, port, vmod_dyn_cb, o, &err) == 1); + + VRT_init_vbe(ctx, &o->dir, &o->vrt); + if (o->dir) + *op = o; + + VRT_event_vbe(VCL_EVENT_WARM, o->dir, &o->vrt); +} + +VCL_VOID +vmod_dyn__fini(struct vmod_debug_dyn **op) +{ + struct vmod_debug_dyn *o; + + AN(op); + CAST_OBJ_NOTNULL(o, *op, VMOD_DEBUG_DYN_MAGIC); + CHECK_OBJ_NOTNULL(&o->vrt, VRT_BACKEND_MAGIC); + AN(o->dir); + VRT_fini_vbe(&o->dir, &o->vrt); + AZ(o->dir); + free(o->addr); + free(o->port); + FREE_OBJ(o); + *op = NULL; +} + +VCL_BACKEND __match_proto__() +vmod_dyn_backend(VRT_CTX, struct vmod_debug_dyn *op) +{ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + CHECK_OBJ_NOTNULL(op, VMOD_DEBUG_DYN_MAGIC); + AN(op->dir); + return op->dir; +} -- 2.1.0
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
