static int sv_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { sv_dev_t *svp; int a_opt, v_opt; int dev_t_chars; a_opt = v_opt = FALSE; dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ if (mdb_getopts(argc, argv, 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) return (DCMD_USAGE); svp = mdb_zalloc(sizeof (*svp), UM_GC); if (!(flags & DCMD_ADDRSPEC)) { /* * paranoid mode on: qualify walker name with module name * using '`' syntax. */ if (mdb_walk_dcmd("sv`sv_dev", "sv`sv_dev", argc, argv) == -1) { mdb_warn("failed to walk 'sv_dev'"); return (DCMD_ERR); } return (DCMD_OK); } if (DCMD_HDRSPEC(flags)) { mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", dev_t_chars, "DEV", "STATE"); } if (mdb_vread(svp, sizeof (*svp), addr) != sizeof (*svp)) { mdb_warn("failed to read sv_dev at %p", addr); return (DCMD_ERR); } if (!a_opt && svp->sv_state == SV_DISABLE) return (DCMD_OK); mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, svp->sv_dev); if (svp->sv_state == SV_DISABLE) mdb_printf("disabled"); else if (svp->sv_state == SV_PENDING) mdb_printf("pending"); else if (svp->sv_state == SV_ENABLE) mdb_printf("enabled"); mdb_printf("\n"); if (!v_opt) return (DCMD_OK); /* * verbose - print the rest of the structure as well. */ mdb_inc_indent(4); mdb_printf("\n"); mdb_printf("hash chain: 0x%p %8Tlock: 0x%p %8Tolock: 0x%p\n", svp->sv_hash, addr + OFFSETOF(sv_dev_t, sv_lock), addr + OFFSETOF(sv_dev_t, sv_olock)); mdb_printf("fd: 0x%p %8T\n", svp->sv_fd); mdb_printf("maxfbas: %d %8Tnblocks: %d %8Tstate: %d\n", svp->sv_maxfbas, svp->sv_nblocks, svp->sv_state); mdb_printf("gclients: 0x%llx %8Tgkernel: 0x%llx\n", svp->sv_gclients, svp->sv_gkernel); mdb_printf("openlcnt: %d %8Ttimestamp: 0x%lx\n", svp->sv_openlcnt, svp->sv_timestamp); mdb_printf("flags: 0x%08x <%b>\n", svp->sv_flag, svp->sv_flag, sv_flag_bits); mdb_printf("lh: 0x%p %8Tpending: 0x%p\n", svp->sv_lh, svp->sv_pending); mdb_dec_indent(4); return (DCMD_OK); }
/* * Display a single sv_maj_t structure. * If called with no address, performs a global walk of all sv_majs. * -a : all (i.e. display all devices, even if disabled * -v : verbose */ static int sv_maj(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { sv_maj_t *maj; int a_opt, v_opt; int i; a_opt = v_opt = FALSE; if (mdb_getopts(argc, argv, 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { /* * paranoid mode on: qualify walker name with module name * using '`' syntax. */ if (mdb_walk_dcmd("sv`sv_maj", "sv`sv_maj", argc, argv) == -1) { mdb_warn("failed to walk 'sv_maj'"); return (DCMD_ERR); } return (DCMD_OK); } if (DCMD_HDRSPEC(flags)) { mdb_printf("%-?s %8T%s\n", "ADDR", "INUSE"); } maj = mdb_zalloc(sizeof (*maj), UM_GC); if (mdb_vread(maj, sizeof (*maj), addr) != sizeof (*maj)) { mdb_warn("failed to read sv_maj at %p", addr); return (DCMD_ERR); } if (!a_opt && maj->sm_inuse == 0) return (DCMD_OK); mdb_printf("%?p %8T%d\n", addr, maj->sm_inuse); if (!v_opt) return (DCMD_OK); /* * verbose - print the rest of the structure as well. */ mdb_inc_indent(4); mdb_printf("\n"); mdb_printf("dev_ops: %a (%p)\n", maj->sm_dev_ops, maj->sm_dev_ops); mdb_printf("flag: %08x %8Tsequence: %d %8Tmajor: %d\n", maj->sm_flag, maj->sm_seq, maj->sm_major); mdb_printf("function pointers:\n"); mdb_inc_indent(4); mdb_printf("%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n", maj->sm_open, maj->sm_close, maj->sm_read, maj->sm_write, maj->sm_aread, maj->sm_awrite, maj->sm_strategy, maj->sm_ioctl); mdb_dec_indent(4); mdb_printf("hash chain:\n"); mdb_inc_indent(4); for (i = 0; i < SV_MINOR_HASH_CNT; i++) { mdb_printf("%?p", maj->sm_hash[i]); mdb_printf(((i % 4) == 3) ? "\n" : " %8T"); } mdb_printf("\n\n"); mdb_dec_indent(4); mdb_dec_indent(4); return (DCMD_OK); }
/* * Print the core fields in an NCA node_t. With the "-r" argument, * provide additional information about the request; with "-v", * provide more verbose output. */ static int nca_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { unsigned int i, max; unsigned int verbose = FALSE; unsigned int request = FALSE; const int NODE_REFDELT = NCA_ADDR_WIDTH + 4 + 2; boolean_t arm; node_t node; char *buf; namedmem_t hdr[4]; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 'r', MDB_OPT_SETBITS, TRUE, &request, 'p', NULL) != argc) return (DCMD_USAGE); if (!DCMD_HDRSPEC(flags) && verbose) mdb_printf("\n\n"); if (DCMD_HDRSPEC(flags) || verbose) { mdb_printf("%<u>%-*s %4s %5s %8s %-*s %-*s %-*s %-*s%</u>\n", NCA_ADDR_WIDTH, "ADDR", "REF", "STATE", "DATASIZE", NCA_ADDR_WIDTH, "SQUEUE", NCA_ADDR_WIDTH, "REQUEST", NCA_ADDR_WIDTH, "PLRUN", NCA_ADDR_WIDTH, "VLRUN"); } if (mdb_vread(&node, sizeof (node_t), addr) == -1) { mdb_warn("cannot read node_t at %p", addr); return (DCMD_ERR); } mdb_printf("%0*p %4d %05x %8d %0*p %0*p %0*p %0*p\n", NCA_ADDR_WIDTH, addr, node.cnt, node.ref, node.datasz, NCA_ADDR_WIDTH, node.sqp, NCA_ADDR_WIDTH, node.req, NCA_ADDR_WIDTH, node.plrunn, NCA_ADDR_WIDTH, node.vlrunn); if (verbose) { arm = B_TRUE; for (i = 0; node_refs[i].bit_name != NULL; i++) { if ((node.ref & (1 << i)) == 0) continue; if (arm) { mdb_printf("%*s|\n", NODE_REFDELT, ""); mdb_printf("%*s+--> ", NODE_REFDELT, ""); arm = B_FALSE; } else mdb_printf("%*s ", NODE_REFDELT, ""); mdb_printf("%-12s %s\n", node_refs[i].bit_name, node_refs[i].bit_descr); } } if (!request || node.req == NULL) return (DCMD_OK); mdb_inc_indent(4); mdb_printf("\n%u byte HTTP/%u.%u %s request (%u bytes in header, " "%u in content)\n", node.reqsz, node.version >> 16, node.version & 0xff, method2name(node.method), node.reqhdrsz, node.reqcontl); hdr[0].nm_name = "URI"; hdr[0].nm_addr = (uintptr_t)node.path; hdr[0].nm_len = node.pathsz; hdr[1].nm_name = "Accept"; hdr[1].nm_addr = (uintptr_t)node.reqaccept; hdr[1].nm_len = node.reqacceptsz; hdr[2].nm_name = "Accept-Language"; hdr[2].nm_addr = (uintptr_t)node.reqacceptl; hdr[2].nm_len = node.reqacceptlsz; hdr[3].nm_name = "Host"; hdr[3].nm_addr = (uintptr_t)node.reqhost; hdr[3].nm_len = node.reqhostsz; /* * A little optimization. Allocate all of the necessary memory here, * so we don't have to allocate on each loop iteration. */ max = node.reqhdrsz; for (i = 0; i < 4; i++) max = MAX(max, hdr[i].nm_len); max++; buf = mdb_alloc(max, UM_SLEEP); mdb_inc_indent(4); for (i = 0; i < sizeof (hdr) / sizeof (hdr[0]); i++) { if (hdr[i].nm_len <= 0) continue; if (mdb_vread(buf, hdr[i].nm_len, hdr[i].nm_addr) == -1) { mdb_warn("cannot read \"%s\" header field at %p", hdr[i].nm_name, hdr[i].nm_addr); continue; } buf[hdr[i].nm_len] = '\0'; mdb_printf("%s: ", hdr[i].nm_name); mdb_inc_indent(4); mdb_printf("%s\n", buf); mdb_dec_indent(4); } if (node.reqhdrsz > 0 && verbose) { if (mdb_vread(buf, node.reqhdrsz, (uintptr_t)node.reqhdr) == -1) mdb_warn("cannot read header at %p", node.reqhdr); else { mdb_printf("Raw header: "); mdb_inc_indent(4); printbuf((uint8_t *)buf, node.reqhdrsz); mdb_dec_indent(4); } } mdb_dec_indent(4); mdb_dec_indent(4); mdb_free(buf, max); return (DCMD_OK); }
/* * Print the core fields for one or all NCA timers. If no address is * specified, all NCA timers are printed; otherwise the specified timer * list is printed. With the "-e" argument, the "encapsulated" pointer * for each te_t in a given tb_t is shown in parentheses. */ static int nca_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { unsigned int show_encap = FALSE; void *tb_addr, *te_addr; clock_t lbolt, first_exec = 0; ti_t ti; tb_t tb; te_t te; if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk_dcmd("nca_timer", "nca_timer", argc, argv) == -1) { mdb_warn("cannot walk timer list"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_getopts(argc, argv, 'e', MDB_OPT_SETBITS, TRUE, &show_encap, NULL) != argc) return (DCMD_USAGE); if (DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%-*s %-*s %-55s%</u>\n", NCA_ADDR_WIDTH, "TI", NCA_ADDR_WIDTH, "SQUEUE", "FIRELIST +MSEC"); } if (mdb_vread(&ti, sizeof (ti_t), addr) == -1) { mdb_warn("cannot read ti_t at %p", addr); return (DCMD_ERR); } if (mdb_readvar(&lbolt, "lbolt") == -1) { mdb_warn("cannot read symbol lbolt"); return (DCMD_ERR); } mdb_printf("%0*p %0*p", NCA_ADDR_WIDTH, addr, NCA_ADDR_WIDTH, ti.ep); mdb_inc_indent(24); for (tb_addr = ti.head; tb_addr != NULL; tb_addr = tb.next) { if (mdb_vread(&tb, sizeof (tb_t), (uintptr_t)tb_addr) == -1) { mdb_warn("cannot read tb_t at %p", tb_addr); return (DCMD_ERR); } if (first_exec == 0) { mdb_printf(" %ld", tick2msec(tb.exec - lbolt)); first_exec = tb.exec; } else mdb_printf(" %+lld", tick2msec(tb.exec - first_exec)); if (!show_encap || tb.head == NULL) continue; mdb_printf("("); for (te_addr = tb.head; te_addr != NULL; te_addr = te.next) { if (mdb_vread(&te, sizeof (te_t), (uintptr_t)te_addr) == -1) { mdb_warn("cannot read te_t at %p", te_addr); return (DCMD_ERR); } mdb_printf("%0p%s", te.ep, te.next == NULL ? "" : " "); } mdb_printf(")"); } mdb_printf("\n"); mdb_dec_indent(24); return (DCMD_OK); }
/* * Print the core fields in an nca_io2_t. With the "-v" argument, * provide more verbose output. With the "-p" argument, print payload * information. */ static int nca_io2(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { unsigned int i; unsigned int payload_len; uint64_t payload_output_max = 0; unsigned int verbose = FALSE; const int IO2_ADVDELT = NCA_ADDR_WIDTH + 1; boolean_t arm; nca_io2_t io2; uint8_t *buf; namedmem_t area[3]; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 'p', MDB_OPT_UINT64, &payload_output_max, NULL) != argc) return (DCMD_USAGE); if (!DCMD_HDRSPEC(flags) && verbose) mdb_printf("\n\n"); if (DCMD_HDRSPEC(flags) || verbose) { mdb_printf("%<u>%-*s %2s %4s %8s %*s %8s %16s %-12s%</u>\n", NCA_ADDR_WIDTH, "ADDR", "AV", "MFNP", "TID", NCA_ADDR_WIDTH, "CONN", "CONN_TAG", "CACHE_TAG", "OPERATION"); } if (mdb_vread(&io2, sizeof (nca_io2_t), addr) == -1) { mdb_warn("cannot read nca_io2_t at %p", addr); return (DCMD_ERR); } if (io2.version != NCA_HTTP_VERSION2) mdb_warn("nca_io2_t at %p has incorrect version `%u'\n", addr, io2.version); mdb_printf("%0*p %02x %c%c%c%c %08x %0*llx %08x %016llx %s\n", NCA_ADDR_WIDTH, addr, io2.advisory, YESNO(io2.more), YESNO(io2.first), YESNO(io2.nocache), YESNO(io2.preempt), (uint32_t)io2.tid, NCA_ADDR_WIDTH, io2.cid, io2.tag, io2.ctag, op2name(io2.op)); if (verbose) { arm = B_TRUE; for (i = 0; advise_types[i].bit_name != NULL; i++) { if ((io2.advisory & (1 << i)) == 0) continue; if (arm) { mdb_printf("%*s|\n", IO2_ADVDELT, ""); mdb_printf("%*s+--> ", IO2_ADVDELT, ""); arm = B_FALSE; } else mdb_printf("%*s ", IO2_ADVDELT, ""); mdb_printf("%-15s %s\n", advise_types[i].bit_name, advise_types[i].bit_descr); } } payload_len = io2.data_len + io2.direct_len + io2.trailer_len; if (payload_output_max == 0 || payload_len == 0) return (DCMD_OK); mdb_inc_indent(4); mdb_printf("\n%u byte payload consists of:\n", payload_len); mdb_inc_indent(4); buf = mdb_alloc(payload_output_max, UM_SLEEP); area[0].nm_name = "data"; area[0].nm_addr = addr + io2.data; area[0].nm_len = io2.data_len; area[1].nm_name = direct2name(io2.direct_type); area[1].nm_addr = addr + io2.direct; area[1].nm_len = io2.direct_len; area[2].nm_name = "trailer"; area[2].nm_addr = addr + io2.trailer; area[2].nm_len = io2.trailer_len; for (i = 0; i < sizeof (area) / sizeof (area[0]); i++) { if (area[i].nm_len <= 0) continue; mdb_printf("%d byte %s area at %p (", area[i].nm_len, area[i].nm_name, area[i].nm_addr); if (area[i].nm_len > payload_output_max) { mdb_printf("first"); area[i].nm_len = (int)payload_output_max; } else mdb_printf("all"); mdb_printf(" %u bytes follow):\n", area[i].nm_len); if (mdb_vread(buf, area[i].nm_len, area[i].nm_addr) == -1) mdb_warn("cannot read %s area at %p", area[i].nm_name, area[i].nm_addr); else { mdb_inc_indent(4); printbuf(buf, area[i].nm_len); mdb_dec_indent(4); } } mdb_dec_indent(4); mdb_dec_indent(4); mdb_free(buf, payload_output_max); return (DCMD_OK); }
/* * dcmd ::cred - display a credential (cred_t) */ int cmd_cred(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { credgrp_t cr_grps; cred_t *cr; mdb_arg_t cmdarg; uint_t opts = FALSE; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, OPT_VERBOSE, &opts, NULL) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { return (DCMD_USAGE); } cr = mdb_alloc(sizeof (*cr), UM_SLEEP | UM_GC); if (mdb_vread(cr, sizeof (*cr), addr) == -1) { mdb_warn("error reading cred_t at %p", addr); return (DCMD_ERR); } if (cr->cr_grps == NULL) { bzero(&cr_grps, sizeof (cr_grps)); } else { if (mdb_vread(&cr_grps, sizeof (cr_grps), (uintptr_t)cr->cr_grps) == -1) { mdb_warn("error reading credgrp_t at %p", cr->cr_grps); return (DCMD_ERR); } } if (opts & OPT_VERBOSE) { cmdarg.a_type = MDB_TYPE_STRING; cmdarg.a_un.a_str = "cred_t"; (void) mdb_call_dcmd("print", addr, flags, 1, &cmdarg); cmdarg.a_un.a_str = "-v"; mdb_printf("%<u>cr_grps:%</u>\n"); mdb_inc_indent(4); if (cr->cr_grps == NULL) { mdb_printf("(null)\n"); } else { (void) mdb_call_dcmd("credgrp", (uintptr_t)cr->cr_grps, flags, 1, &cmdarg); } mdb_dec_indent(4); mdb_printf("%<u>cr_ksid:%</u>\n"); mdb_inc_indent(4); if (cr->cr_ksid == NULL) { mdb_printf("(null)\n"); } else { (void) mdb_call_dcmd("credsid", (uintptr_t)cr->cr_ksid, flags, 1, &cmdarg); } mdb_dec_indent(4); return (DCMD_OK); } if (DCMD_HDRSPEC(flags)) mdb_printf("%<u>%?s %8s %8s %8s %8s% %8s%</u>\n", "ADDR", "UID", "GID", "RUID", "RGID", "#GRP(+SIDS)"); mdb_printf("%0?p %8u %8u %8u %8u %4u%s\n", addr, cr->cr_uid, cr->cr_gid, cr->cr_ruid, cr->cr_rgid, cr_grps.crg_ngroups, (cr->cr_ksid == NULL) ? "" : "+"); return (DCMD_OK); }