[master] 674c8df Overhaul the VSC api.
Poul-Henning Kamp
phk at FreeBSD.org
Fri Jun 16 09:46:05 CEST 2017
commit 674c8df775c1564d1b97ee14c8ac0f5d492d387b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Jun 16 07:43:17 2017 +0000
Overhaul the VSC api.
VSC_Iter() only provides instantaneous access to the point. If you want
to keep monitoring it (like varnishstat in curses mode) you must
VSC_Clone_Point() the returned points
diff --git a/bin/varnishtest/tests/u00005.vtc b/bin/varnishtest/tests/u00005.vtc
index 2653854..47a036e 100644
--- a/bin/varnishtest/tests/u00005.vtc
+++ b/bin/varnishtest/tests/u00005.vtc
@@ -26,7 +26,7 @@ shell "cmp -s ${p1_out} ${p2_out}"
shell -expect "MGT.uptime" \
"varnishstat -1 -n ${v1_name} -f ^MAIN*"
-shell -match "^MAIN" \
+shell -match "^MGT" \
"varnishstat -1 -n ${v1_name} -f ^foo"
shell -expect "Usage: varnishstat <options>" \
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index b46593e..01ea236 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -54,8 +54,6 @@ int VSC_Arg(struct vsm *vd, int arg, const char *opt);
*/
struct VSC_level_desc;
-struct VSC_type_desc;
-struct VSC_section;
struct VSC_point;
struct VSC_level_desc {
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index 298e9bb..a6935e4 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -53,26 +53,6 @@
#include "vsc_priv.h"
-struct vsc_vf {
- unsigned magic;
-#define VSC_VF_MAGIC 0x516519f8
- VTAILQ_ENTRY(vsc_vf) list;
- struct VSM_fantom fantom;
- char *ident;
- struct vjsn *vjsn;
- int order;
-};
-VTAILQ_HEAD(vsc_vf_head, vsc_vf);
-
-struct vsc_pt {
- unsigned magic;
-#define VSC_PT_MAGIC 0xa4ff159a
- VTAILQ_ENTRY(vsc_pt) list;
- char *name;
- struct VSC_point point;
-};
-VTAILQ_HEAD(vsc_pt_head, vsc_pt);
-
struct vsc_sf {
unsigned magic;
#define VSC_SF_MAGIC 0x558478dd
@@ -85,11 +65,8 @@ struct vsc {
unsigned magic;
#define VSC_MAGIC 0x3373554a
- struct vsc_vf_head vf_list;
- struct vsc_pt_head pt_list;
struct vsc_sf_head sf_list_include;
struct vsc_sf_head sf_list_exclude;
- struct VSM_fantom iter_fantom;
};
/*--------------------------------------------------------------------
@@ -114,13 +91,26 @@ static const size_t nlevels =
struct VSC_point *
VSC_Clone_Point(const struct VSC_point * const vp)
{
- return ((void*)(uintptr_t)vp);
+ struct VSC_point *pt;
+ char *p;
+
+ pt = calloc(sizeof *pt, 1);
+ AN(pt);
+ *pt = *vp;
+ p = strdup(pt->name); AN(p); pt->name = p;
+ p = strdup(pt->sdesc); AN(p); pt->sdesc = p;
+ p = strdup(pt->ldesc); AN(p); pt->ldesc = p;
+ return (pt);
}
void
VSC_Destroy_Point(struct VSC_point **p)
{
AN(p);
+ free(TRUST_ME((*p)->ldesc));
+ free(TRUST_ME((*p)->sdesc));
+ free(TRUST_ME((*p)->name));
+ free(*p);
*p = NULL;
}
@@ -135,8 +125,6 @@ vsc_setup(struct vsm *vd)
if (vsc == NULL) {
ALLOC_OBJ(vsc, VSC_MAGIC);
AN(vsc);
- VTAILQ_INIT(&vsc->vf_list);
- VTAILQ_INIT(&vsc->pt_list);
VTAILQ_INIT(&vsc->sf_list_include);
VTAILQ_INIT(&vsc->sf_list_exclude);
VSM_SetVSC(vd, vsc);
@@ -148,33 +136,6 @@ vsc_setup(struct vsm *vd)
/*--------------------------------------------------------------------*/
static void
-vsc_delete_vf_list(struct vsc_vf_head *head)
-{
- struct vsc_vf *vf;
-
- while (!VTAILQ_EMPTY(head)) {
- vf = VTAILQ_FIRST(head);
- CHECK_OBJ_NOTNULL(vf, VSC_VF_MAGIC);
- VTAILQ_REMOVE(head, vf, list);
- FREE_OBJ(vf);
- }
-}
-
-static void
-vsc_delete_pt_list(struct vsc_pt_head *head)
-{
- struct vsc_pt *pt;
-
- while (!VTAILQ_EMPTY(head)) {
- pt = VTAILQ_FIRST(head);
- CHECK_OBJ_NOTNULL(pt, VSC_PT_MAGIC);
- VTAILQ_REMOVE(head, pt, list);
- REPLACE(pt->name, NULL);
- FREE_OBJ(pt);
- }
-}
-
-static void
vsc_delete_sf_list(struct vsc_sf_head *head)
{
struct vsc_sf *sf;
@@ -195,8 +156,6 @@ VSC_Delete(struct vsc *vsc)
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
vsc_delete_sf_list(&vsc->sf_list_include);
vsc_delete_sf_list(&vsc->sf_list_exclude);
- vsc_delete_pt_list(&vsc->pt_list);
- vsc_delete_vf_list(&vsc->vf_list);
FREE_OBJ(vsc);
}
@@ -245,224 +204,132 @@ VSC_Arg(struct vsm *vd, int arg, const char *opt)
}
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ */
-static struct vsc_vf *
-vsc_add_vf(struct vsc *vsc, const struct VSM_fantom *fantom, int order)
+static int
+vsc_filter(struct vsm *vd, const char *nm)
{
- struct vsc_vf *vf, *vf2;
- struct vsb *vsb;
-
- ALLOC_OBJ(vf, VSC_VF_MAGIC);
- AN(vf);
- vf->fantom = *fantom;
- vsb = VSB_new_auto();
- AN(vsb);
- VSB_printf(vsb, "%s", vf->fantom.type);
- if (*vf->fantom.ident != '\0')
- VSB_printf(vsb, ".%s", vf->fantom.ident);
- AZ(VSB_finish(vsb));
- REPLACE(vf->ident, VSB_data(vsb));
- VSB_destroy(&vsb);
- vf->order = order;
+ struct vsc *vsc = vsc_setup(vd);
+ struct vsc_sf *sf;
- VTAILQ_FOREACH(vf2, &vsc->vf_list, list) {
- if (vf->order < vf2->order)
- break;
- }
- if (vf2 != NULL)
- VTAILQ_INSERT_BEFORE(vf2, vf, list);
- else
- VTAILQ_INSERT_TAIL(&vsc->vf_list, vf, list);
- return (vf);
+ VTAILQ_FOREACH(sf, &vsc->sf_list_exclude, list)
+ if (!fnmatch(sf->pattern, nm, 0))
+ return (1);
+ if (VTAILQ_EMPTY(&vsc->sf_list_include))
+ return (0);
+ VTAILQ_FOREACH(sf, &vsc->sf_list_include, list)
+ if (!fnmatch(sf->pattern, nm, 0))
+ return (0);
+ return (1);
}
/*--------------------------------------------------------------------
*/
-static void
-vsc_build_vf_list(struct vsm *vd)
+static int
+vsc_iter_elem(struct vsm *vd, const struct VSM_fantom *fantom,
+ const struct vjsn_val *vv, struct vsb *vsb, VSC_iter_f *func, void *priv)
{
- uint64_t u;
- struct vsc *vsc = vsc_setup(vd);
- const char *p;
- const char *e;
- struct vjsn *vj;
- struct vjsn_val *vv;
- struct vsc_vf *vf;
+ struct VSC_point point;
+ struct vjsn_val *vt;
- vsc_delete_pt_list(&vsc->pt_list);
- vsc_delete_vf_list(&vsc->vf_list);
+ memset(&point, 0, sizeof point);
- VSM_FOREACH(&vsc->iter_fantom, vd) {
- if (strcmp(vsc->iter_fantom.class, VSC_CLASS))
- continue;
- AZ(VSM_Map(vd, &vsc->iter_fantom));
- u = vbe64dec(vsc->iter_fantom.b);
- if (u == 0) {
- VRMB();
- usleep(100000);
- u = vbe64dec(vsc->iter_fantom.b);
- }
- assert(u > 0);
- p = (char*)vsc->iter_fantom.b + 8 + u;
- vj = vjsn_parse(p, &e);
- if (e != NULL) {
- fprintf(stderr, "%s\n", p);
- fprintf(stderr, "JSON ERROR %s\n", e);
- exit(2);
- }
- AN(vj);
- vv = vjsn_child(vj->value, "order");
- AN(vv);
- assert(vv->type == VJSN_NUMBER);
- vf = vsc_add_vf(vsc, &vsc->iter_fantom, atoi(vv->value));
- AN(vf);
- vf->vjsn = vj;
- // vjsn_dump(vf->vjsn, stderr);
- AZ(e);
- }
-}
+ vt = vjsn_child(vv, "name");
+ AN(vt);
+ assert(vt->type == VJSN_STRING);
-static void
-vsc_build_pt_list(struct vsm *vd)
-{
- struct vsc *vsc = vsc_setup(vd);
- struct vsc_vf *vf;
- struct vjsn_val *vve, *vv, *vt;
- struct vsc_pt *pt;
- struct vsb *vsb;
+ VSB_clear(vsb);
+ VSB_printf(vsb, "%s", fantom->type);
+ if (*fantom->ident)
+ VSB_printf(vsb, ".%s", fantom->ident);
+ VSB_printf(vsb, ".%s", vt->value);
+ AZ(VSB_finish(vsb));
- vsc_delete_pt_list(&vsc->pt_list);
- vsb = VSB_new_auto();
- AN(vsb);
+ if (vsc_filter(vd, VSB_data(vsb)))
+ return (0);
+
+ point.name = VSB_data(vsb);
+
+#define DOF(n, k) \
+ vt = vjsn_child(vv, k); \
+ AN(vt); \
+ assert(vt->type == VJSN_STRING); \
+ point.n = vt->value;
- VTAILQ_FOREACH(vf, &vsc->vf_list, list) {
- vve = vjsn_child(vf->vjsn->value, "elem");
- AN(vve);
- VTAILQ_FOREACH(vv, &vve->children, list) {
- ALLOC_OBJ(pt, VSC_PT_MAGIC);
- AN(pt);
-
- vt = vjsn_child(vv, "name");
- AN(vt);
- assert(vt->type == VJSN_STRING);
-
- VSB_clear(vsb);
- VSB_printf(vsb, "%s.%s", vf->ident, vt->value);
- AZ(VSB_finish(vsb));
- REPLACE(pt->name, VSB_data(vsb));
- pt->point.name = pt->name;
-
-#define DOF(n, k) \
- vt = vjsn_child(vv, k); \
- AN(vt); \
- assert(vt->type == VJSN_STRING); \
- pt->point.n = vt->value;
-
- DOF(ctype, "ctype");
- DOF(sdesc, "oneliner");
- DOF(ldesc, "docs");
+ DOF(ctype, "ctype");
+ DOF(sdesc, "oneliner");
+ DOF(ldesc, "docs");
#undef DOF
- vt = vjsn_child(vv, "type");
- AN(vt);
- assert(vt->type == VJSN_STRING);
-
- if (!strcmp(vt->value, "counter")) {
- pt->point.semantics = 'c';
- } else if (!strcmp(vt->value, "gauge")) {
- pt->point.semantics = 'g';
- } else if (!strcmp(vt->value, "bitmap")) {
- pt->point.semantics = 'b';
- } else {
- pt->point.semantics = '?';
- }
-
- vt = vjsn_child(vv, "format");
- AN(vt);
- assert(vt->type == VJSN_STRING);
-
- if (!strcmp(vt->value, "integer")) {
- pt->point.format = 'i';
- } else if (!strcmp(vt->value, "bytes")) {
- pt->point.format = 'B';
- } else if (!strcmp(vt->value, "bitmap")) {
- pt->point.format = 'b';
- } else if (!strcmp(vt->value, "duration")) {
- pt->point.format = 'd';
- } else {
- pt->point.format = '?';
- }
-
- pt->point.level = &level_info;
-
- vt = vjsn_child(vv, "index");
- AN(vt);
-
- pt->point.ptr = (volatile void*)
- ((volatile char*)vf->fantom.b + atoi(vt->value));
-
- VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
- }
+ vt = vjsn_child(vv, "type");
+ AN(vt);
+ assert(vt->type == VJSN_STRING);
+
+ if (!strcmp(vt->value, "counter")) {
+ point.semantics = 'c';
+ } else if (!strcmp(vt->value, "gauge")) {
+ point.semantics = 'g';
+ } else if (!strcmp(vt->value, "bitmap")) {
+ point.semantics = 'b';
+ } else {
+ point.semantics = '?';
}
- VSB_destroy(&vsb);
-}
-/*--------------------------------------------------------------------
- */
+ vt = vjsn_child(vv, "format");
+ AN(vt);
+ assert(vt->type == VJSN_STRING);
+
+ if (!strcmp(vt->value, "integer")) {
+ point.format = 'i';
+ } else if (!strcmp(vt->value, "bytes")) {
+ point.format = 'B';
+ } else if (!strcmp(vt->value, "bitmap")) {
+ point.format = 'b';
+ } else if (!strcmp(vt->value, "duration")) {
+ point.format = 'd';
+ } else {
+ point.format = '?';
+ }
-static int
-vsc_filter_match_pt(const struct vsc_sf *sf, const struct vsc_pt *pt)
-{
- return (!fnmatch(sf->pattern, pt->point.name, 0));
+ point.level = &level_info;
+
+ vt = vjsn_child(vv, "index");
+ AN(vt);
+
+ point.ptr = (volatile void*)
+ ((volatile char*)fantom->b + atoi(vt->value));
+
+ return (func(priv, &point));
}
-static void
-vsc_filter_pt_list(struct vsm *vd)
+static int
+vsc_iter_fantom(struct vsm *vd, const struct VSM_fantom *fantom,
+ struct vsb *vsb, VSC_iter_f *func, void *priv)
{
- struct vsc *vsc = vsc_setup(vd);
- struct vsc_pt_head tmplist;
- struct vsc_sf *sf;
- struct vsc_pt *pt, *pt2;
-
- if (VTAILQ_EMPTY(&vsc->sf_list_include) &&
- VTAILQ_EMPTY(&vsc->sf_list_exclude))
- return;
-
- VTAILQ_INIT(&tmplist);
-
- /* Include filters. Empty include filter list implies one that
- * matches everything. Points are sorted by the order of include
- * filter they match. */
- if (!VTAILQ_EMPTY(&vsc->sf_list_include)) {
- VTAILQ_FOREACH(sf, &vsc->sf_list_include, list) {
- CHECK_OBJ_NOTNULL(sf, VSC_SF_MAGIC);
- VTAILQ_FOREACH_SAFE(pt, &vsc->pt_list, list, pt2) {
- CHECK_OBJ_NOTNULL(pt, VSC_PT_MAGIC);
- if (vsc_filter_match_pt(sf, pt)) {
- VTAILQ_REMOVE(&vsc->pt_list,
- pt, list);
- VTAILQ_INSERT_TAIL(&tmplist,
- pt, list);
- }
- }
- }
- vsc_delete_pt_list(&vsc->pt_list);
- VTAILQ_CONCAT(&vsc->pt_list, &tmplist, list);
+ int i = 0;
+ const char *p;
+ const char *e;
+ struct vjsn *vj;
+ struct vjsn_val *vv, *vve;
+
+ p = (char*)fantom->b + 8 + vbe64dec(fantom->b);
+ vj = vjsn_parse(p, &e);
+ if (e != NULL) {
+ fprintf(stderr, "%s\n", p);
+ fprintf(stderr, "JSON ERROR %s\n", e);
+ exit(2);
}
-
- /* Exclude filters */
- VTAILQ_FOREACH(sf, &vsc->sf_list_exclude, list) {
- CHECK_OBJ_NOTNULL(sf, VSC_SF_MAGIC);
- VTAILQ_FOREACH_SAFE(pt, &vsc->pt_list, list, pt2) {
- CHECK_OBJ_NOTNULL(pt, VSC_PT_MAGIC);
- if (vsc_filter_match_pt(sf, pt)) {
- VTAILQ_REMOVE(&vsc->pt_list, pt, list);
- VTAILQ_INSERT_TAIL(&tmplist, pt, list);
- }
- }
+ AN(vj);
+ vve = vjsn_child(vj->value, "elem");
+ AN(vve);
+ VTAILQ_FOREACH(vv, &vve->children, list) {
+ i = vsc_iter_elem(vd, fantom, vv, vsb, func, priv);
+ if (i)
+ break;
}
- vsc_delete_pt_list(&tmplist);
+ // XXX: destroy vj
+ return (i);
}
/*--------------------------------------------------------------------
@@ -472,26 +339,33 @@ int
VSC_Iter(struct vsm *vd, struct VSM_fantom *fantom, VSC_iter_f *func,
void *priv)
{
- struct vsc *vsc = vsc_setup(vd);
- struct vsc_pt *pt;
- int i;
+ struct VSM_fantom ifantom;
+ uint64_t u;
+ int i = 0;
+ struct vsb *vsb;
- /* XXX: workaround: Force reload */
- if (1 || VSM_valid != VSM_StillValid(vd, &vsc->iter_fantom)) {
- /* Tell app that list will be nuked */
- (void)func(priv, NULL);
- vsc_build_vf_list(vd);
- vsc_build_pt_list(vd);
- vsc_filter_pt_list(vd);
- }
- if (fantom != NULL)
- *fantom = vsc->iter_fantom;
- VTAILQ_FOREACH(pt, &vsc->pt_list, list) {
- i = func(priv, &pt->point);
+ vsb = VSB_new_auto();
+ AN(vsb);
+ VSM_FOREACH(&ifantom, vd) {
+ if (strcmp(ifantom.class, VSC_CLASS))
+ continue;
+ AZ(VSM_Map(vd, &ifantom));
+ u = vbe64dec(ifantom.b);
+ if (u == 0) {
+ VRMB();
+ usleep(100000);
+ u = vbe64dec(ifantom.b);
+ }
+ assert(u > 0);
+ if (fantom != NULL)
+ *fantom = ifantom;
+ i = vsc_iter_fantom(vd, &ifantom, vsb, func, priv);
+ // AZ(VSM_Unmap(vd, &ifantom));
if (i)
- return (i);
+ break;
}
- return (0);
+ VSB_destroy(&vsb);
+ return (i);
}
/*--------------------------------------------------------------------
More information about the varnish-commit
mailing list