static void
pan_backtrace(struct vsb *vsb)
{
	void *array[10];
	size_t size;
	size_t i;
	char **strings;
	char *p;

	size = backtrace (array, 10);
	if (size == 0)
		return;
	VSB_printf(vsb, "Backtrace:\n");
	VSB_indent(vsb, 2);
	for (i = 0; i < size; i++) {
		if (Symbol_Lookup(vsb, array[i]) < 0) {
			strings = backtrace_symbols(&array[i], 1);
			if (strings == NULL || strings[0] == NULL) {
				VSB_printf(vsb, "%p: (?)", array[i]);
			} else {
				p = strrchr(strings[0], '/');
				if (p == NULL)
					p = strings[0];
				else
					p++;
				VSB_printf(vsb, "%p: %s", array[i], p);
			}
		}
		VSB_printf (vsb, "\n");
	}
	VSB_indent(vsb, -2);
}
static void
pan_ws(struct vsb *vsb, const struct ws *ws)
{

	VSB_printf(vsb, "ws = %p {\n", ws);
	VSB_indent(vsb, 2);
	if (WS_Overflowed(ws))
		VSB_printf(vsb, "OVERFLOW ");
	VSB_printf(vsb, "id = \"%s\",\n",  ws->id);
	VSB_printf(vsb, "{s,f,r,e} = {%p",  ws->s);
	if (ws->f > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->f - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->f);
	if (ws->r > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->r - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->r);
	if (ws->e > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->e - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->e);
	VSB_printf(vsb, "},\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_sess(struct vsb *vsb, const struct sess *sp)
{
	const char *stp;
	char *ci;
	char *cp;

	VSB_printf(vsb, "sp = %p {\n", sp);
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "fd = %d, vxid = %u,\n", sp->fd, VXID(sp->vxid));
	AZ(SES_Get_client_ip(sp, &ci));
	AZ(SES_Get_client_port(sp, &cp));
	VSB_printf(vsb, "client = %s %s,\n", ci, cp);
	switch (sp->sess_step) {
#define SESS_STEP(l, u) case S_STP_##u: stp = "S_STP_" #u; break;
#include "tbl/steps.h"
#undef SESS_STEP
		default: stp = NULL;
	}
	if (stp != NULL)
		VSB_printf(vsb, "step = %s,\n", stp);
	else
		VSB_printf(vsb, "step = 0x%x,\n", sp->sess_step);

	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_objcore(struct vsb *vsb, const char *typ, const struct objcore *oc)
{

	VSB_printf(vsb, "objcore[%s] = %p {\n", typ, oc);
	if (pan_already(vsb, oc))
		return;
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "refcnt = %d,\n", oc->refcnt);
	VSB_printf(vsb, "flags = 0x%x,\n", oc->flags);
	VSB_printf(vsb, "exp_flags = 0x%x,\n", oc->exp_flags);
	if (oc->boc != NULL)
		pan_boc(vsb, oc->boc);
	VSB_printf(vsb, "exp = { %f, %f, %f, %f }\n",
	    oc->t_origin, oc->ttl, oc->grace, oc->keep);
	VSB_printf(vsb, "objhead = %p,\n", oc->objhead);
	VSB_printf(vsb, "stevedore = %p", oc->stobj->stevedore);
	if (oc->stobj->stevedore != NULL) {
		VSB_printf(vsb, " (%s", oc->stobj->stevedore->name);
		if (strlen(oc->stobj->stevedore->ident))
			VSB_printf(vsb, " %s", oc->stobj->stevedore->ident);
		VSB_printf(vsb, ")");
	}
	VSB_printf(vsb, ",\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_sess(struct vsb *vsb, const struct sess *sp)
{
	const char *ci;
	const char *cp;
	const struct transport *xp;

	VSB_printf(vsb, "sp = %p {\n", sp);
	if (pan_already(vsb, sp))
		return;
	VSB_indent(vsb, 2);
	xp = XPORT_ByNumber(sp->sattr[SA_TRANSPORT]);
	VSB_printf(vsb, "fd = %d, vxid = %u, transport = %s",
	    sp->fd, VXID(sp->vxid),
	    xp == NULL ? "<none>" : xp->name);
	if (xp != NULL && xp->sess_panic != NULL) {
		VSB_printf(vsb, " {\n");
		VSB_indent(vsb, 2);
		xp->sess_panic(vsb, sp);
		VSB_indent(vsb, -2);
		VSB_printf(vsb, "}");
	}
	ci = SES_Get_String_Attr(sp, SA_CLIENT_IP);
	cp = SES_Get_String_Attr(sp, SA_CLIENT_PORT);
	VSB_printf(vsb, "\nclient = %s %s,\n", ci, cp);

	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_htc(struct vsb *vsb, const struct http_conn *htc)
{

	VSB_printf(vsb, "http_conn = %p {\n", htc);
	if (pan_already(vsb, htc))
		return;
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "fd = %d,\n", htc->fd);
	VSB_printf(vsb, "doclose = %s,\n", sess_close_2str(htc->doclose, 0));
	VSB_printf(vsb, "ws = %p,\n", htc->ws);
	VSB_printf(vsb, "{rxbuf_b, rxbuf_e} = {%p, %p},\n",
	    htc->rxbuf_b, htc->rxbuf_e);
	VSB_printf(vsb, "{pipeline_b, pipeline_e} = {%p, %p},\n",
	    htc->pipeline_b, htc->pipeline_e);
	VSB_printf(vsb, "content_length = %jd,\n",
	    (intmax_t)htc->content_length);
	VSB_printf(vsb, "body_status = %s,\n",
	    body_status_2str(htc->body_status));
	VSB_printf(vsb, "first_byte_timeout = %f,\n",
	    htc->first_byte_timeout);
	VSB_printf(vsb, "between_bytes_timeout = %f,\n",
	    htc->between_bytes_timeout);
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_ws(struct vsb *vsb, const struct ws *ws)
{

	VSB_printf(vsb, "ws = %p {\n", ws);
	if (pan_already(vsb, ws))
		return;
	VSB_indent(vsb, 2);
	if (!(ws->id[0] & 0x20))
		VSB_printf(vsb, "OVERFLOWED ");
	VSB_printf(vsb, "id = \"%s\",\n",  ws->id);
	VSB_printf(vsb, "{s,f,r,e} = {%p",  ws->s);
	if (ws->f > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->f - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->f);
	if (ws->r > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->r - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->r);
	if (ws->e > ws->s)
		VSB_printf(vsb, ",+%ld", (long) (ws->e - ws->s));
	else
		VSB_printf(vsb, ",%p", ws->e);
	VSB_printf(vsb, "},\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_busyobj(struct vsb *vsb, const struct busyobj *bo)
{
	struct vfp_entry *vfe;
	const char *p;

	VSB_printf(vsb, "busyobj = %p {\n", bo);
	VSB_indent(vsb, 2);
	pan_ws(vsb, bo->ws);
	VSB_printf(vsb, "refcnt = %u,\n", bo->refcount);
	VSB_printf(vsb, "retries = %d, ", bo->retries);
	VSB_printf(vsb, "failed = %d, ", bo->vfc->failed);
	VSB_printf(vsb, "state = %d,\n", (int)bo->state);
	VSB_printf(vsb, "flags = {");
	p = "";
	/*lint -save -esym(438,p) */
#define BO_FLAG(l, r, w, d) \
	if(bo->l) { VSB_printf(vsb,  "%s" #l, p); p = ", "; }
#include "tbl/bo_flags.h"
#undef BO_FLAG
	/*lint -restore */
	VSB_printf(vsb, "},\n");

	if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC))
		pan_htc(vsb, bo->htc);

	if (!VTAILQ_EMPTY(&bo->vfc->vfp)) {
		VSB_printf(vsb, "filters =");
		VTAILQ_FOREACH(vfe, &bo->vfc->vfp, list)
			VSB_printf(vsb, " %s=%d",
			    vfe->vfp->name, (int)vfe->closed);
		VSB_printf(vsb, "\n");
	}

	VDI_Panic(bo->director_req, vsb, "director_req");
	if (bo->director_resp == bo->director_req)
		VSB_printf(vsb, "director_resp = director_req,\n");
	else
		VDI_Panic(bo->director_resp, vsb, "director_resp");
	if (bo->bereq != NULL && bo->bereq->ws != NULL)
		pan_http(vsb, "bereq", bo->bereq);
	if (bo->beresp != NULL && bo->beresp->ws != NULL)
		pan_http(vsb, "beresp", bo->beresp);
	if (bo->fetch_objcore)
		pan_objcore(vsb, "fetch", bo->fetch_objcore);
	if (bo->stale_oc)
		pan_objcore(vsb, "ims", bo->stale_oc);
	VCL_Panic(vsb, bo->vcl);
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
/*--------------------------------------------------------------------*/
static void
pan_boc(struct vsb *vsb, const struct boc *boc)
{
	VSB_printf(vsb, "boc = %p {\n", boc);
	if (pan_already(vsb, boc))
		return;
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "refcnt = %u,\n", boc->refcount);
	VSB_printf(vsb, "state = %d,\n", boc->state);
	VSB_printf(vsb, "vary = %p,\n", boc->vary);
	VSB_printf(vsb, "stevedore_priv = %p,\n", boc->stevedore_priv);
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
/*lint -e{774} constant value boolean */
void
VBP_Status(struct vsb *vsb, const struct backend *be, int details, int json)
{
	struct vbp_target *vt;
	char buf[12];

	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
	vt = be->probe;
	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);

	if (!details) {
		bprintf(buf, "%u/%u %s", vt->good, vt->window,
		    vt->backend->director->sick ? "bad" : "good");
		if (json)
			VSB_printf(vsb, "\"%s\"", buf);
		else
			VSB_printf(vsb, "%-10s", buf);
		return;
	}

	if (json) {
		VSB_printf(vsb, "{\n");
		VSB_indent(vsb, 2);
#define BITMAP(nn, cc, tt, bb)					\
		VSB_printf(vsb, "\"bits_%c\": %ju,\n", cc, vt->nn);
#include "tbl/backend_poll.h"
		VSB_printf(vsb, "\"good\": %u,\n", vt->good);
		VSB_printf(vsb, "\"threshold\": %u,\n", vt->threshold);
		VSB_printf(vsb, "\"window\": %u", vt->window);
		VSB_indent(vsb, -2);
		VSB_printf(vsb, "\n");
		VSB_printf(vsb, "},\n");
		return;
	}

	VSB_printf(vsb,
	    "\nCurrent states  good: %2u threshold: %2u window: %2u\n",
	    vt->good, vt->threshold, vt->window);
	VSB_printf(vsb,
	    "  Average response time of good probes: %.6f\n", vt->avg);
	VSB_printf(vsb,
	    "  Oldest ======================"
	    "============================ Newest\n");

#define BITMAP(n, c, t, b)					\
		if ((vt->n != 0) || (b))			\
			vbp_bitmap(vsb, (c), vt->n, (t));
#include "tbl/backend_poll.h"
}
static void
pan_wrk(struct vsb *vsb, const struct worker *wrk)
{
	const char *hand;
	unsigned m, u;
	const char *p;

	VSB_printf(vsb, "worker = %p {\n", wrk);
	if (pan_already(vsb, wrk))
		return;
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "stack = {0x%jx -> 0x%jx},\n",
	    (uintmax_t)wrk->stack_start, (uintmax_t)wrk->stack_end);
	pan_ws(vsb, wrk->aws);

	m = wrk->cur_method;
	VSB_printf(vsb, "VCL::method = ");
	if (m == 0) {
		VSB_printf(vsb, "none,\n");
		return;
	}
	if (!(m & 1))
		VSB_printf(vsb, "inside ");
	m &= ~1;
	hand = VCL_Method_Name(m);
	if (hand != NULL)
		VSB_printf(vsb, "%s,\n", hand);
	else
		VSB_printf(vsb, "0x%x,\n", m);

	hand = VCL_Return_Name(wrk->handling);
	if (hand != NULL)
		VSB_printf(vsb, "VCL::return = %s,\n", hand);
	else
		VSB_printf(vsb, "VCL::return = 0x%x,\n", wrk->handling);
	VSB_printf(vsb, "VCL::methods = {");
	m = wrk->seen_methods;
	p = "";
	for (u = 1; m ; u <<= 1) {
		if (m & u) {
			VSB_printf(vsb, "%s%s", p, VCL_Method_Name(u));
			m &= ~u;
			p = ", ";
		}
	}
	VSB_printf(vsb, "},\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_objcore(struct vsb *vsb, const char *typ, const struct objcore *oc)
{

	VSB_printf(vsb, "objcore[%s] = %p {\n", typ, oc);
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "refcnt = %d,\n", oc->refcnt);
	VSB_printf(vsb, "flags = 0x%x,\n", oc->flags);
	VSB_printf(vsb, "objhead = %p,\n", oc->objhead);
	VSB_printf(vsb, "stevedore = %p", oc->stobj->stevedore);
	if (oc->stobj->stevedore != NULL) {
		VSB_printf(vsb, " (%s", oc->stobj->stevedore->name);
		if (strlen(oc->stobj->stevedore->ident))
			VSB_printf(vsb, " %s", oc->stobj->stevedore->ident);
		VSB_printf(vsb, ")");
	}
	VSB_printf(vsb, ",\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_http(struct vsb *vsb, const char *id, const struct http *h)
{
	int i;

	VSB_printf(vsb, "http[%s] = %p {\n", id, h);
	VSB_indent(vsb, 2);
	VSB_printf(vsb, "ws[%s] = %p,\n", h->ws ? h->ws->id : "", h->ws);
	VSB_printf(vsb, "hdrs {\n");
	VSB_indent(vsb, 2);
	for (i = 0; i < h->nhd; ++i) {
		if (h->hd[i].b == NULL && h->hd[i].e == NULL)
			continue;
		VSB_printf(vsb, "\"%.*s\",\n",
		    (int)(h->hd[i].e - h->hd[i].b), h->hd[i].b);
	}
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
static void
pan_req(struct vsb *vsb, const struct req *req)
{
	const char *stp;

	VSB_printf(vsb, "req = %p {\n", req);
	VSB_indent(vsb, 2);

	VSB_printf(vsb, "vxid = %u, ", VXID(req->vsl->wid));

	switch (req->req_step) {
#define REQ_STEP(l, u, arg) case R_STP_##u: stp = "R_STP_" #u; break;
#include "tbl/steps.h"
#undef REQ_STEP
		default: stp = NULL;
	}
	if (stp != NULL)
		VSB_printf(vsb, "step = %s,\n", stp);
	else
		VSB_printf(vsb, "step = 0x%x,\n", req->req_step);

	VSB_printf(vsb, "req_body = %s,\n",
	    reqbody_status_2str(req->req_body_status));

	if (req->err_code)
		VSB_printf(vsb,
		    "err_code = %d, err_reason = %s,\n", req->err_code,
		    req->err_reason ? req->err_reason : "(null)");

	VSB_printf(vsb, "restarts = %d, esi_level = %d,\n",
	    req->restarts, req->esi_level);

	if (req->sp != NULL)
		pan_sess(vsb, req->sp);

	if (req->wrk != NULL)
		pan_wrk(vsb, req->wrk);

	pan_ws(vsb, req->ws);
	if (VALID_OBJ(req->htc, HTTP_CONN_MAGIC))
		pan_htc(vsb, req->htc);
	pan_http(vsb, "req", req->http);
	if (req->resp->ws != NULL)
		pan_http(vsb, "resp", req->resp);

	VCL_Panic(vsb, req->vcl);

	if (req->objcore != NULL) {
		pan_objcore(vsb, "REQ", req->objcore);
		if (req->objcore->busyobj != NULL)
			pan_busyobj(vsb, req->objcore->busyobj);
	}

	VSB_printf(vsb, "flags = {\n");
	VSB_indent(vsb, 2);
#define REQ_FLAG(l, r, w, d) if(req->l) VSB_printf(vsb, #l ",\n");
#include "tbl/req_flags.h"
#undef REQ_FLAG
	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");

	VSB_indent(vsb, -2);
	VSB_printf(vsb, "},\n");
}
Exemple #15
0
void
vdir_list(VRT_CTX, struct vdir *vd, struct vsb *vsb, int pflag, int jflag,
    int weight)
{
	VCL_BACKEND be;
	VCL_BOOL h;
	unsigned u, nh;
	double w;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC);

	if (pflag) {
		if (jflag) {
			VSB_cat(vsb, "{\n");
			VSB_indent(vsb, 2);
			if (weight)
				VSB_printf(vsb, "\"total_weight\": %f,\n",
				    vd->total_weight);
			VSB_cat(vsb, "\"backends\": {\n");
			VSB_indent(vsb, 2);
		} else {
			VSB_cat(vsb, "\n\n\tBackend\tWeight\tHealth\n");
		}
	}

	vdir_rdlock(vd);
	vdir_update_health(ctx, vd);
	for (u = 0; pflag && u < vd->n_backend; u++) {
		be = vd->backend[u];
		CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);

		h = vbit_test(vd->healthy, u);

		w = h ? vd->weight[u] : 0.0;

		if (jflag) {
			if (u)
				VSB_cat(vsb, ",\n");
			VSB_printf(vsb, "\"%s\": {\n", be->vcl_name);
			VSB_indent(vsb, 2);

			if (weight)
				VSB_printf(vsb, "\"weight\": %f,\n", w);

			if (h)
				VSB_cat(vsb, "\"health\": \"healthy\"\n");
			else
				VSB_cat(vsb, "\"health\": \"sick\"\n");

			VSB_indent(vsb, -2);
			VSB_cat(vsb, "}");
		} else {
			VSB_cat(vsb, "\t");
			VSB_cat(vsb, be->vcl_name);
			if (weight)
				VSB_printf(vsb, "\t%6.2f%%\t",
				    100 * w / vd->total_weight);
			else
				VSB_cat(vsb, "\t-\t");
			VSB_cat(vsb, h ? "healthy" : "sick");
			VSB_cat(vsb, "\n");
		}
	}
	nh = vd->n_healthy;
	u = vd->n_backend;
	vdir_unlock(vd);

	if (jflag && (pflag)) {
		VSB_cat(vsb, "\n");
		VSB_indent(vsb, -2);
		VSB_cat(vsb, "}\n");
		VSB_indent(vsb, -2);
		VSB_cat(vsb, "},\n");
	}

	if (pflag)
		return;

	if (jflag)
		VSB_printf(vsb, "[%u, %u, \"%s\"]", nh, u,
		    nh ? "healthy" : "sick");
	else
		VSB_printf(vsb, "%u/%u\t%s", nh, u, nh ? "healthy" : "sick");
}