[master] 2aeca56 First part of VSC API rework to capitalize on VSM improvements.

Poul-Henning Kamp phk at FreeBSD.org
Thu Sep 7 19:57:06 UTC 2017


commit 2aeca565355fe148edd21e42bb32fc43e371b1d8
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Sep 7 19:56:17 2017 +0000

    First part of VSC API rework to capitalize on VSM improvements.

diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index 7138ba4..c622cc7 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -42,8 +42,6 @@
 #include "vapi/voptget.h"
 #include "vapi/vsl.h"
 #include "vdef.h"
-#include "vnum.h"
-#include "vtim.h"
 #include "vut.h"
 
 #include "varnishstat.h"
@@ -83,7 +81,7 @@ do_xml(struct vsm *vsm, struct vsc *vsc)
 	now = time(NULL);
 	(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
 	printf("<varnishstat timestamp=\"%s\">\n", time_stamp);
-	(void)VSC_Iter(vsc, vsm, NULL, do_xml_cb, NULL);
+	(void)VSC_Iter(vsc, vsm, NULL, do_xml_cb, NULL, NULL);
 	printf("</varnishstat>\n");
 }
 
@@ -137,7 +135,7 @@ do_json(struct vsm *vsm, struct vsc *vsc)
 
 	(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
 	printf("  \"timestamp\": \"%s\",\n", time_stamp);
-	(void)VSC_Iter(vsc, vsm, NULL, do_json_cb, &jp);
+	(void)VSC_Iter(vsc, vsm, NULL, do_json_cb, NULL, &jp);
 	printf("\n}\n");
 }
 
@@ -201,8 +199,8 @@ do_once(struct vsm *vsm, struct vsc *vsc)
 	memset(&op, 0, sizeof op);
 	op.pad = 18;
 
-	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb_first, &op);
-	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb, &op);
+	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb_first, NULL, &op);
+	(void)VSC_Iter(vsc, vsm, NULL, do_once_cb, NULL, &op);
 }
 
 /*--------------------------------------------------------------------*/
@@ -232,7 +230,7 @@ list_fields(struct vsm *vsm, struct vsc *vsc)
 	printf("Field name                     Description\n");
 	printf("----------                     -----------\n");
 
-	(void)VSC_Iter(vsc, vsm, NULL, do_list_cb, NULL);
+	(void)VSC_Iter(vsc, vsm, NULL, do_list_cb, NULL, NULL);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c
index e61d2f7..fcc96ef 100644
--- a/bin/varnishstat/varnishstat_curses.c
+++ b/bin/varnishstat/varnishstat_curses.c
@@ -31,7 +31,6 @@
  * Statistics output program
  */
 
-
 #include "config.h"
 
 #include <stdlib.h>
@@ -313,7 +312,7 @@ build_pt_list_cb(void *priv, const struct VSC_point *vpt)
 }
 
 static void
-build_pt_list(struct vsc *vsc, struct vsm *vsm, struct vsm_fantom *fantom)
+build_pt_list(struct vsc *vsc, struct vsm *vsm)
 {
 	struct pt_priv pt_priv;
 	int i;
@@ -334,7 +333,7 @@ build_pt_list(struct vsc *vsc, struct vsm *vsm, struct vsm_fantom *fantom)
 	main_cache_hit = NULL;
 	main_cache_miss = NULL;
 
-	(void)VSC_Iter(vsc, vsm, fantom, build_pt_list_cb, &pt_priv);
+	(void)VSC_Iter(vsc, vsm, NULL, build_pt_list_cb, NULL, &pt_priv);
 	delete_pt_list();
 	AN(VTAILQ_EMPTY(&ptlist));
 	AZ(n_ptlist);
@@ -1050,7 +1049,6 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
 	long t;
 	int ch, initial = 1;
 	double now;
-	struct vsm_fantom f_iter = VSM_FANTOM_NULL;
 
 	interval = delay;
 
@@ -1073,7 +1071,7 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
 		    (VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED))) {
 			init_hitrate();
 			delete_pt_list();
-			build_pt_list(vsc, vd, &f_iter);
+			build_pt_list(vsc, vd);
 			initial = 0;
 		}
 
diff --git a/bin/varnishtest/vtc_varnish.c b/bin/varnishtest/vtc_varnish.c
index e81c054..d63b37e 100644
--- a/bin/varnishtest/vtc_varnish.c
+++ b/bin/varnishtest/vtc_varnish.c
@@ -849,8 +849,7 @@ varnish_vsc(const struct varnish *v, const char *arg)
 	dp.v = v;
 	dp.arg = arg;
 	(void)VSM_Status(v->vsm_vsc);
