[master] 1f3fbd8 Make VSC/varnishstat sorta-work again.
Poul-Henning Kamp
phk at varnish-cache.org
Wed Nov 23 22:11:13 CET 2011
commit 1f3fbd8eb67062fe211e731cccaf7251b74d2840
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Nov 23 08:57:48 2011 +0000
Make VSC/varnishstat sorta-work again.
diff --git a/bin/varnishstat/varnishstat.c b/bin/varnishstat/varnishstat.c
index 2fe7ffb..5d9226f 100644
--- a/bin/varnishstat/varnishstat.c
+++ b/bin/varnishstat/varnishstat.c
@@ -52,7 +52,9 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
(void)priv;
- assert(!strcmp(pt->fmt, "uint64_t"));
+ if (pt == NULL)
+ return (0);
+ assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
printf("\t<stat>\n");
@@ -60,10 +62,10 @@ do_xml_cb(void *priv, const struct VSC_point * const pt)
printf("\t\t<type>%s</type>\n", pt->class);
if (strcmp(pt->ident, ""))
printf("\t\t<ident>%s</ident>\n", pt->ident);
- printf("\t\t<name>%s</name>\n", pt->name);
+ printf("\t\t<name>%s</name>\n", pt->desc->name);
printf("\t\t<value>%ju</value>\n", val);
- printf("\t\t<flag>%c</flag>\n", pt->flag);
- printf("\t\t<description>%s</description>\n", pt->desc);
+ printf("\t\t<flag>%c</flag>\n", pt->desc->flag);
+ printf("\t\t<description>%s</description>\n", pt->desc->sdesc);
printf("\t</stat>\n");
return (0);
}
@@ -91,9 +93,11 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
int *jp;
- jp = priv;
+ if (pt == NULL)
+ return (0);
- assert(!strcmp(pt->fmt, "uint64_t"));
+ jp = priv;
+ assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
if (*jp) *jp = 0; else printf(",\n");
@@ -104,15 +108,15 @@ do_json_cb(void *priv, const struct VSC_point * const pt)
printf("%s.", pt->class);
if (pt->ident[0])
printf("%s.", pt->ident);
- printf("%s\": {", pt->name);
+ printf("%s\": {", pt->desc->name);
if (strcmp(pt->class, "")) printf("\"type\": \"%s\", ", pt->class);
if (strcmp(pt->ident, "")) printf("\"ident\": \"%s\", ", pt->ident);
printf("\"value\": %ju, ", val);
- printf("\"flag\": \"%c\", ", pt->flag);
- printf("\"description\": \"%s\"", pt->desc);
+ printf("\"flag\": \"%c\", ", pt->desc->flag);
+ printf("\"description\": \"%s\"", pt->desc->sdesc);
printf("}");
if (*jp) printf("\n");
@@ -153,22 +157,24 @@ do_once_cb(void *priv, const struct VSC_point * const pt)
uint64_t val;
int i;
+ if (pt == NULL)
+ return (0);
op = priv;
- assert(!strcmp(pt->fmt, "uint64_t"));
+ assert(!strcmp(pt->desc->fmt, "uint64_t"));
val = *(const volatile uint64_t*)pt->ptr;
i = 0;
if (strcmp(pt->class, ""))
i += printf("%s.", pt->class);
if (strcmp(pt->ident, ""))
i += printf("%s.", pt->ident);
- i += printf("%s", pt->name);
+ i += printf("%s", pt->desc->name);
if (i > op->pad)
op->pad = i + 1;
printf("%*.*s", op->pad - i, op->pad - i, "");
- if (pt->flag == 'a' || pt->flag == 'c')
- printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc);
+ if (pt->desc->flag == 'a' || pt->desc->flag == 'c')
+ printf("%12ju %12.2f %s\n", val, val / op->up, pt->desc->sdesc);
else
- printf("%12ju %12s %s\n", val, ". ", pt->desc);
+ printf("%12ju %12s %s\n", val, ". ", pt->desc->sdesc);
return (0);
}
@@ -197,10 +203,10 @@ do_list_cb(void *priv, const struct VSC_point * const pt)
i += fprintf(stderr, "%s.", pt->class);
if (strcmp(pt->ident, ""))
i += fprintf(stderr, "%s.", pt->ident);
- i += fprintf(stderr, "%s", pt->name);
+ i += fprintf(stderr, "%s", pt->desc->name);
if (i < 30)
fprintf(stderr, "%*s", i - 30, "");
- fprintf(stderr, " %s\n", pt->desc);
+ fprintf(stderr, " %s\n", pt->desc->sdesc);
return (0);
}
@@ -253,7 +259,6 @@ main(int argc, char * const *argv)
int delay = 1, once = 0, xml = 0, json = 0, do_repeat = 0;
vd = VSM_New();
- VSC_Setup(vd);
while ((c = getopt(argc, argv, VSC_ARGS "1f:lVw:xjt:")) != -1) {
switch (c) {
@@ -261,8 +266,6 @@ main(int argc, char * const *argv)
once = 1;
break;
case 'l':
- if (VSC_Open(vd, 1))
- exit(1);
list_fields(vd);
exit(0);
case 'V':
@@ -285,9 +288,6 @@ main(int argc, char * const *argv)
}
}
- if (VSC_Open(vd, 1))
- exit(1);
-
VSC_C_main = VSC_Main(vd);
AN(VSC_C_main);
diff --git a/bin/varnishstat/varnishstat_curses.c b/bin/varnishstat/varnishstat_curses.c
index 9fa6b82..d4e714c 100644
--- a/bin/varnishstat/varnishstat_curses.c
+++ b/bin/varnishstat/varnishstat_curses.c
@@ -81,7 +81,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
char buf[128];
(void)priv;
- assert(!strcmp(sp->fmt, "uint64_t"));
+ if (sp == NULL)
+ return (0);
+ assert(!strcmp(sp->desc->fmt, "uint64_t"));
pt = calloc(sizeof *pt, 1);
AN(pt);
@@ -89,7 +91,7 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
pt->ptr = sp->ptr;
pt->ref = *pt->ptr;
- pt->flag = sp->flag;
+ pt->flag = sp->desc->flag;
*buf = '\0';
if (strcmp(sp->class, "")) {
@@ -100,9 +102,9 @@ do_curses_cb(void *priv, const struct VSC_point * const sp)
strcat(buf, sp->ident);
strcat(buf, ".");
}
- strcat(buf, sp->name);
+ strcat(buf, sp->desc->name);
strcat(buf, " - ");
- strcat(buf, sp->desc);
+ strcat(buf, sp->desc->sdesc);
pt->name = strdup(buf);
AN(pt->name);
return (0);
@@ -144,7 +146,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
int ch, line;
struct pt *pt;
double act, lact;
- unsigned seq;
(void)initscr();
AC(raw());
@@ -157,7 +158,6 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
/*
* Initialization goes in outher loop
*/
- seq = VSM_Seq(vd);
prep_pts(vd);
AC(erase());
AC(refresh());
@@ -170,15 +170,11 @@ do_curses(struct VSM_data *vd, const struct VSC_C_main *VSC_C_main,
lact = 0;
while (1) {
- if (seq != VSM_Seq(vd))
- break;
/*
* Break to outher loop if we need to re-read file.
* Only check if it looks like nothing is happening.
*/
act = VSC_C_main->cache_hit + VSC_C_main->cache_miss + 1;
- if (act == lact && VSM_ReOpen(vd, 1))
- break;
lact = act;
AZ(gettimeofday(&tv, NULL));
diff --git a/include/vapi/vsc.h b/include/vapi/vsc.h
index 3cf16c6..6ebab31 100644
--- a/include/vapi/vsc.h
+++ b/include/vapi/vsc.h
@@ -26,6 +26,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * This is the public API for the VSC access.
+ *
+ * VSC is a "subclass" of VSM.
+ *
*/
#ifndef VAPI_VSC_H_INCLUDED
@@ -34,17 +38,12 @@
#include "vapi/vsc_int.h"
struct VSM_data;
+struct VSM_fantom;
/*---------------------------------------------------------------------
* VSC level access functions
*/
-void VSC_Setup(struct VSM_data *vd);
- /*
- * Setup vd for use with VSC functions.
- * Must be called once before any other VSC function is called
- */
-
#define VSC_ARGS "f:n:"
#define VSC_n_USAGE VSM_n_USAGE
#define VSC_f_USAGE "[-f field_name,...]"
@@ -55,39 +54,58 @@ int VSC_Arg(struct VSM_data *vd, int arg, const char *opt);
/*
* Handle standard stat-presenter arguments
* Return:
- * -1 error
+ * -1 error, VSM_Error() returns diagnostic string
* 0 not handled
* 1 Handled.
*/
-int VSC_Open(struct VSM_data *vd, int diag);
- /*
- * Open shared memory for VSC processing.
- * args and returns as VSM_Open()
- */
-
-struct VSC_C_main *VSC_Main(const struct VSM_data *vd);
+struct VSC_C_main *VSC_Main(struct VSM_data *vd);
/*
* return Main stats structure
* returns NULL until child has been started.
*/
+struct VSC_desc {
+ const char *name; /* field name */
+ const char *fmt; /* field format ("uint64_t") */
+ int flag; /* 'c' = counter, 'g' = gauge */
+ const char *sdesc; /* short description */
+ const char *ldesc; /* long description */
+};
+
struct VSC_point {
const char *class; /* stat struct type */
const char *ident; /* stat struct ident */
- const char *name; /* field name */
- const char *fmt; /* field format ("uint64_t") */
- int flag; /* 'a' = counter, 'i' = gauge */
- const char *desc; /* description */
+ const struct VSC_desc *desc; /* point description */
const volatile void *ptr; /* field value */
+ struct VSM_fantom *vf;
};
typedef int VSC_iter_f(void *priv, const struct VSC_point *const pt);
-int VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv);
+int VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv);
/*
* Iterate over all statistics counters, calling "func" for
* each counter not suppressed by any "-f" arguments.
+ *
+ * Func is called with pt == NULL, whenever VSM allocations
+ * change (child restart, allocations/deallocations)
+ *
+ * Returns:
+ * !=0: func returned non-zero
+ * -1: No VSC's available
+ * 0: Done
*/
+/**********************************************************************
+ * Precompiled VSC_desc's for all know VSCs.
+ */
+#define VSC_F(n,t,l,f,d,e)
+#define VSC_DO(U,l,t) extern const struct VSC_desc VSC_desc_##l[];
+#define VSC_DONE(U,l,t)
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+
#endif /* VAPI_VSC_H_INCLUDED */
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index c9facfd..54bf20f 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -47,15 +47,22 @@
#include "vqueue.h"
#include "vsm_api.h"
+struct vsc_pt {
+ unsigned magic;
+#define VSC_PT_MAGIC 0xa4ff159a
+ struct VSC_point point;
+ VTAILQ_ENTRY(vsc_pt) list;
+};
+
struct vsc_sf {
unsigned magic;
-#define VSL_SF_MAGIC 0x558478dd
- VTAILQ_ENTRY(vsc_sf) next;
+#define VSC_SF_MAGIC 0x558478dd
+ VTAILQ_ENTRY(vsc_sf) list;
int flags;
-#define VSL_SF_EXCL (1 << 0)
-#define VSL_SF_CL_WC (1 << 1)
-#define VSL_SF_ID_WC (1 << 2)
-#define VSL_SF_NM_WC (1 << 3)
+#define VSC_SF_EXCL (1 << 0)
+#define VSC_SF_CL_WC (1 << 1)
+#define VSC_SF_ID_WC (1 << 2)
+#define VSC_SF_NM_WC (1 << 3)
char *class;
char *ident;
char *name;
@@ -65,40 +72,56 @@ struct vsc {
unsigned magic;
#define VSC_MAGIC 0x3373554a
- int sf_init;
+ VTAILQ_HEAD(, vsc_pt) pt_list;
VTAILQ_HEAD(, vsc_sf) sf_list;
-
+ struct VSM_fantom main_fantom;
+ struct VSM_fantom iter_fantom;
};
/*--------------------------------------------------------------------*/
-void
-VSC_Setup(struct VSM_data *vd)
+static struct vsc *
+vsc_setup(struct VSM_data *vd)
{
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- AZ(vd->vsc);
- ALLOC_OBJ(vd->vsc, VSC_MAGIC);
- AN(vd->vsc);
- VTAILQ_INIT(&vd->vsc->sf_list);
+ if (vd->vsc == NULL) {
+ ALLOC_OBJ(vd->vsc, VSC_MAGIC);
+ VTAILQ_INIT(&vd->vsc->sf_list);
+ VTAILQ_INIT(&vd->vsc->pt_list);
+ }
+ CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
+ return (vd->vsc);
}
/*--------------------------------------------------------------------*/
-void
-VSC_Delete(struct VSM_data *vd)
+static void
+vsc_delete_pts(struct vsc *vsc)
+{
+ struct vsc_pt *pt;
+ struct VSM_fantom *vf = NULL;
+
+ while(!VTAILQ_EMPTY(&vsc->pt_list)) {
+ pt = VTAILQ_FIRST(&vsc->pt_list);
+ VTAILQ_REMOVE(&vsc->pt_list, pt, list);
+ if (pt->point.vf != vf) {
+ vf = pt->point.vf;
+ free(vf);
+ }
+ FREE_OBJ(pt);
+ }
+}
+
+static void
+vsc_delete_sfs(struct vsc *vsc)
{
struct vsc_sf *sf;
- struct vsc *vsc;
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- vsc = vd->vsc;
- vd->vsc = NULL;
- CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
while(!VTAILQ_EMPTY(&vsc->sf_list)) {
sf = VTAILQ_FIRST(&vsc->sf_list);
- VTAILQ_REMOVE(&vsc->sf_list, sf, next);
+ VTAILQ_REMOVE(&vsc->sf_list, sf, list);
free(sf->class);
free(sf->ident);
free(sf->name);
@@ -106,39 +129,42 @@ VSC_Delete(struct VSM_data *vd)
}
}
-/*--------------------------------------------------------------------*/
-
-static int
-vsc_sf_arg(const struct VSM_data *vd, const char *opt)
+void
+VSC_Delete(struct VSM_data *vd)
{
struct vsc *vsc;
- struct vsc_sf *sf;
- char **av, *q, *p;
- int i;
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
vsc = vd->vsc;
+ vd->vsc = NULL;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
+ vsc_delete_sfs(vsc);
+ vsc_delete_pts(vsc);
+ FREE_OBJ(vsc);
+}
- if (VTAILQ_EMPTY(&vsc->sf_list)) {
- if (*opt == '^')
- vsc->sf_init = 1;
- }
+/*--------------------------------------------------------------------*/
+
+static int
+vsc_f_arg(struct VSM_data *vd, const char *opt)
+{
+ struct vsc *vsc = vsc_setup(vd);
+ struct vsc_sf *sf;
+ char **av, *q, *p;
+ int i;
av = VAV_Parse(opt, NULL, ARGV_COMMA);
AN(av);
- if (av[0] != NULL) {
- vd->diag(vd->priv, "Parse error: %s", av[0]);
- return (-1);
- }
+ if (av[0] != NULL)
+ return (vsm_diag(vd, "Parse error: %s", av[0]));
for (i = 1; av[i] != NULL; i++) {
- ALLOC_OBJ(sf, VSL_SF_MAGIC);
+ ALLOC_OBJ(sf, VSC_SF_MAGIC);
AN(sf);
- VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, next);
+ VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, list);
p = av[i];
if (*p == '^') {
- sf->flags |= VSL_SF_EXCL;
+ sf->flags |= VSC_SF_EXCL;
p++;
}
@@ -167,21 +193,21 @@ vsc_sf_arg(const struct VSM_data *vd, const char *opt)
q = strchr(sf->class, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
- sf->flags |= VSL_SF_CL_WC;
+ sf->flags |= VSC_SF_CL_WC;
}
}
if (sf->ident != NULL) {
q = strchr(sf->ident, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
- sf->flags |= VSL_SF_ID_WC;
+ sf->flags |= VSC_SF_ID_WC;
}
}
if (sf->name != NULL) {
q = strchr(sf->name, '*');
if (q != NULL && q[1] == '\0') {
*q = '\0';
- sf->flags |= VSL_SF_NM_WC;
+ sf->flags |= VSC_SF_NM_WC;
}
}
}
@@ -195,10 +221,8 @@ int
VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
{
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- AN(vd->vsc);
switch (arg) {
- case 'f': return (vsc_sf_arg(vd, opt));
+ case 'f': return (vsc_f_arg(vd, opt));
case 'n': return (VSM_n_Arg(vd, opt));
default:
return (0);
@@ -207,33 +231,19 @@ VSC_Arg(struct VSM_data *vd, int arg, const char *opt)
/*--------------------------------------------------------------------*/
-int
-VSC_Open(struct VSM_data *vd, int diag)
-{
- int i;
-
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- AN(vd->vsc);
-
- i = VSM_Open(vd, diag);
- return (i);
-}
-
-/*--------------------------------------------------------------------*/
-
struct VSC_C_main *
-VSC_Main(const struct VSM_data *vd)
+VSC_Main(struct VSM_data *vd)
{
- struct VSM_fantom vf;
+ struct vsc *vsc = vsc_setup(vd);
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- CHECK_OBJ_NOTNULL(vd->vsc, VSC_MAGIC);
-
- if (!VSM_Get(vd, &vf, VSC_CLASS, "", ""))
+ if (!vd->head && VSM_Open(vd))
return (NULL);
- return ((void*)vf.b);
+ if (!VSM_Get(vd, &vsc->main_fantom, VSC_CLASS, "", ""))
+ return (NULL);
+ return ((void*)vsc->main_fantom.b);
}
+#if 0
/*--------------------------------------------------------------------
* -1 -> unknown stats encountered.
*/
@@ -256,23 +266,28 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
const struct VSC_point *const sp)
{
struct vsc_sf *sf;
+ struct vsc_pt *pt;
int good;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
- if (VTAILQ_EMPTY(&vsc->sf_list))
- return (func(priv, sp));
+ ALLOC_OBJ(pt, VSC_PT_MAGIC);
+ AN(pt);
- good = vsc->sf_init;
+ if (VTAILQ_EMPTY(&vsc->sf_list)) {
+ VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
+ return (func(priv, sp));
+ }
- VTAILQ_FOREACH(sf, &vsc->sf_list, next) {
- if (iter_test(sf->class, sp->class, sf->flags & VSL_SF_CL_WC))
+ good = 0;
+ VTAILQ_FOREACH(sf, &vsc->sf_list, list) {
+ if (iter_test(sf->class, sp->class, sf->flags & VSC_SF_CL_WC))
continue;
- if (iter_test(sf->ident, sp->ident, sf->flags & VSL_SF_ID_WC))
+ if (iter_test(sf->ident, sp->ident, sf->flags & VSC_SF_ID_WC))
continue;
- if (iter_test(sf->name, sp->name, sf->flags & VSL_SF_NM_WC))
+ if (iter_test(sf->name, sp->desc->name, sf->flags & VSC_SF_NM_WC))
continue;
- if (sf->flags & VSL_SF_EXCL)
+ if (sf->flags & VSC_SF_EXCL)
good = 0;
else
good = 1;
@@ -283,26 +298,27 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
}
#define VSC_DO(U,l,t) \
- static int \
+ static void \
iter_##l(const struct vsc *vsc, struct VSM_fantom *vf, \
- VSC_iter_f *func, void *priv) \
+ const struct VSC_desc *descs) \
{ \
struct VSC_C_##l *st; \
- struct VSC_point sp; \
+ struct VSM_fantom *vf2; \
int i; \
\
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); \
st = vf->b; \
sp.class = t; \
- sp.ident = vf->chunk->ident;
+ sp.ident = vf->chunk->ident; \
+ sp.desc = descs++; \
+ vf2 = malloc(sizeof *vf2); \
+ AN(vf2); \
+ memcpy(vf2, vf, sizeof *vf2);
#define VSC_F(nn,tt,ll,ff,dd,ee) \
- sp.name = #nn; \
- sp.fmt = #tt; \
- sp.flag = ff; \
- sp.desc = dd; \
sp.ptr = &st->nn; \
- i = iter_call(vsc, func, priv, &sp); \
+ sp.vf = vf2; \
+ i = iter_call(vsc, &sp); \
if (i) \
return(i);
@@ -315,19 +331,14 @@ iter_call(const struct vsc *vsc, VSC_iter_f *func, void *priv,
#undef VSC_F
#undef VSC_DONE
-int
-VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
+static void
+vsc_build_pt_list(struct VSM_data *vd)
{
- struct vsc *vsc;
+ struct vsc *vsc = vsc_setup(vd);
struct VSM_fantom vf;
- int i;
- CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- vsc = vd->vsc;
- CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
- i = 0;
- if (!VSM_StillValid(vd, NULL))
- return (-1);
+ vsc_delete_pts(vsc *vsc);
+
VSM_FOREACH_SAFE(&vf, vd) {
if (strcmp(vf.chunk->class, VSC_CLASS))
continue;
@@ -335,11 +346,8 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
#define VSC_F(n,t,l,f,d,e)
#define VSC_DONE(a,b,c)
#define VSC_DO(U,l,t) \
- if (!strcmp(vf.chunk->type, t)) { \
- i = iter_##l(vsc, &vf, func, priv); \
- if (!i) \
- continue; \
- }
+ if (!strcmp(vf.chunk->type, t)) \
+ iter_##l(vsc, &vf, VSC_desc_##l);
#include "tbl/vsc_all.h"
#undef VSC_F
#undef VSC_DO
@@ -349,3 +357,127 @@ VSC_Iter(const struct VSM_data *vd, VSC_iter_f *func, void *priv)
}
return (i);
}
+#endif
+
+/*--------------------------------------------------------------------
+ */
+
+static void
+vsc_add_pt(struct vsc *vsc, const char *class, const char *ident,
+ const struct VSC_desc *desc, const volatile void *ptr,
+ struct VSM_fantom *vf)
+{
+ struct vsc_pt *pt;
+
+ ALLOC_OBJ(pt, VSC_PT_MAGIC);
+ AN(pt);
+ pt->point.class = class;
+ pt->point.ident = ident;
+ pt->point.desc = desc;
+ pt->point.ptr = ptr;
+ pt->point.vf = vf;
+ VTAILQ_INSERT_TAIL(&vsc->pt_list, pt, list);
+}
+
+#define VSC_DO(U,l,t) \
+ static void \
+ iter_##l(struct vsc *vsc, struct VSM_fantom *vf, \
+ const struct VSC_desc *descs) \
+ { \
+ struct VSC_C_##l *st; \
+ struct VSM_fantom *vf2; \
+ const char *class = t; \
+ \
+ CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); \
+ st = vf->b; \
+ vf2 = malloc(sizeof *vf2); \
+ AN(vf2); \
+ memcpy(vf2, vf, sizeof *vf2);
+
+#define VSC_F(nn,tt,ll,ff,dd,ee) \
+ vsc_add_pt(vsc, class, vf->chunk->ident, descs++, \
+ &st->nn, vf2);
+
+#define VSC_DONE(U,l,t) \
+ }
+
+#include "tbl/vsc_all.h"
+#undef VSC_DO
+#undef VSC_F
+#undef VSC_DONE
+
+/*--------------------------------------------------------------------
+ */
+
+static void
+vsc_build_pt_list(struct VSM_data *vd)
+{
+ struct vsc *vsc = vsc_setup(vd);
+ struct VSM_fantom vf;
+
+ vsc_delete_pts(vsc);
+
+ VSM_FOREACH_SAFE(&vf, vd) {
+ if (strcmp(vf.chunk->class, VSC_CLASS))
+ continue;
+ /*lint -save -e525 -e539 */
+#define VSC_F(n,t,l,f,d,e)
+#define VSC_DONE(a,b,c)
+#define VSC_DO(U,l,t) \
+ if (!strcmp(vf.chunk->type, t)) \
+ iter_##l(vsc, &vf, VSC_desc_##l);
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+ /*lint -restore */
+ }
+
+ /* XXX: filter pt list */
+}
+
+/*--------------------------------------------------------------------
+ */
+
+int
+VSC_Iter(struct VSM_data *vd, VSC_iter_f *func, void *priv)
+{
+ struct vsc *vsc = vsc_setup(vd);
+ struct vsc_pt *pt;
+ int i;
+
+ if (1 != VSM_StillValid(vd, &vsc->iter_fantom)) {
+ if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
+ VSM_Close(vd);
+ if (!vd->head && VSM_Open(vd))
+ return (-1);
+ if (!VSM_Get(vd, &vsc->iter_fantom, VSC_CLASS, "", "")) {
+ return (-1);
+ }
+ }
+ AN(vd->head);
+ func(priv, NULL);
+ vsc_build_pt_list(vd);
+ }
+ AN(vd->head);
+ VTAILQ_FOREACH(pt, &vsc->pt_list, list) {
+ i = func(priv, &pt->point);
+ if (i)
+ return (i);
+ }
+ return (0);
+}
+
+/*--------------------------------------------------------------------
+ * Build the static point descriptions
+ */
+
+#define VSC_F(n,t,l,f,d,e) {#n,#t,f,d,e},
+#define VSC_DO(U,l,t) const struct VSC_desc VSC_desc_##l[] = {
+#define VSC_DONE(U,l,t) };
+#include "tbl/vsc_all.h"
+#undef VSC_F
+#undef VSC_DO
+#undef VSC_DONE
+
+
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index 1d762e5..a9f176c 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -113,7 +113,7 @@ VSM_n_Arg(struct VSM_data *vd, const char *opt)
{
CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
- AN(vd->n_opt);
+ AN(opt);
REPLACE(vd->n_opt, opt);
if (VIN_N_Arg(vd->n_opt, NULL, NULL, &vd->fname))
More information about the varnish-commit
mailing list