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"); }
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"); }