[master] b9eaa41 Add VCL_IterDirector() for CLI to iterate over backends.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Nov 14 11:31:06 UTC 2017
commit b9eaa410c415786e9df1081dd8a7f0f6cc56aff6
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Nov 14 11:29:27 2017 +0000
Add VCL_IterDirector() for CLI to iterate over backends.
(Replaces cache_backend_cfg.c::backend_find)
diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index 3a77d88..733975c 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -196,10 +196,10 @@ void
VBE_SetHappy(const struct backend *be, uint64_t happy)
{
- Lck_Lock(&backends_mtx);
- if (be->vsc != NULL)
- be->vsc->happy = happy;
- Lck_Unlock(&backends_mtx);
+ Lck_Lock(&backends_mtx);
+ if (be->vsc != NULL)
+ be->vsc->happy = happy;
+ Lck_Unlock(&backends_mtx);
}
/*---------------------------------------------------------------------
@@ -264,88 +264,37 @@ VDI_Healthy(const struct director *d, double *changed)
WRONG("Wrong admin health");
}
-/*---------------------------------------------------------------------
- * A general function for finding backends and doing things with them.
- *
- * Return -1 on match-argument parse errors.
- *
- * If the call-back function returns negative, the search is terminated
- * and we relay that return value.
- *
- * Otherwise we return the number of matches.
- */
-
-typedef int bf_func(struct cli *cli, struct backend *b, void *priv);
-
-static int
-backend_find(struct cli *cli, const char *matcher, bf_func *func, void *priv)
-{
- int i, found = 0;
- struct vsb *vsb;
- struct vcl *vcc = NULL;
- struct backend *b;
-
- VCL_Refresh(&vcc);
- AN(vcc);
- vsb = VSB_new_auto();
- AN(vsb);
- if (matcher == NULL || *matcher == '\0' || !strcmp(matcher, "*")) {
- // all backends in active VCL
- VSB_printf(vsb, "%s.*", VCL_Name(vcc));
- } else if (strchr(matcher, '.') != NULL) {
- // use pattern as is
- VSB_cat(vsb, matcher);
- } else {
- // pattern applies to active vcl
- VSB_printf(vsb, "%s.%s", VCL_Name(vcc), matcher);
- }
- AZ(VSB_finish(vsb));
- Lck_Lock(&backends_mtx);
- VTAILQ_FOREACH(b, &backends, list) {
- if (b->director->admin_health == vbe_ah_deleted)
- continue;
- if (fnmatch(VSB_data(vsb), b->director->display_name, 0))
- continue;
- found++;
- i = func(cli, b, priv);
- if (i < 0) {
- found = i;
- break;
- }
- }
- Lck_Unlock(&backends_mtx);
- VSB_destroy(&vsb);
- VCL_Rel(&vcc);
- return (found);
-}
-
/*---------------------------------------------------------------------*/
-static int __match_proto__()
-do_list(struct cli *cli, struct backend *b, void *priv)
+static int __match_proto__(vcl_be_func)
+do_list(struct cli *cli, struct director *d, void *priv)
{
int *probes;
char time_str[VTIM_FORMAT_SIZE];
+ struct backend *be;
AN(priv);
probes = priv;
- CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+ CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+ CAST_OBJ_NOTNULL(be, d->priv, BACKEND_MAGIC);
+ if (d->admin_health == vbe_ah_deleted)
+ return (0);
- VCLI_Out(cli, "\n%-30s", b->director->display_name);
+ VCLI_Out(cli, "\n%-30s", d->display_name);
- VCLI_Out(cli, " %-10s", VBE_AdminHealth(b->director->admin_health));
+ VCLI_Out(cli, " %-10s", VBE_AdminHealth(d->admin_health));
- if (b->probe == NULL)
+ if (be->probe == NULL)
VCLI_Out(cli, " %-20s", "Healthy (no probe)");
else {
- if (b->director->health)
+ if (d->health)
VCLI_Out(cli, " %-20s", "Healthy ");
else
VCLI_Out(cli, " %-20s", "Sick ");
- VBP_Status(cli, b, *probes);
+ VBP_Status(cli, be, *probes);
}
- VTIM_format(b->director->health_changed, time_str);
+ VTIM_format(d->health_changed, time_str);
VCLI_Out(cli, " %s", time_str);
return (0);
@@ -372,27 +321,29 @@ cli_backend_list(struct cli *cli, const char * const *av, void *priv)
}
VCLI_Out(cli, "%-30s %-10s %-20s %s", "Backend name", "Admin",
"Probe", "Last updated");
- (void)backend_find(cli, av[2], do_list, &probes);
+ (void)VCL_IterDirector(cli, av[2], do_list, &probes);
}
/*---------------------------------------------------------------------*/
-static int __match_proto__()
-do_set_health(struct cli *cli, struct backend *b, void *priv)
+static int __match_proto__(vcl_be_func)
+do_set_health(struct cli *cli, struct director *d, void *priv)
{
const struct vbe_ahealth *ah;
unsigned prev;
(void)cli;
AN(priv);
+ CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+ if (d->admin_health == vbe_ah_deleted)
+ return (0);
ah = *(const struct vbe_ahealth **)priv;
AN(ah);
- CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
- prev = VDI_Healthy(b->director, NULL);
- if (b->director->admin_health != vbe_ah_deleted)
- b->director->admin_health = ah;
- if (prev != VDI_Healthy(b->director, NULL))
- b->director->health_changed = VTIM_real();
+ prev = VDI_Healthy(d, NULL);
+ if (d->admin_health != vbe_ah_deleted)
+ d->admin_health = ah;
+ if (prev != VDI_Healthy(d, NULL))
+ d->health_changed = VTIM_real();
return (0);
}
@@ -414,7 +365,7 @@ cli_backend_set_health(struct cli *cli, const char * const *av, void *priv)
VCLI_SetResult(cli, CLIS_PARAM);
return;
}
- n = backend_find(cli, av[2], do_set_health, &ah);
+ n = VCL_IterDirector(cli, av[2], do_set_health, &ah);
if (n == 0) {
VCLI_Out(cli, "No Backends matches");
VCLI_SetResult(cli, CLIS_PARAM);
diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h
index 61bd187..b7fb23c 100644
--- a/bin/varnishd/cache/cache_varnishd.h
+++ b/bin/varnishd/cache/cache_varnishd.h
@@ -214,6 +214,9 @@ void VCL_Refresh(struct vcl **);
void VCL_Rel(struct vcl **);
const char *VCL_Return_Name(unsigned);
+typedef int vcl_be_func(struct cli *, struct director *, void *);
+
+int VCL_IterDirector(struct cli *, const char *, vcl_be_func *, void *);
/* cache_vrt.c */
void VRTPRIV_init(struct vrt_privs *privs);
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 36b64c5..afb4ea0 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -32,6 +32,7 @@
#include <errno.h>
#include <dlfcn.h>
+#include <fnmatch.h>
#include <stdio.h>
#include <stdlib.h>
@@ -384,6 +385,69 @@ VCL_DelDirector(struct director *d)
d->destroy(d);
}
+static int
+vcl_iterdir(struct cli *cli, const char *pat, const struct vcl *vcl,
+ vcl_be_func *func, void *priv)
+{
+ int i, found = 0;
+ struct director *d;
+
+ VTAILQ_FOREACH(d, &vcl->director_list, vcl_list) {
+ if (fnmatch(pat, d->display_name, 0))
+ continue;
+ found++;
+ i = func(cli, d, priv);
+ if (i < 0)
+ return (i);
+ found += i;
+ }
+ return (found);
+}
+
+int
+VCL_IterDirector(struct cli *cli, const char *pat,
+ vcl_be_func *func, void *priv)
+{
+ int i, found = 0;
+ struct vsb *vsb;
+ struct vcl *vcl;
+
+ ASSERT_CLI();
+ vsb = VSB_new_auto();
+ AN(vsb);
+ if (pat == NULL || *pat == '\0' || !strcmp(pat, "*")) {
+ // all backends in active VCL
+ VSB_printf(vsb, "%s.*", VCL_Name(vcl_active));
+ vcl = vcl_active;
+ } else if (strchr(pat, '.') == NULL) {
+ // pattern applies to active vcl
+ VSB_printf(vsb, "%s.%s", VCL_Name(vcl_active), pat);
+ vcl = vcl_active;
+ } else {
+ // use pattern as is
+ VSB_cat(vsb, pat);
+ vcl = NULL;
+ }
+ AZ(VSB_finish(vsb));
+ Lck_Lock(&vcl_mtx);
+ if (vcl != NULL) {
+ found = vcl_iterdir(cli, VSB_data(vsb), vcl, func, priv);
+ } else {
+ VTAILQ_FOREACH(vcl, &vcl_head, list) {
+ i = vcl_iterdir(cli, VSB_data(vsb), vcl, func, priv);
+ if (i < 0) {
+ found = i;
+ break;
+ } else {
+ found += i;
+ }
+ }
+ }
+ Lck_Unlock(&vcl_mtx);
+ VSB_destroy(&vsb);
+ return (found);
+}
+
static void
vcl_BackendEvent(const struct vcl *vcl, enum vcl_event_e e)
{
More information about the varnish-commit
mailing list