Commit 0a5b5fcd authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Rototill the last bit of the VSC-api and simplify varnishstat_curses

accordingly.

If somebody has time to push varnishstat in curses mode though the
paces and check that everything works I'd appreciate it.
parent 770d3699
...@@ -81,7 +81,7 @@ do_xml(struct vsm *vsm, struct vsc *vsc) ...@@ -81,7 +81,7 @@ do_xml(struct vsm *vsm, struct vsc *vsc)
now = time(NULL); now = time(NULL);
(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now)); (void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
printf("<varnishstat timestamp=\"%s\">\n", time_stamp); printf("<varnishstat timestamp=\"%s\">\n", time_stamp);
(void)VSC_Iter(vsc, vsm, NULL, do_xml_cb, NULL, NULL); (void)VSC_Iter(vsc, vsm, do_xml_cb, NULL);
printf("</varnishstat>\n"); printf("</varnishstat>\n");
} }
...@@ -135,7 +135,7 @@ do_json(struct vsm *vsm, struct vsc *vsc) ...@@ -135,7 +135,7 @@ do_json(struct vsm *vsm, struct vsc *vsc)
(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now)); (void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
printf(" \"timestamp\": \"%s\",\n", time_stamp); printf(" \"timestamp\": \"%s\",\n", time_stamp);
(void)VSC_Iter(vsc, vsm, NULL, do_json_cb, NULL, &jp); (void)VSC_Iter(vsc, vsm, do_json_cb, &jp);
printf("\n}\n"); printf("\n}\n");
} }
...@@ -199,8 +199,8 @@ do_once(struct vsm *vsm, struct vsc *vsc) ...@@ -199,8 +199,8 @@ do_once(struct vsm *vsm, struct vsc *vsc)
memset(&op, 0, sizeof op); memset(&op, 0, sizeof op);
op.pad = 18; op.pad = 18;
(void)VSC_Iter(vsc, vsm, NULL, do_once_cb_first, NULL, &op); (void)VSC_Iter(vsc, vsm, do_once_cb_first, &op);
(void)VSC_Iter(vsc, vsm, NULL, do_once_cb, NULL, &op); (void)VSC_Iter(vsc, vsm, do_once_cb, &op);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -230,7 +230,7 @@ list_fields(struct vsm *vsm, struct vsc *vsc) ...@@ -230,7 +230,7 @@ list_fields(struct vsm *vsm, struct vsc *vsc)
printf("Field name Description\n"); printf("Field name Description\n");
printf("---------- -----------\n"); printf("---------- -----------\n");
(void)VSC_Iter(vsc, vsm, NULL, do_list_cb, NULL, NULL); (void)VSC_Iter(vsc, vsm, do_list_cb, NULL);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
......
...@@ -72,7 +72,7 @@ struct pt { ...@@ -72,7 +72,7 @@ struct pt {
#define PT_MAGIC 0x41698E4F #define PT_MAGIC 0x41698E4F
VTAILQ_ENTRY(pt) list; VTAILQ_ENTRY(pt) list;
struct VSC_point *vpt; const struct VSC_point *vpt;
char seen; char seen;
...@@ -119,6 +119,7 @@ static int sample = 0; ...@@ -119,6 +119,7 @@ static int sample = 0;
static int scale = 1; static int scale = 1;
static double t_sample = 0.; static double t_sample = 0.;
static double interval = 1.; static double interval = 1.;
static int vsm_status = 0;
static void static void
init_hitrate(void) init_hitrate(void)
...@@ -225,130 +226,6 @@ build_pt_array(void) ...@@ -225,130 +226,6 @@ build_pt_array(void)
redraw = 1; redraw = 1;
} }
static void
delete_pt_list(void)
{
struct pt *pt;
unsigned i = 0;
delete_pt_array();
while (!VTAILQ_EMPTY(&ptlist)) {
pt = VTAILQ_FIRST(&ptlist);
CHECK_OBJ_NOTNULL(pt, PT_MAGIC);
VTAILQ_REMOVE(&ptlist, pt, list);
VSC_Destroy_Point(&pt->vpt);
FREE_OBJ(pt);
i++;
}
assert(i == n_ptlist);
n_ptlist = 0;
update_position();
}
struct pt_priv {
unsigned magic;
#define PT_PRIV_MAGIC 0x34ACBAD6
VTAILQ_HEAD(, pt) ptlist;
unsigned n_ptlist;
};
static int __match_proto__(VSC_iter_f)
build_pt_list_cb(void *priv, const struct VSC_point *vpt)
{
struct pt_priv *pt_priv;
struct pt *pt;
if (vpt == NULL)
return (0);
CAST_OBJ_NOTNULL(pt_priv, priv, PT_PRIV_MAGIC);
AZ(strcmp(vpt->ctype, "uint64_t"));
if (!strcmp(vpt->name, "MGT.uptime"))
mgt_uptime = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.uptime"))
main_uptime = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.cache_hit"))
main_cache_hit = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.cache_miss"))
main_cache_miss = vpt->ptr;
VTAILQ_FOREACH(pt, &ptlist, list) {
CHECK_OBJ_NOTNULL(pt, PT_MAGIC);
AN(pt->vpt->name);
if (strcmp(vpt->name, pt->vpt->name))
continue;
VTAILQ_REMOVE(&ptlist, pt, list);
AN(n_ptlist);
n_ptlist--;
VSC_Destroy_Point(&pt->vpt);
pt->vpt = VSC_Clone_Point(vpt);
AN(pt->vpt);
VTAILQ_INSERT_TAIL(&pt_priv->ptlist, pt, list);
pt_priv->n_ptlist++;
return (0);
}
AZ(pt);
ALLOC_OBJ(pt, PT_MAGIC);
AN(pt);
pt->vpt = VSC_Clone_Point(vpt);
AN(pt->vpt);
pt->last = *pt->vpt->ptr;
pt->ma_10.nmax = 10;
pt->ma_100.nmax = 100;
pt->ma_1000.nmax = 1000;
VTAILQ_INSERT_TAIL(&pt_priv->ptlist, pt, list);
pt_priv->n_ptlist++;
return (0);
}
static void
build_pt_list(struct vsc *vsc, struct vsm *vsm)
{
struct pt_priv pt_priv;
int i;
struct pt *pt_current = NULL;
int current_line = 0;
if (current < n_ptarray) {
pt_current = ptarray[current];
current_line = current - page_start;
}
pt_priv.magic = PT_PRIV_MAGIC;
VTAILQ_INIT(&pt_priv.ptlist);
pt_priv.n_ptlist = 0;
mgt_uptime = NULL;
main_uptime = NULL;
main_cache_hit = NULL;
main_cache_miss = NULL;
(void)VSC_Iter(vsc, vsm, NULL, build_pt_list_cb, NULL, &pt_priv);
delete_pt_list();
AN(VTAILQ_EMPTY(&ptlist));
AZ(n_ptlist);
VTAILQ_CONCAT(&ptlist, &pt_priv.ptlist, list);
n_ptlist = pt_priv.n_ptlist;
build_pt_array();
for (i = 0; pt_current != NULL && i < n_ptarray; i++)
if (ptarray[i] == pt_current)
break;
current = i;
page_start = current - current_line;
update_position();
}
static void static void
sample_points(void) sample_points(void)
{ {
...@@ -527,12 +404,23 @@ print_duration(WINDOW *w, time_t t) ...@@ -527,12 +404,23 @@ print_duration(WINDOW *w, time_t t)
(intmax_t)(t % 3600) / 60, (intmax_t)t % 60); (intmax_t)(t % 3600) / 60, (intmax_t)t % 60);
} }
static void
running(WINDOW *w, time_t up, int flg)
{
if (vsm_status & flg) {
print_duration(w_status, up);
} else {
wattron(w, A_STANDOUT);
wprintw(w, " Not Running");
wattroff(w, A_STANDOUT);
}
}
static void static void
draw_status(void) draw_status(void)
{ {
time_t up_mgt = 0; time_t up_mgt = 0;
time_t up_chld = 0; time_t up_chld = 0;
static const char discon[] = "*** DISCONNECTED ***";
AN(w_status); AN(w_status);
...@@ -543,14 +431,12 @@ draw_status(void) ...@@ -543,14 +431,12 @@ draw_status(void)
if (main_uptime != NULL) if (main_uptime != NULL)
up_chld = *main_uptime; up_chld = *main_uptime;
mvwprintw(w_status, 0, 0, "Uptime mgt: "); mvwprintw(w_status, 0, 0, "Uptime mgt: ");
print_duration(w_status, up_mgt); running(w_status, up_mgt, VSM_MGT_RUNNING);
mvwprintw(w_status, 1, 0, "Uptime child:"); mvwprintw(w_status, 1, 0, "Uptime child: ");
print_duration(w_status, up_chld); running(w_status, up_chld, VSM_WRK_RUNNING);
if (mgt_uptime == NULL) if (COLS > 70) {
mvwprintw(w_status, 0, COLS - strlen(discon), discon);
else if (COLS > 70) {
mvwprintw(w_status, 0, getmaxx(w_status) - 37, mvwprintw(w_status, 0, getmaxx(w_status) - 37,
"Hitrate n: %8u %8u %8u", hitrate.hr_10.n, hitrate.hr_100.n, "Hitrate n: %8u %8u %8u", hitrate.hr_10.n, hitrate.hr_100.n,
hitrate.hr_1000.n); hitrate.hr_1000.n);
...@@ -1042,12 +928,62 @@ handle_keypress(int ch) ...@@ -1042,12 +928,62 @@ handle_keypress(int ch)
redraw = 1; redraw = 1;
} }
static void * __match_proto__(VSC_new_f)
newpt(void *priv, const struct VSC_point *const vpt)
{
struct pt *pt;
ALLOC_OBJ(pt, PT_MAGIC);
AN(pt);
AZ(priv);
pt->vpt = vpt;
pt->last = *pt->vpt->ptr;
pt->ma_10.nmax = 10;
pt->ma_100.nmax = 100;
pt->ma_1000.nmax = 1000;
VTAILQ_INSERT_TAIL(&ptlist, pt, list);
n_ptlist++;
AZ(strcmp(vpt->ctype, "uint64_t"));
if (!strcmp(vpt->name, "MGT.uptime"))
mgt_uptime = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.uptime"))
main_uptime = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.cache_hit"))
main_cache_hit = vpt->ptr;
if (!strcmp(vpt->name, "MAIN.cache_miss"))
main_cache_miss = vpt->ptr;
return (pt);
}
static void __match_proto__(VSC_destroy_f)
delpt(void *priv, const struct VSC_point *const vpt)
{
struct pt *pt;
AZ(priv);
CAST_OBJ_NOTNULL(pt, vpt->priv, PT_MAGIC);
VTAILQ_REMOVE(&ptlist, pt, list);
n_ptlist--;
FREE_OBJ(pt);
if (vpt->ptr == mgt_uptime)
mgt_uptime = NULL;
if (vpt->ptr == main_uptime)
main_uptime = NULL;
if (vpt->ptr == main_cache_hit)
main_cache_hit = NULL;
if (vpt->ptr == main_cache_miss)
main_cache_miss = NULL;
}
void void
do_curses(struct vsm *vd, struct vsc *vsc, double delay) do_curses(struct vsm *vsm, struct vsc *vsc, double delay)
{ {
struct pollfd pollfd; struct pollfd pollfd;
long t; long t;
int ch, initial = 1; int ch;
double now; double now;
interval = delay; interval = delay;
...@@ -1066,13 +1002,17 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay) ...@@ -1066,13 +1002,17 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
make_windows(); make_windows();
doupdate(); doupdate();
VSC_State(vsc, newpt, delpt, NULL);
rebuild = 1;
while (keep_running) { while (keep_running) {
if (initial || vsm_status = VSM_Status(vsm);
(VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED))) { rebuild |= vsm_status & ~(VSM_MGT_RUNNING|VSM_WRK_RUNNING);
if (rebuild) {
(void)VSC_Iter(vsc, vsm, NULL, NULL);
init_hitrate(); init_hitrate();
delete_pt_list(); build_pt_array();
build_pt_list(vsc, vd); redraw = 1;
initial = 0;
} }
now = VTIM_mono(); now = VTIM_mono();
...@@ -1080,8 +1020,6 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay) ...@@ -1080,8 +1020,6 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
sample = 1; sample = 1;
if (sample) if (sample)
sample_data(); sample_data();
if (rebuild)
build_pt_array();
if (redraw) if (redraw)
draw_screen(); draw_screen();
...@@ -1103,6 +1041,8 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay) ...@@ -1103,6 +1041,8 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
break; break;
} }
} }
VSM_Destroy(&vd); VSC_Destroy(&vsc);
AN(VTAILQ_EMPTY(&ptlist));
VSM_Destroy(&vsm);
AZ(endwin()); AZ(endwin());
} }
...@@ -849,7 +849,7 @@ varnish_vsc(const struct varnish *v, const char *arg) ...@@ -849,7 +849,7 @@ varnish_vsc(const struct varnish *v, const char *arg)
dp.v = v; dp.v = v;
dp.arg = arg; dp.arg = arg;
(void)VSM_Status(v->vsm_vsc); (void)VSM_Status(v->vsm_vsc);
(void)VSC_Iter(v->vsc, v->vsm_vsc, NULL, do_stat_dump_cb, NULL, &dp); (void)VSC_Iter(v->vsc, v->vsm_vsc, do_stat_dump_cb, &dp);
} }
/********************************************************************** /**********************************************************************
...@@ -914,8 +914,7 @@ varnish_expect(const struct varnish *v, char * const *av) ...@@ -914,8 +914,7 @@ varnish_expect(const struct varnish *v, char * const *av)
good = 0; good = 0;
for (i = 0; i < 50; i++, (void)usleep(100000)) { for (i = 0; i < 50; i++, (void)usleep(100000)) {
(void)VSM_Status(v->vsm_vsc); (void)VSM_Status(v->vsm_vsc);
good = VSC_Iter(v->vsc, v->vsm_vsc, good = VSC_Iter(v->vsc, v->vsm_vsc, do_expect_cb, &sp);
NULL, do_expect_cb, NULL, &sp);
if (!good) { if (!good) {
good = -2; good = -2;
continue; continue;
......
...@@ -41,25 +41,6 @@ struct vsm; ...@@ -41,25 +41,6 @@ struct vsm;
struct vsc; struct vsc;
struct vsm_fantom; struct vsm_fantom;
/*---------------------------------------------------------------------
* VSC level access functions
*/
struct vsc *VSC_New(void);
void VSC_Destroy(struct vsc **);
int VSC_Arg(struct vsc *, char arg, const char *opt);
/*
* Handle standard stat-presenter arguments
* Return:
* -1 error, VSM_Error() returns diagnostic string
* 0 not handled
* 1 Handled.
*/
struct VSC_level_desc;
struct VSC_point;
struct VSC_level_desc { struct VSC_level_desc {
const char *name; /* name */ const char *name; /* name */
const char *label; /* label */ const char *label; /* label */
...@@ -71,50 +52,104 @@ struct VSC_point { ...@@ -71,50 +52,104 @@ struct VSC_point {
const volatile uint64_t *ptr; /* field value */ const volatile uint64_t *ptr; /* field value */
const char *name; /* field name */ const char *name; /* field name */
const char *ctype; /* C-type */ const char *ctype; /* C-type */
int semantics; /* semantics */ int semantics; /* semantics
int format; /* display format */ * 'c' = Counter
* 'g' = Gauge
* 'b' = bitmap
* '?' = unknown
*/
int format; /* display format
* 'i' = integer
* 'B' = bytes
* 'b' = bitmap
* 'd' = duration
* '?' = unknown
*/
const struct VSC_level_desc *level; /* verbosity level */ const struct VSC_level_desc *level; /* verbosity level */
const char *sdesc; /* short description */ const char *sdesc; /* short description */
const char *ldesc; /* long description */ const char *ldesc; /* long description */
void *priv; /* return val from VSC_new_f */
}; };
struct VSC_point *VSC_Clone_Point(const struct VSC_point * const); /*---------------------------------------------------------------------
* Function pointers
void VSC_Destroy_Point(struct VSC_point **); */
typedef void *VSC_new_f(void *priv, const struct VSC_point *const pt); typedef void *VSC_new_f(void *priv, const struct VSC_point *const pt);
/*
* priv is from VSC_State().
*
* The return value is installed in pt->priv
*/
typedef void VSC_destroy_f(void *priv, const struct VSC_point *const pt);
/*
* priv is from VSC_State().
*/
typedef int VSC_iter_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); /*
* priv is the argument to VSC_Iter() and not from VSC_State().
*
* A non-zero return terminates the iteration
*/
int VSC_Iter(struct vsc *, struct vsm *, VSC_new_f *, VSC_iter_f *, VSC_destroy_f *, void *priv); /*---------------------------------------------------------------------
* VSC level access functions
*/
struct vsc *VSC_New(void);
/* /*
* Iterate over all statistics counters, calling "func" for * Create a new VSC instance
* each counter not suppressed by any "-f" arguments. */
void VSC_Destroy(struct vsc **);
/*
* Destroy a VSC instance
* *
* fantom points to a struct vsm_fantom. If non-NULL, it can be * If a destroy function was installed with VSC_State()
* used with VSM_StillValid to check the validity of the points * it will be called for all remaining points
* returned. */
int VSC_Arg(struct vsc *, char arg, const char *opt);
/*
* Handle standard stat-presenter arguments
* 'f' - filter
* *
* The returned points are valid for at most 60 seconds after * Return:
* VSM_StillValid(,fantom) starts returning anything but * -1 error, VSM_Error() returns diagnostic string
* VSM_valid, or until the next call to VSC_Iter. Using the point * 0 not handled
* values after any of these events gives undefined behavior. * 1 Handled.
*/
void VSC_State(struct vsc *, VSC_new_f *, VSC_destroy_f *, void *);
/*
* Install function pointers for create/destroy and their
* priv pointer. All arguments can be NULL.
*/
int VSC_Iter(struct vsc *, struct vsm *, VSC_iter_f *, void *priv);
/*
* Iterate over all statistics counters, calling a function for
* each counter not suppressed by any "-f" arguments.
* *
* Func is called with pt == NULL, whenever VSM allocations * To discover new/deleted points, call VSM_Status() first.
* change (child restart, allocations/deallocations) *
* The returned points are valid until the next call to VSC_Iter()
* *
* Arguments: * Arguments:
* vd: The vsm context * vd: The vsm context
* fantom: Pointer to a fantom. Can be NULL.
* func: The callback function * func: The callback function
* priv: Passed as argument to func * priv: Passed as argument to func
* *
* Returns: * Returns:
* !=0: func returned non-zero * !=0: func returned non-zero
* -1: No VSC's available
* 0: Done * 0: Done
*/ */
const struct VSC_level_desc *VSC_ChangeLevel(const struct VSC_level_desc*, int); const struct VSC_level_desc *VSC_ChangeLevel(const struct VSC_level_desc*, int);
/*
* Change a level up or down.
*/
#endif /* VAPI_VSC_H_INCLUDED */ #endif /* VAPI_VSC_H_INCLUDED */
...@@ -195,5 +195,5 @@ LIBVARNISHAPI_1.7 { ...@@ -195,5 +195,5 @@ LIBVARNISHAPI_1.7 {
VSM_Dup; VSM_Dup;
VSC_New; VSC_New;
VSC_Destroy; VSC_Destroy;
VSC_Iter2; VSC_State;
} LIBVARNISHAPI_1.0; } LIBVARNISHAPI_1.0;
...@@ -69,7 +69,7 @@ struct vsc_seg { ...@@ -69,7 +69,7 @@ struct vsc_seg {
#define VSC_SEG_MAGIC 0x801177d4 #define VSC_SEG_MAGIC 0x801177d4
VTAILQ_ENTRY(vsc_seg) list; VTAILQ_ENTRY(vsc_seg) list;
struct vsm_fantom fantom[1]; struct vsm_fantom fantom[1];
struct vjsn *vj; struct vjsn *vj;
unsigned npoints; unsigned npoints;
struct vsc_pt *points; struct vsc_pt *points;
}; };
...@@ -81,6 +81,10 @@ struct vsc { ...@@ -81,6 +81,10 @@ struct vsc {
struct vsc_sf_head sf_list_include; struct vsc_sf_head sf_list_include;
struct vsc_sf_head sf_list_exclude; struct vsc_sf_head sf_list_exclude;
VTAILQ_HEAD(,vsc_seg) segs; VTAILQ_HEAD(,vsc_seg) segs;
VSC_new_f *fnew;
VSC_destroy_f *fdestroy;
void *priv;
}; };
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -101,34 +105,6 @@ static const size_t nlevels = sizeof(levels)/sizeof(*levels); ...@@ -101,34 +105,6 @@ static const size_t nlevels = sizeof(levels)/sizeof(*levels);
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
struct VSC_point *
VSC_Clone_Point(const struct VSC_point * const 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;
}
/*--------------------------------------------------------------------*/
struct vsc * struct vsc *
VSC_New(void) VSC_New(void)
{ {
...@@ -213,6 +189,18 @@ VSC_Arg(struct vsc *vsc, char arg, const char *opt) ...@@ -213,6 +189,18 @@ VSC_Arg(struct vsc *vsc, char arg, const char *opt)
} }
} }
/*--------------------------------------------------------------------
*/
void
VSC_State(struct vsc *vsc, VSC_new_f *fn, VSC_destroy_f *fd, void *priv)
{
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
vsc->fnew = fn;
vsc->fdestroy = fd;
vsc->priv = priv;
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
*/ */
...@@ -329,16 +317,22 @@ vsc_fill_point(const struct vsc *vsc, const struct vsm_fantom *fantom, ...@@ -329,16 +317,22 @@ vsc_fill_point(const struct vsc *vsc, const struct vsm_fantom *fantom,
} }
static void static void
vsc_del_seg(struct vsm *vsm, struct vsc_seg *sp) vsc_del_seg(const struct vsc *vsc, struct vsm *vsm, struct vsc_seg *sp)
{ {
unsigned u; unsigned u;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
AN(vsm); AN(vsm);
CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC); CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
AZ(VSM_Unmap(vsm, sp->fantom)); AZ(VSM_Unmap(vsm, sp->fantom));
vjsn_delete(&sp->vj); vjsn_delete(&sp->vj);
for(u = 0; u < sp->npoints; u++) pp = sp->points;
vsc_clean_point(&sp->points[u]); for(u = 0; u < sp->npoints; u++, pp++) {
if (vsc->fdestroy != NULL)
vsc->fdestroy(vsc->priv, &pp->point);
vsc_clean_point(pp);
}
free(sp->points); free(sp->points);
FREE_OBJ(sp); FREE_OBJ(sp);
} }
...@@ -348,11 +342,11 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp) ...@@ -348,11 +342,11 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
{ {
struct vsc_seg *sp; struct vsc_seg *sp;
uint64_t u; uint64_t u;
unsigned j;
const char *p; const char *p;
const char *e; const char *e;
struct vjsn_val *vv, *vve; struct vjsn_val *vv, *vve;
struct vsb *vsb; struct vsb *vsb;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
AN(vsm); AN(vsm);
...@@ -380,37 +374,41 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp) ...@@ -380,37 +374,41 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
AN(sp->points); AN(sp->points);
vsb = VSB_new_auto(); vsb = VSB_new_auto();
AN(vsb); AN(vsb);
j = 0;
vve = vjsn_child(sp->vj->value, "elem"); vve = vjsn_child(sp->vj->value, "elem");
AN(vve); AN(vve);
VTAILQ_FOREACH(vv, &vve->children, list) pp = sp->points;
(void)vsc_fill_point(vsc, sp->fantom, vv, vsb, sp->points + j++); VTAILQ_FOREACH(vv, &vve->children, list) {
if (vsc_fill_point(vsc, sp->fantom, vv, vsb, pp) &&
vsc->fnew != NULL)
pp->point.priv = vsc->fnew(vsc->priv, &pp->point);
pp++;
}
VSB_destroy(&vsb); VSB_destroy(&vsb);
AN(sp->vj); AN(sp->vj);
return (sp); return (sp);
} }
static int static int
vsc_iter_seg(const struct vsc_seg *sp, VSC_iter_f *fiter, void *priv) vsc_iter_seg(const struct vsc *vsc, const struct vsc_seg *sp,
VSC_iter_f *fiter, void *priv)
{ {
unsigned u; unsigned u;
int i = 0; int i = 0;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC); CHECK_OBJ_NOTNULL(sp, VSC_SEG_MAGIC);
AN(fiter); AN(fiter);
for(u = 0; u < sp->npoints; u++) { pp = sp->points;
if (sp->points[u].name != NULL) { for(u = 0; u < sp->npoints && i == 0; u++, pp++) {
i = fiter(priv, &sp->points[u].point); if (pp->name != NULL)
if (i) i = fiter(priv, &pp->point);
break;
}
} }
return (i); return (i);
} }
int int
VSC_Iter(struct vsc *vsc, struct vsm *vsm, VSC_Iter(struct vsc *vsc, struct vsm *vsm, VSC_iter_f *fiter, void *priv)
VSC_new_f *fnew, VSC_iter_f *fiter, VSC_destroy_f *fdestroy, void *priv)
{ {
struct vsm_fantom ifantom; struct vsm_fantom ifantom;
struct vsc_seg *sp, *sp2; struct vsc_seg *sp, *sp2;
...@@ -418,8 +416,6 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm, ...@@ -418,8 +416,6 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC); CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
AN(vsm); AN(vsm);
(void)fnew;
(void)fdestroy;
sp = VTAILQ_FIRST(&vsc->segs); sp = VTAILQ_FIRST(&vsc->segs);
VSM_FOREACH(&ifantom, vsm) { VSM_FOREACH(&ifantom, vsm) {
if (strcmp(ifantom.class, VSC_CLASS)) if (strcmp(ifantom.class, VSC_CLASS))
...@@ -430,20 +426,28 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm, ...@@ -430,20 +426,28 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
sp2 = sp; sp2 = sp;
sp = VTAILQ_NEXT(sp, list); sp = VTAILQ_NEXT(sp, list);
VTAILQ_REMOVE(&vsc->segs, sp2, list); VTAILQ_REMOVE(&vsc->segs, sp2, list);
vsc_del_seg(vsm, sp2); vsc_del_seg(vsc, vsm, sp2);
} }
if (sp != NULL) { if (sp != NULL) {
i = vsc_iter_seg(sp, fiter, priv); if (fiter != NULL)
i = vsc_iter_seg(vsc, sp, fiter, priv);
sp = VTAILQ_NEXT(sp, list); sp = VTAILQ_NEXT(sp, list);
} else { } else {
sp = vsc_add_seg(vsc, vsm, &ifantom); sp = vsc_add_seg(vsc, vsm, &ifantom);
VTAILQ_INSERT_TAIL(&vsc->segs, sp, list); VTAILQ_INSERT_TAIL(&vsc->segs, sp, list);
i = vsc_iter_seg(sp, fiter, priv); if (fiter != NULL)
i = vsc_iter_seg(vsc, sp, fiter, priv);
sp = NULL; sp = NULL;
} }
if (i) if (i)
break; break;
} }
while (sp != NULL) {
sp2 = sp;
sp = VTAILQ_NEXT(sp, list);
VTAILQ_REMOVE(&vsc->segs, sp2, list);
vsc_del_seg(vsc, vsm, sp2);
}
return (i); return (i);
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
#include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
...@@ -353,7 +354,7 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb) ...@@ -353,7 +354,7 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
retval |= VSM_MGT_CHANGED; retval |= VSM_MGT_CHANGED;
vs->fd = openat(vs->dfd, "_.index", O_RDONLY); vs->fd = openat(vs->dfd, "_.index", O_RDONLY);
if (vs->fd < 0) if (vs->fd < 0)
return (retval|VSM_NUKE_ALL); return (retval|VSM_MGT_RESTARTED);
AZ(fstat(vs->fd, &vs->fst)); AZ(fstat(vs->fd, &vs->fst));
...@@ -376,17 +377,17 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb) ...@@ -376,17 +377,17 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
* XXX: be kill(pid,0)'ed for more rapid abandonment detection. * XXX: be kill(pid,0)'ed for more rapid abandonment detection.
*/ */
i = sscanf(VSB_data(vsb), "# %ju %ju\n%n", &id1, &id2, &ac); i = sscanf(VSB_data(vsb), "# %ju %ju\n%n", &id1, &id2, &ac);
if (i != 2) { if (i != 2 || kill(id1, 0)) {
retval |= VSM_MGT_RESTARTED; retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
return (retval|VSM_NUKE_ALL); return (retval);
} }
retval |= VSM_MGT_RUNNING;
if (id1 != vs->id1 || id2 != vs->id2) { if (id1 != vs->id1 || id2 != vs->id2) {
retval |= VSM_MGT_RESTARTED; retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
vs->id1 = id1; vs->id1 = id1;
vs->id2 = id2; vs->id2 = id2;
} }
p = VSB_data(vsb) + ac; p = VSB_data(vsb) + ac;
retval |= VSM_MGT_RUNNING;
VTAILQ_FOREACH(vg, &vs->segs, list) VTAILQ_FOREACH(vg, &vs->segs, list)
vg->markscan = 0; vg->markscan = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment