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)
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, NULL);
(void)VSC_Iter(vsc, vsm, do_xml_cb, NULL);
printf("</varnishstat>\n");
}
......@@ -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));
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");
}
......@@ -199,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, NULL, &op);
(void)VSC_Iter(vsc, vsm, NULL, do_once_cb, NULL, &op);
(void)VSC_Iter(vsc, vsm, do_once_cb_first, &op);
(void)VSC_Iter(vsc, vsm, do_once_cb, &op);
}
/*--------------------------------------------------------------------*/
......@@ -230,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, NULL);
(void)VSC_Iter(vsc, vsm, do_list_cb, NULL);
}
/*--------------------------------------------------------------------*/
......
......@@ -72,7 +72,7 @@ struct pt {
#define PT_MAGIC 0x41698E4F
VTAILQ_ENTRY(pt) list;
struct VSC_point *vpt;
const struct VSC_point *vpt;
char seen;
......@@ -119,6 +119,7 @@ static int sample = 0;
static int scale = 1;
static double t_sample = 0.;
static double interval = 1.;
static int vsm_status = 0;
static void
init_hitrate(void)
......@@ -225,130 +226,6 @@ build_pt_array(void)
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
sample_points(void)
{
......@@ -527,12 +404,23 @@ print_duration(WINDOW *w, time_t t)
(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
draw_status(void)
{
time_t up_mgt = 0;
time_t up_chld = 0;
static const char discon[] = "*** DISCONNECTED ***";
AN(w_status);
......@@ -543,14 +431,12 @@ draw_status(void)
if (main_uptime != NULL)
up_chld = *main_uptime;
mvwprintw(w_status, 0, 0, "Uptime mgt: ");
print_duration(w_status, up_mgt);
mvwprintw(w_status, 1, 0, "Uptime child:");
print_duration(w_status, up_chld);
mvwprintw(w_status, 0, 0, "Uptime mgt: ");
running(w_status, up_mgt, VSM_MGT_RUNNING);
mvwprintw(w_status, 1, 0, "Uptime child: ");
running(w_status, up_chld, VSM_WRK_RUNNING);
if (mgt_uptime == NULL)
mvwprintw(w_status, 0, COLS - strlen(discon), discon);
else if (COLS > 70) {
if (COLS > 70) {
mvwprintw(w_status, 0, getmaxx(w_status) - 37,
"Hitrate n: %8u %8u %8u", hitrate.hr_10.n, hitrate.hr_100.n,
hitrate.hr_1000.n);
......@@ -1042,12 +928,62 @@ handle_keypress(int ch)
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
do_curses(struct vsm *vd, struct vsc *vsc, double delay)
do_curses(struct vsm *vsm, struct vsc *vsc, double delay)
{
struct pollfd pollfd;
long t;
int ch, initial = 1;
int ch;
double now;
interval = delay;
......@@ -1066,13 +1002,17 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
make_windows();
doupdate();
VSC_State(vsc, newpt, delpt, NULL);
rebuild = 1;
while (keep_running) {
if (initial ||
(VSM_Status(vd) & (VSM_MGT_CHANGED|VSM_WRK_CHANGED))) {
vsm_status = VSM_Status(vsm);
rebuild |= vsm_status & ~(VSM_MGT_RUNNING|VSM_WRK_RUNNING);
if (rebuild) {
(void)VSC_Iter(vsc, vsm, NULL, NULL);
init_hitrate();
delete_pt_list();
build_pt_list(vsc, vd);
initial = 0;
build_pt_array();
redraw = 1;
}
now = VTIM_mono();
......@@ -1080,8 +1020,6 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
sample = 1;
if (sample)
sample_data();
if (rebuild)
build_pt_array();
if (redraw)
draw_screen();
......@@ -1103,6 +1041,8 @@ do_curses(struct vsm *vd, struct vsc *vsc, double delay)
break;
}
}
VSM_Destroy(&vd);
VSC_Destroy(&vsc);
AN(VTAILQ_EMPTY(&ptlist));
VSM_Destroy(&vsm);
AZ(endwin());
}
......@@ -849,7 +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, 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)
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, NULL, &sp);
good = VSC_Iter(v->vsc, v->vsm_vsc, do_expect_cb, &sp);
if (!good) {
good = -2;
continue;
......
......@@ -41,25 +41,6 @@ struct vsm;
struct vsc;
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 {
const char *name; /* name */
const char *label; /* label */
......@@ -71,50 +52,104 @@ struct VSC_point {
const volatile uint64_t *ptr; /* field value */
const char *name; /* field name */
const char *ctype; /* C-type */
int semantics; /* semantics */
int format; /* display format */
int semantics; /* semantics
* '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 char *sdesc; /* short 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);
void VSC_Destroy_Point(struct VSC_point **);
/*---------------------------------------------------------------------
* Function pointers
*/
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_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
* each counter not suppressed by any "-f" arguments.
* Create a new VSC instance
*/
void VSC_Destroy(struct vsc **);
/*
* Destroy a VSC instance
*
* fantom points to a struct vsm_fantom. If non-NULL, it can be
* used with VSM_StillValid to check the validity of the points
* returned.
* If a destroy function was installed with VSC_State()
* it will be called for all remaining points
*/
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
* VSM_StillValid(,fantom) starts returning anything but
* VSM_valid, or until the next call to VSC_Iter. Using the point
* values after any of these events gives undefined behavior.
* Return:
* -1 error, VSM_Error() returns diagnostic string
* 0 not handled
* 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
* change (child restart, allocations/deallocations)
* To discover new/deleted points, call VSM_Status() first.
*
* The returned points are valid until the next call to VSC_Iter()
*
* Arguments:
* vd: The vsm context
* fantom: Pointer to a fantom. Can be NULL.
* func: The callback function
* priv: Passed as argument to func
*
* Returns:
* !=0: func returned non-zero
* -1: No VSC's available
* 0: Done
*/
const struct VSC_level_desc *VSC_ChangeLevel(const struct VSC_level_desc*, int);
/*
* Change a level up or down.
*/
#endif /* VAPI_VSC_H_INCLUDED */
......@@ -195,5 +195,5 @@ LIBVARNISHAPI_1.7 {
VSM_Dup;
VSC_New;
VSC_Destroy;
VSC_Iter2;
VSC_State;
} LIBVARNISHAPI_1.0;
......@@ -69,7 +69,7 @@ struct vsc_seg {
#define VSC_SEG_MAGIC 0x801177d4
VTAILQ_ENTRY(vsc_seg) list;
struct vsm_fantom fantom[1];
struct vjsn *vj;
struct vjsn *vj;
unsigned npoints;
struct vsc_pt *points;
};
......@@ -81,6 +81,10 @@ struct vsc {
struct vsc_sf_head sf_list_include;
struct vsc_sf_head sf_list_exclude;
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);
/*--------------------------------------------------------------------*/
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 *
VSC_New(void)
{
......@@ -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,
}
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;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
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]);
pp = sp->points;
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_OBJ(sp);
}
......@@ -348,11 +342,11 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
{
struct vsc_seg *sp;
uint64_t u;
unsigned j;
const char *p;
const char *e;
struct vjsn_val *vv, *vve;
struct vsb *vsb;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
AN(vsm);
......@@ -380,37 +374,41 @@ vsc_add_seg(const struct vsc *vsc, struct vsm *vsm, const struct vsm_fantom *fp)
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++);
pp = sp->points;
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);
AN(sp->vj);
return (sp);
}
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;
int i = 0;
struct vsc_pt *pp;
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
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;
}
pp = sp->points;
for(u = 0; u < sp->npoints && i == 0; u++, pp++) {
if (pp->name != NULL)
i = fiter(priv, &pp->point);
}
return (i);
}
int
VSC_Iter(struct vsc *vsc, struct vsm *vsm,
VSC_new_f *fnew, VSC_iter_f *fiter, VSC_destroy_f *fdestroy, void *priv)
VSC_Iter(struct vsc *vsc, struct vsm *vsm, VSC_iter_f *fiter, void *priv)
{
struct vsm_fantom ifantom;
struct vsc_seg *sp, *sp2;
......@@ -418,8 +416,6 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
CHECK_OBJ_NOTNULL(vsc, VSC_MAGIC);
AN(vsm);
(void)fnew;
(void)fdestroy;
sp = VTAILQ_FIRST(&vsc->segs);
VSM_FOREACH(&ifantom, vsm) {
if (strcmp(ifantom.class, VSC_CLASS))
......@@ -430,20 +426,28 @@ VSC_Iter(struct vsc *vsc, struct vsm *vsm,
sp2 = sp;
sp = VTAILQ_NEXT(sp, list);
VTAILQ_REMOVE(&vsc->segs, sp2, list);
vsc_del_seg(vsm, sp2);
vsc_del_seg(vsc, vsm, sp2);
}
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);
} else {
sp = vsc_add_seg(vsc, vsm, &ifantom);
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;
}
if (i)
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);
}
......
......@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <float.h>
#include <math.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
......@@ -353,7 +354,7 @@ vsm_refresh_set2(struct vsm *vd, struct vsm_set *vs, struct vsb *vsb)
retval |= VSM_MGT_CHANGED;
vs->fd = openat(vs->dfd, "_.index", O_RDONLY);
if (vs->fd < 0)
return (retval|VSM_NUKE_ALL);
return (retval|VSM_MGT_RESTARTED);
AZ(fstat(vs->fd, &vs->fst));
......@@ -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.
*/
i = sscanf(VSB_data(vsb), "# %ju %ju\n%n", &id1, &id2, &ac);
if (i != 2) {
retval |= VSM_MGT_RESTARTED;
return (retval|VSM_NUKE_ALL);
if (i != 2 || kill(id1, 0)) {
retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
return (retval);
}
retval |= VSM_MGT_RUNNING;
if (id1 != vs->id1 || id2 != vs->id2) {
retval |= VSM_MGT_RESTARTED;
retval |= VSM_MGT_RESTARTED | VSM_MGT_CHANGED;
vs->id1 = id1;
vs->id2 = id2;
}
p = VSB_data(vsb) + ac;
retval |= VSM_MGT_RUNNING;
VTAILQ_FOREACH(vg, &vs->segs, list)
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