Skip to content

Commit

Permalink
Add VCL_IterDirector() for CLI to iterate over backends.
Browse files Browse the repository at this point in the history
(Replaces cache_backend_cfg.c::backend_find)
  • Loading branch information
bsdphk committed Nov 14, 2017
1 parent ce3c13b commit b9eaa41
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 78 deletions.
107 changes: 29 additions & 78 deletions bin/varnishd/cache/cache_backend_cfg.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ void
VBE_SetHappy(const struct backend *be, uint64_t happy) VBE_SetHappy(const struct backend *be, uint64_t happy)
{ {


Lck_Lock(&backends_mtx); Lck_Lock(&backends_mtx);
if (be->vsc != NULL) if (be->vsc != NULL)
be->vsc->happy = happy; be->vsc->happy = happy;
Lck_Unlock(&backends_mtx); Lck_Unlock(&backends_mtx);
} }


/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
Expand Down Expand Up @@ -264,88 +264,37 @@ VDI_Healthy(const struct director *d, double *changed)
WRONG("Wrong admin health"); 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__() static int __match_proto__(vcl_be_func)
do_list(struct cli *cli, struct backend *b, void *priv) do_list(struct cli *cli, struct director *d, void *priv)
{ {
int *probes; int *probes;
char time_str[VTIM_FORMAT_SIZE]; char time_str[VTIM_FORMAT_SIZE];
struct backend *be;


AN(priv); AN(priv);
probes = 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)"); VCLI_Out(cli, " %-20s", "Healthy (no probe)");
else { else {
if (b->director->health) if (d->health)
VCLI_Out(cli, " %-20s", "Healthy "); VCLI_Out(cli, " %-20s", "Healthy ");
else else
VCLI_Out(cli, " %-20s", "Sick "); 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); VCLI_Out(cli, " %s", time_str);


return (0); return (0);
Expand All @@ -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", VCLI_Out(cli, "%-30s %-10s %-20s %s", "Backend name", "Admin",
"Probe", "Last updated"); "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__() static int __match_proto__(vcl_be_func)
do_set_health(struct cli *cli, struct backend *b, void *priv) do_set_health(struct cli *cli, struct director *d, void *priv)
{ {
const struct vbe_ahealth *ah; const struct vbe_ahealth *ah;
unsigned prev; unsigned prev;


(void)cli; (void)cli;
AN(priv); AN(priv);
CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
if (d->admin_health == vbe_ah_deleted)
return (0);
ah = *(const struct vbe_ahealth **)priv; ah = *(const struct vbe_ahealth **)priv;
AN(ah); AN(ah);
CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC); prev = VDI_Healthy(d, NULL);
prev = VDI_Healthy(b->director, NULL); if (d->admin_health != vbe_ah_deleted)
if (b->director->admin_health != vbe_ah_deleted) d->admin_health = ah;
b->director->admin_health = ah; if (prev != VDI_Healthy(d, NULL))
if (prev != VDI_Healthy(b->director, NULL)) d->health_changed = VTIM_real();
b->director->health_changed = VTIM_real();


return (0); return (0);
} }
Expand All @@ -414,7 +365,7 @@ cli_backend_set_health(struct cli *cli, const char * const *av, void *priv)
VCLI_SetResult(cli, CLIS_PARAM); VCLI_SetResult(cli, CLIS_PARAM);
return; return;
} }
n = backend_find(cli, av[2], do_set_health, &ah); n = VCL_IterDirector(cli, av[2], do_set_health, &ah);
if (n == 0) { if (n == 0) {
VCLI_Out(cli, "No Backends matches"); VCLI_Out(cli, "No Backends matches");
VCLI_SetResult(cli, CLIS_PARAM); VCLI_SetResult(cli, CLIS_PARAM);
Expand Down
3 changes: 3 additions & 0 deletions bin/varnishd/cache/cache_varnishd.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ void VCL_Refresh(struct vcl **);
void VCL_Rel(struct vcl **); void VCL_Rel(struct vcl **);
const char *VCL_Return_Name(unsigned); 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 */ /* cache_vrt.c */
void VRTPRIV_init(struct vrt_privs *privs); void VRTPRIV_init(struct vrt_privs *privs);
Expand Down
64 changes: 64 additions & 0 deletions bin/varnishd/cache/cache_vcl.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@


#include <errno.h> #include <errno.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <fnmatch.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>


Expand Down Expand Up @@ -384,6 +385,69 @@ VCL_DelDirector(struct director *d)
d->destroy(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 static void
vcl_BackendEvent(const struct vcl *vcl, enum vcl_event_e e) vcl_BackendEvent(const struct vcl *vcl, enum vcl_event_e e)
{ {
Expand Down

0 comments on commit b9eaa41

Please sign in to comment.