-
-	(void)VSC_Iter(v->vsc, v->vsm_vsc, NULL, do_stat_dump_cb, &dp);
+	(void)VSC_Iter(v->vsc, v->vsm_vsc, NULL, do_stat_dump_cb, NULL, &dp);
 }
 
 /**********************************************************************
@@ -915,8 +914,8 @@ varnish_expect(const struct varnish *v, char * const *av)
 	good = 0;
 	for (i = 0; i < 50; i++, (void)usleep(100000)) {
 		(void)VSM_Status(v->vsm_vsc);
-
-		good = VSC_Iter(v->vsc, v->vsm_vsc, NULL, do_expect_cb, &sp);
+		good = VSC_Iter(v->vsc, v->vsm_vsc,
+		    NULL, do_expect_cb, NULL, &sp);
 		if (!good) {
 			good = -2;
 			continue;
diff --git a/flint.lnt b/flint.lnt
index f77c78b..3fa3bf4 100644
--- a/flint.lnt
+++ b/flint.lnt
@@ -27,6 +27,7 @@
 
 ///////////////////////////////////////////////////////////////////////
 // General stylistic issues
+-e663		// Suspicious array to pointer conversion
 -e574		// Signed-unsigned mix with relational
 -e641		// Converting enum '...' to int
 -e716		// while(1) ...
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index 986259b..6f747f7 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -82,10 +82,11 @@ struct VSC_point *VSC_Clone_Point(const struct VSC_point * const);
 
 void VSC_Destroy_Point(struct VSC_point **);
 
+typedef void *VSC_new_f(void *priv, const struct VSC_point *const pt);
 typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt);
+typedef int VSC_destroy_f(void *priv, const struct VSC_point *const pt);
 
-int VSC_Iter(struct vsc *, struct vsm *, struct vsm_fantom *,
-    VSC_iter_f *func, void *priv);
+int VSC_Iter(struct vsc *, struct vsm *, VSC_new_f *, VSC_iter_f *, VSC_destroy_f *, void *priv);
 	/*
 	 * Iterate over all statistics counters, calling "func" for
 	 * each counter not suppressed by any "-f" arguments.
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index b5d1b00..b89c90c 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -195,4 +195,5 @@ LIBVARNISHAPI_1.7 {
 	VSM_Dup;
 	VSC_New;
 	VSC_Destroy;
+	VSC_Iter2;
 } LIBVARNISHAPI_1.0;
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index 47a5ccd..6ccbc9d 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -59,12 +59,28 @@ struct vsc_sf {
 };
 VTAILQ_HEAD(vsc_sf_head, vsc_sf);
 
+struct vsc_pt {
+	struct VSC_point	point;
+	char			*name;
+};
+
+struct vsc_seg {
+	unsigned		magic;
+#define VSC_SEG_MAGIC		0x801177d4
+	VTAILQ_ENTRY(vsc_seg)	list;
+	struct vsm_fantom	fantom[1];
+	struct vjsn 		*vj;
+	unsigned		npoints;
+	struct vsc_pt		*points;
+};
+
 struct vsc {
 	unsigned		magic;
 #define VSC_MAGIC		0x3373554a
 
 	struct vsc_sf_head	sf_list_include;
 	struct vsc_sf_head	sf_list_exclude;
+	VTAILQ_HEAD(,vsc_seg)	segs;
 };
 
 /*--------------------------------------------------------------------
@@ -81,8 +97,7 @@ static const struct VSC_level_desc * const levels[] = {
 #undef VSC_LEVEL_F
 };
 
-static const size_t nlevels =
-    sizeof(levels)/sizeof(*levels);
+static const size_t nlevels = sizeof(levels)/sizeof(*levels);
 
 /*--------------------------------------------------------------------*/
 
@@ -124,6 +139,7 @@ VSC_New(void)
 		return (vsc);
 	VTAILQ_INIT(&vsc->sf_list_include);
 	VTAILQ_INIT(&vsc->sf_list_exclude);
+	VTAILQ_INIT(&vsc->segs);
 	return (vsc);
 }
 
@@ -220,15 +236,20 @@ vsc_filter(const struct vsc *vsc, const char *nm)
 /*--------------------------------------------------------------------
  */
 
+static void
+vsc_clean_point(struct vsc_pt *point)
+{
+	REPLACE(point->name, NULL);
+}
+
 static int
-vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
-    const struct vjsn_val *vv, struct vsb *vsb, VSC_iter_f *func, void *priv)
+vsc_fill_point(const struct vsc *vsc, const struct vsm_fantom *fantom,
+    const struct vjsn_val *vv, struct vsb *vsb, struct vsc_pt *point)
 {
-	struct VSC_point	point;
 	struct vjsn_val *vt;
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
-	memset(&point, 0, sizeof point);
+	memset(point, 0, sizeof *point);
 
 	vt = vjsn_child(vv, "name");
 	AN(vt);
@@ -241,13 +262,15 @@ vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
 	if (vsc_filter(vsc, VSB_data(vsb)))
 		return (0);
 
-	point.name = VSB_data(vsb);
+	point->name = strdup(VSB_data(vsb));
+	AN(point->name);
+	point->point.name = point->name;
 
 #define DOF(n, k)				\
 	vt = vjsn_child(vv, k);			\
 	AN(vt);					\
 	assert(vt->type == VJSN_STRING);	\
-	point.n = vt->value;
+	point->point.n = vt->value;
 
 	DOF(ctype, "ctype");
 	DOF(sdesc, "oneliner");
@@ -258,13 +281,13 @@ vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
 	assert(vt->type == VJSN_STRING);
 
 	if (!strcmp(vt->value, "counter")) {
-		point.semantics = 'c';
+		point->point.semantics = 'c';
 	} else if (!strcmp(vt->value, "gauge")) {
-		point.semantics = 'g';
+		point->point.semantics = 'g';
 	} else if (!strcmp(vt->value, "bitmap")) {
-		point.semantics = 'b';
+		point->point.semantics = 'b';
 	} else {
-		point.semantics = '?';
+		point->point.semantics = '?';
 	}
 
 	vt = vjsn_child(vv, "format");
@@ -272,15 +295,15 @@ vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
 	assert(vt->type == VJSN_STRING);
 
 	if (!strcmp(vt->value, "integer")) {
-		point.format = 'i';
+		point->point.format = 'i';
 	} else if (!strcmp(vt->value, "bytes")) {
-		point.format = 'B';
+		point->point.format = 'B';
 	} else if (!strcmp(vt->value, "bitmap")) {
-		point.format = 'b';
+		point->point.format = 'b';
 	} else if (!strcmp(vt->value, "duration")) {
-		point.format = 'd';
+		point->point.format = 'd';
 	} else {
-		point.format = '?';
+		point->point.format = '?';
 	}
 
 	vt = vjsn_child(vv, "level");
@@ -288,11 +311,11 @@ vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
 	assert(vt->type == VJSN_STRING);
 
 	if (!strcmp(vt->value, "info"))  {
-		point.level = &level_info;
+		point->point.level = &level_info;
 	} else if (!strcmp(vt->value, "diag")) {
-		point.level = &level_diag;
+		point->point.level = &level_diag;
 	} else if (!strcmp(vt->value, "debug")) {
-		point.level = &level_debug;
+		point->point.level = &level_debug;
 	} else {
 		WRONG("Illegal level");
 	}
@@ -300,80 +323,131 @@ vsc_iter_elem(const struct vsc *vsc, const struct vsm_fantom *fantom,
 	vt = vjsn_child(vv, "index");
 	AN(vt);
 
-	point.ptr = (volatile void*)
+	point->point.ptr = (volatile void*)
 	    ((volatile char*)fantom->b + atoi(vt->value));
+	return (1);
+}
+
+static void
+vsc_del_seg(struct vsm *vsm, struct vsc_seg *sp)
+{
+	unsigned u;
 
-	return (func(priv, &point));
+	AN(vsm);
+	CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
+	AZ(VSM_Unmap(vsm, sp->fantom));
+	vjsn_delete(&sp->vj);
+	for(u = 0; u < sp->npoints; u++)
+		vsc_clean_point(&sp->points[u]);
+	free(sp->points);
+	FREE_OBJ(sp);
 }
 
-static int
-vsc_iter_fantom(const struct vsc *vsc, const struct vsm_fantom *fantom,
-    struct vsb *vsb, VSC_iter_f *func, void *priv)
+static struct vsc_seg *
+vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
 {
-	int i = 0;
+	struct vsc_seg *sp;
+	uint64_t u;
+	unsigned j;
 	const char *p;
 	const char *e;
-	struct vjsn *vj;
 	struct vjsn_val *vv, *vve;
+	struct vsb *vsb;
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
+	AN(vsm);
+
+	ALLOC_OBJ(sp, VSC_SEG_MAGIC);
+	AN(sp);
+	*sp->fantom = *fp;
+	AZ(VSM_Map(vsm, sp->fantom));
 
-	p = (char*)fantom->b + 8 + vbe64dec(fantom->b);
-	assert (p < (char*)fantom->e);
-	vj = vjsn_parse(p, &e);
+	u = vbe64dec(sp->fantom->b);
+	if (u == 0) {
+		VRMB();
+		usleep(100000);
+		u = vbe64dec(sp->fantom->b);
+	}
+	assert(u > 0);
+	p = (char*)sp->fantom->b + 8 + u;
+	assert (p < (char*)sp->fantom->e);
+	sp->vj = vjsn_parse(p, &e);
 	XXXAZ(e);
-	AN(vj);
-	vve = vjsn_child(vj->value, "elem");
+	vve = vjsn_child(sp->vj->value, "elements");
 	AN(vve);
-	VTAILQ_FOREACH(vv, &vve->children, list) {
-		i = vsc_iter_elem(vsc, fantom, vv, vsb, func, priv);
-		if (i)
-			break;
+	sp->npoints = strtoul(vve->value, NULL, 0);
+	sp->points = calloc(sp->npoints, sizeof *sp->points);
+	AN(sp->points);
+	vsb = VSB_new_auto();
+	AN(vsb);
+	j = 0;
+	vve = vjsn_child(sp->vj->value, "elem");
+	AN(vve);
+	VTAILQ_FOREACH(vv, &vve->children, list)
+		(void)vsc_fill_point(vsc, sp->fantom, vv, vsb, sp->points + j++);
+	VSB_destroy(&vsb);
+	AN(sp->vj);
+	return (sp);
+}
+
+static int
+vsc_iter_seg(const struct vsc_seg *sp, VSC_iter_f *fiter, void *priv)
+{
+	unsigned u;
+	int i = 0;
+
+	CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
+	AN(fiter);
+	for(u = 0; u < sp->npoints; u++) {
+		if (sp->points[u].name != NULL) {
+			i = fiter(priv, &sp->points[u].point);
+			if (i)
+				break;
+		}
 	}
-	vjsn_delete(&vj);
 	return (i);
 }
 
-/*--------------------------------------------------------------------
- */
-
-int __match_proto__()	// We don't want vsc to be const
-VSC_Iter(struct vsc *vsc, struct vsm *vsm, struct vsm_fantom *f,
-    VSC_iter_f *func, void *priv)
+int
+VSC_Iter(struct vsc *vsc, struct vsm *vsm,
+    VSC_new_f *fnew, VSC_iter_f *fiter, VSC_destroy_f *fdestroy, void *priv)
 {
-	struct vsm_fantom	ifantom;
-	uint64_t u;
+	struct vsm_fantom ifantom;
+	struct vsc_seg *sp, *sp2;
 	int i = 0;
-	struct vsb *vsb;
 
 	CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
 	AN(vsm);
-	vsb = VSB_new_auto();
-	AN(vsb);
+	(void)fnew;
+	(void)fdestroy;
+	sp = VTAILQ_FIRST(&vsc->segs);
 	VSM_FOREACH(&ifantom, vsm) {
 		if (strcmp(ifantom.class, VSC_CLASS))
 			continue;
-		AZ(VSM_Map(vsm, &ifantom));
-		u = vbe64dec(ifantom.b);
-		if (u == 0) {
-			VRMB();
-			usleep(100000);
-			u = vbe64dec(ifantom.b);
+		while (sp != NULL &&
+		    (strcmp(ifantom.ident, sp->fantom->ident) ||
+		    VSM_StillValid(vsm, sp->fantom) != VSM_valid)) {
+			sp2 = sp;
+			sp = VTAILQ_NEXT(sp, list);
+			VTAILQ_REMOVE(&vsc->segs, sp2, list);
+			vsc_del_seg(vsm, sp2);
 		}
-		assert(u > 0);
-		i = vsc_iter_fantom(vsc, &ifantom, vsb, func, priv);
-		if (f != NULL) {
-			*f = ifantom;
+		if (sp != NULL) {
+			i = vsc_iter_seg(sp, fiter, priv);
+			sp = VTAILQ_NEXT(sp, list);
 		} else {
-			AZ(VSM_Unmap(vsm, &ifantom));
+			sp = vsc_add_seg(vsc, vsm, &ifantom);
+			VTAILQ_INSERT_TAIL(&vsc->segs, sp, list);
+			i = vsc_iter_seg(sp, fiter, priv);
+			sp = NULL;
 		}
 		if (i)
 			break;
 	}
-	VSB_destroy(&vsb);
 	return (i);
 }
 
+
 /*--------------------------------------------------------------------
  */
 
@@ -397,4 +471,3 @@ VSC_ChangeLevel(const struct VSC_level_desc *old, int chg)
 		i = 0;
 	return (levels[i]);
 }
-


More information about the varnish-commit mailing list