/* * dcmd ::ksidlist - display a ksidlist_t */ int cmd_ksidlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { ksidlist_t ksl; ksid_t ks; uint_t i, opts = FALSE; int rv = DCMD_OK; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, OPT_VERBOSE, &opts, NULL) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { return (DCMD_USAGE); } if (mdb_vread(&ksl, sizeof (ksl), addr) == -1) { mdb_warn("error reading ksidlist_t at %p", addr); return (DCMD_ERR); } if (opts & OPT_VERBOSE) { mdb_printf("ksl_ref = 0x%x\n", ksl.ksl_ref); mdb_printf("ksl_nsid = 0x%x\n", ksl.ksl_nsid); mdb_printf("ksl_neid = 0x%x\n", ksl.ksl_neid); } mdb_printf("ksl_sids = [\n"); addr += OFFSETOF(ksidlist_t, ksl_sids); mdb_inc_indent(4); for (i = 0; i < ksl.ksl_nsid; i++, addr += sizeof (ksid_t)) { if (mdb_vread(&ks, sizeof (ks), addr) == -1) { mdb_warn("error reading ksid_t at %p", addr); rv = DCMD_ERR; break; } print_ksid(&ks); } mdb_dec_indent(4); mdb_printf("]\n"); return (rv); }
/* ARGSUSED */ static int sv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { clock_t clock; int maj, min, mic, baseline, i; if (argc != 0) return (DCMD_USAGE); if (mdb_readvar(&maj, "sv_major_rev") == -1) { mdb_warn("unable to read 'sv_major_rev'"); return (DCMD_ERR); } if (mdb_readvar(&min, "sv_minor_rev") == -1) { mdb_warn("unable to read 'sv_minor_rev'"); return (DCMD_ERR); } if (mdb_readvar(&mic, "sv_micro_rev") == -1) { mdb_warn("unable to read 'sv_micro_rev'"); return (DCMD_ERR); } if (mdb_readvar(&baseline, "sv_baseline_rev") == -1) { mdb_warn("unable to read 'sv_baseline_rev'"); return (DCMD_ERR); } mdb_printf("SV module version: kernel %d.%d.%d.%d; mdb %d.%d.%d.%d\n", maj, min, mic, baseline, ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); mdb_inc_indent(4); sv_get_print(sv_config_time, "last config time", "0x%lx", clock); sv_get_print(sv_stats_on, "stats on", "%d", i); sv_get_print(sv_debug, "debug", "%d", i); sv_get_print(sv_max_devices, "max sv devices", "%d", i); mdb_dec_indent(4); return (DCMD_OK); }
/* * dcmd ::credgrp - display cred_t groups */ int cmd_credgrp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { credgrp_t grps; gid_t gid; uint_t i, opts = FALSE; int rv = DCMD_OK; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, OPT_VERBOSE, &opts, NULL) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { return (DCMD_USAGE); } if (mdb_vread(&grps, sizeof (grps), addr) == -1) { mdb_warn("error reading credgrp_t at %p", addr); return (DCMD_ERR); } if (opts & OPT_VERBOSE) { mdb_printf("crg_ref = 0x%x\n", grps.crg_ref); mdb_printf("crg_ngroups = 0x%x\n", grps.crg_ngroups); } mdb_printf("crg_groups = [\n"); addr += OFFSETOF(credgrp_t, crg_groups); mdb_inc_indent(4); for (i = 0; i < grps.crg_ngroups; i++, addr += sizeof (gid_t)) { if (mdb_vread(&gid, sizeof (gid), addr) == -1) { mdb_warn("error reading gid_t at %p", addr); rv = DCMD_ERR; break; } mdb_printf("\t%u,", gid); } mdb_dec_indent(4); mdb_printf("\n]\n"); return (rv); }
/*ARGSUSED*/ static int ii_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { ii_fd_t fd; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_vread(&fd, sizeof (fd), addr) != sizeof (fd)) { mdb_warn("failed to read ii_fd_t at 0x%p", addr); return (DCMD_ERR); } mdb_inc_indent(4); mdb_printf("ii_info: 0x%p ii_bmp: %d ii_shd: %d ii_ovr: %d ii_optr: " "0x%p\nii_oflags: 0x%x\n", fd.ii_info, fd.ii_bmp, fd.ii_shd, fd.ii_ovr, fd.ii_optr, fd.ii_oflags); mdb_dec_indent(4); return (DCMD_OK); }
/* ARGSUSED */ static int ii(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int maj, min, mic, baseline, i; if (argc != 0) return (DCMD_USAGE); if (mdb_readvar(&maj, "dsw_major_rev") == -1) { mdb_warn("unable to read 'dsw_major_rev'"); return (DCMD_ERR); } if (mdb_readvar(&min, "dsw_minor_rev") == -1) { mdb_warn("unable to read 'dsw_minor_rev'"); return (DCMD_ERR); } if (mdb_readvar(&mic, "dsw_micro_rev") == -1) { mdb_warn("unable to read 'dsw_micro_rev'"); return (DCMD_ERR); } if (mdb_readvar(&baseline, "dsw_baseline_rev") == -1) { mdb_warn("unable to read 'dsw_baseline_rev'"); return (DCMD_ERR); } mdb_printf("Point-in-Time Copy module version: kernel %d.%d.%d.%d; " "mdb %d.%d.%d.%d\n", maj, min, mic, baseline, ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); mdb_inc_indent(4); ii_get_print(ii_debug, "debug", "%d", i); ii_get_print(ii_bitmap, "bitmaps", "%d", i); mdb_dec_indent(4); return (DCMD_OK); }
static int fmd_xprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t opt_s = FALSE, opt_l = FALSE, opt_r = FALSE, opt_u = FALSE; fmd_xprt_impl_t xi; if (mdb_getopts(argc, argv, 'l', MDB_OPT_SETBITS, TRUE, &opt_l, 'r', MDB_OPT_SETBITS, TRUE, &opt_r, 's', MDB_OPT_SETBITS, TRUE, &opt_s, 'u', MDB_OPT_SETBITS, TRUE, &opt_u, NULL) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk_dcmd("fmd_xprt", "fmd_xprt", argc, argv) != 0) { mdb_warn("failed to walk fmd_xprt"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) { mdb_warn("failed to read fmd_xprt at %p", addr); return (DCMD_ERR); } if (DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%-8s %-4s %-4s %-5s %s%</u>\n", "ADDR", "ID", "VERS", "FLAGS", "STATE"); } mdb_printf("%-8p %-4d %-4u %-5x %a\n", addr, xi.xi_id, xi.xi_version, xi.xi_flags, xi.xi_state); if (opt_l | opt_s) { (void) mdb_inc_indent(4); mdb_printf("Local subscriptions requested by peer:\n"); mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS"); (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi, addr + OFFSETOF(fmd_xprt_impl_t, xi_lsub)); (void) mdb_dec_indent(4); } if (opt_r | opt_s) { (void) mdb_inc_indent(4); mdb_printf("Remote subscriptions requested of peer:\n"); mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS"); (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi, addr + OFFSETOF(fmd_xprt_impl_t, xi_rsub)); (void) mdb_dec_indent(4); } if (opt_u | opt_s) { (void) mdb_inc_indent(4); mdb_printf("Pending unsubscription acknowledgements:\n"); mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS"); (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi, addr + OFFSETOF(fmd_xprt_impl_t, xi_usub)); (void) mdb_dec_indent(4); } return (DCMD_OK); }
int zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { zone_t zn; char name[ZONE_NAMELEN]; char path[ZONE_PATHLEN]; int len; uint_t vopt_given; uint_t ropt_given; if (argc > 2) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk_dcmd("zone", "zone", argc, argv) == -1) { mdb_warn("can't walk zones"); return (DCMD_ERR); } return (DCMD_OK); } /* * Get the optional -r (reference counts) and -v (verbose output) * arguments. */ vopt_given = FALSE; ropt_given = FALSE; if (argc > 0 && mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &vopt_given, 'r', MDB_OPT_SETBITS, TRUE, &ropt_given, NULL) != argc) return (DCMD_USAGE); /* * -v can only be specified with -r. */ if (vopt_given == TRUE && ropt_given == FALSE) return (DCMD_USAGE); /* * Print a table header, if necessary. */ if (DCMD_HDRSPEC(flags)) { if (ropt_given == FALSE) mdb_printf("%<u>%?s %6s %-13s %-20s %-s%</u>\n", "ADDR", "ID", "STATUS", "NAME", "PATH"); else mdb_printf("%<u>%?s %6s %10s %10s %-20s%</u>\n", "ADDR", "ID", "REFS", "CREFS", "NAME"); } /* * Read the zone_t structure at the given address and read its name. */ if (mdb_vread(&zn, sizeof (zone_t), addr) == -1) { mdb_warn("can't read zone_t structure at %p", addr); return (DCMD_ERR); } len = mdb_readstr(name, ZONE_NAMELEN, (uintptr_t)zn.zone_name); if (len > 0) { if (len == ZONE_NAMELEN) (void) strcpy(&name[len - 4], "..."); } else { (void) strcpy(name, "??"); } if (ropt_given == FALSE) { char *statusp; /* * Default display * Fetch the zone's path and print the results. */ len = mdb_readstr(path, ZONE_PATHLEN, (uintptr_t)zn.zone_rootpath); if (len > 0) { if (len == ZONE_PATHLEN) (void) strcpy(&path[len - 4], "..."); } else { (void) strcpy(path, "??"); } if (zn.zone_status >= ZONE_IS_UNINITIALIZED && zn.zone_status <= ZONE_IS_DEAD) statusp = zone_status_names[zn.zone_status]; else statusp = "???"; mdb_printf("%0?p %6d %-13s %-20s %s\n", addr, zn.zone_id, statusp, name, path); } else { /* * Display the zone's reference counts. * Display the zone's subsystem-specific reference counts if * the user specified the '-v' option. */ mdb_printf("%0?p %6d %10u %10u %-20s\n", addr, zn.zone_id, zn.zone_ref, zn.zone_cred_ref, name); if (vopt_given == TRUE) { GElf_Sym subsys_names_sym; uintptr_t **zone_ref_subsys_names; uint_t num_subsys; uint_t n; /* * Read zone_ref_subsys_names from the kernel image. */ if (mdb_lookup_by_name("zone_ref_subsys_names", &subsys_names_sym) != 0) { mdb_warn("can't find zone_ref_subsys_names"); return (DCMD_ERR); } if (subsys_names_sym.st_size != ZONE_REF_NUM_SUBSYS * sizeof (char *)) { mdb_warn("number of subsystems in target " "differs from what mdb expects (mismatched" " kernel versions?)"); if (subsys_names_sym.st_size < ZONE_REF_NUM_SUBSYS * sizeof (char *)) num_subsys = subsys_names_sym.st_size / sizeof (char *); else num_subsys = ZONE_REF_NUM_SUBSYS; } else { num_subsys = ZONE_REF_NUM_SUBSYS; } if ((zone_ref_subsys_names = mdb_alloc( subsys_names_sym.st_size, UM_GC)) == NULL) { mdb_warn("out of memory"); return (DCMD_ERR); } if (mdb_readvar(zone_ref_subsys_names, "zone_ref_subsys_names") == -1) { mdb_warn("can't find zone_ref_subsys_names"); return (DCMD_ERR); } /* * Display each subsystem's reference count if it's * nonzero. */ mdb_inc_indent(7); for (n = 0; n < num_subsys; ++n) { char subsys_name[16]; /* * Skip subsystems lacking outstanding * references. */ if (zn.zone_subsys_ref[n] == 0) continue; /* * Each subsystem's name must be read from * the target's image. */ if (mdb_readstr(subsys_name, sizeof (subsys_name), (uintptr_t)zone_ref_subsys_names[n]) == -1) { mdb_warn("unable to read subsystem name" " from zone_ref_subsys_names[%u]", n); return (DCMD_ERR); } mdb_printf("%15s: %10u\n", subsys_name, zn.zone_subsys_ref[n]); } mdb_dec_indent(7); } } return (DCMD_OK); }
int zsd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { zone_t zone; const mdb_arg_t *argp; int argcindex; struct zsd_cb_data cbd; char name[ZONE_NAMELEN]; int len; /* * Walk all zones if necessary. */ if (argc > 2) return (DCMD_USAGE); if ((flags & DCMD_ADDRSPEC) == 0) { if (mdb_walk_dcmd("zone", "zsd", argc, argv) == -1) { mdb_warn("failed to walk zone\n"); return (DCMD_ERR); } return (DCMD_OK); } /* * Make sure a zone_t can be read from the specified address. */ if (mdb_vread(&zone, sizeof (zone), addr) == -1) { mdb_warn("couldn't read zone_t at %p", (void *)addr); return (DCMD_ERR); } /* * Get the optional arguments (key or -v or both). Note that * mdb_getopts() will not parse a key argument because it is not * preceded by an option letter. We'll get around this by requiring * that all options precede the optional key argument. */ cbd.keygiven = FALSE; cbd.voptgiven = FALSE; if (argc > 0 && (argcindex = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &cbd.voptgiven, NULL)) != argc) { /* * No options may appear after the key. */ if (argcindex != argc - 1) return (DCMD_USAGE); /* * The missed argument should be a key. */ argp = &argv[argcindex]; if (argp->a_type == MDB_TYPE_IMMEDIATE) cbd.key = argp->a_un.a_val; else cbd.key = mdb_strtoull(argp->a_un.a_str); cbd.keygiven = TRUE; cbd.found = FALSE; } /* * Prepare to output the specified zone's ZSD information. */ if (DCMD_HDRSPEC(flags)) mdb_printf("%<u>%-20s %?s %?s %8s%</u>\n", "ZONE", "KEY", "VALUE", "FLAGS"); len = mdb_readstr(name, ZONE_NAMELEN, (uintptr_t)zone.zone_name); if (len > 0) { if (len == ZONE_NAMELEN) (void) strcpy(&name[len - 4], "..."); } else { (void) strcpy(name, "??"); } mdb_printf("%-20s ", name); /* * Display the requested ZSD entries. */ mdb_inc_indent(21); if (mdb_pwalk("zsd", zsd_print, &cbd, addr) != 0) { mdb_warn("failed to walk zsd\n"); mdb_dec_indent(21); return (DCMD_ERR); } if (cbd.keygiven == TRUE && cbd.found == FALSE) { mdb_printf("no corresponding ZSD entry found\n"); mdb_dec_indent(21); return (DCMD_ERR); } mdb_dec_indent(21); return (DCMD_OK); }
/*ARGSUSED*/ int nvpair_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { nvpair_t nvpair_tmp, *nvpair; int32_t i, size, nelem, elem_size = 0; char *data = NULL, *data_end = NULL; char *type_name = NULL; data_type_t type = DATA_TYPE_UNKNOWN; int quiet = FALSE; int recurse = FALSE; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'r', MDB_OPT_SETBITS, TRUE, &recurse, 'q', MDB_OPT_SETBITS, TRUE, &quiet, NULL) != argc) return (DCMD_USAGE); /* read in the nvpair header so we can get the size */ if (mdb_vread(&nvpair_tmp, sizeof (nvpair), addr) == -1) { mdb_warn("failed to read nvpair at %p", addr); return (DCMD_ERR); } size = NVP_SIZE(&nvpair_tmp); if (size == 0) { mdb_warn("nvpair of size zero at %p", addr); return (DCMD_OK); } /* read in the entire nvpair */ nvpair = mdb_alloc(size, UM_SLEEP | UM_GC); if (mdb_vread(nvpair, size, addr) == -1) { mdb_warn("failed to read nvpair and data at %p", addr); return (DCMD_ERR); } /* lookup type decoding information for this nvpair */ type = NVP_TYPE(nvpair); nelem = NVP_NELEM(nvpair); for (i = 0; i < NELEM(nvpair_info); i++) { if (nvpair_info[i].type == type) { elem_size = nvpair_info[i].elem_size; type_name = nvpair_info[i].type_name; break; } } if (quiet) { mdb_printf("%s", NVP_NAME(nvpair)); } else { /* print out the first line of nvpair info */ mdb_printf("name='%s'", NVP_NAME(nvpair)); if (type_name != NULL) { mdb_printf(" type=%s", type_name); } else { /* * If the nvpair type is unknown we print the type * number */ mdb_printf(" type=0x%x", type); } mdb_printf(" items=%d\n", nelem); } /* if there is no data and the type is known then we're done */ if ((nelem == 0) && (type_name != NULL)) { if (quiet) mdb_printf("(unknown)\n"); return (DCMD_OK); } /* get pointers to the data to print out */ data = (char *)NVP_VALUE(nvpair); data_end = (char *)nvpair + NVP_SIZE(nvpair); /* * The value of the name-value pair for a single embedded * list is the nvlist_t structure for the embedded list. * So we print that address out (computed as an offset from * the nvpair address we received as addr). * * The value of the name-value pair for an array of embedded * lists is nelem pointers to nvlist_t structures followed * by the structures themselves. We display the list * of pointers as the pair's value. */ if (type == DATA_TYPE_NVLIST) { char *p = (char *)addr + (data - (char *)nvpair); if (recurse) { if (quiet) mdb_printf("\n"); mdb_inc_indent(NVPAIR_VALUE_INDENT); if (mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv, (uintptr_t)p) != DCMD_OK) return (DCMD_ERR); mdb_dec_indent(NVPAIR_VALUE_INDENT); } else { if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value", p); } mdb_printf("=%p\n", p); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); } return (DCMD_OK); } else if (type == DATA_TYPE_NVLIST_ARRAY) { if (recurse) { for (i = 0; i < nelem; i++, data += sizeof (nvlist_t *)) { nvlist_t **nl = (nvlist_t **)(void *)data; if (quiet && i != 0) mdb_printf("%s", NVP_NAME(nvpair)); mdb_printf("[%d]\n", i); mdb_inc_indent(NVPAIR_VALUE_INDENT); if (mdb_pwalk_dcmd("nvpair", "nvpair", argc, argv, (uintptr_t)*nl) != DCMD_OK) return (DCMD_ERR); mdb_dec_indent(NVPAIR_VALUE_INDENT); } } else { if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value"); } mdb_printf("="); for (i = 0; i < nelem; i++, data += sizeof (nvlist_t *)) { nvlist_t **nl = (nvlist_t **)(void *)data; mdb_printf("%c%p", " "[i == 0], *nl); } mdb_printf("\n"); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); } return (DCMD_OK); } /* if it's a string array, skip the index pointers */ if (type == DATA_TYPE_STRING_ARRAY) data += (sizeof (int64_t) * nelem); /* if the type is unknown, treat the data as a byte array */ if (type_name == NULL) { elem_size = 1; nelem = data_end - data; } /* * if the type is of strings, make sure they are printable * otherwise print them out as byte arrays */ if (elem_size == 0) { int32_t count = 0; i = 0; while ((&data[i] < data_end) && (count < nelem)) { if (data[i] == '\0') count++; else if (!isprint(data[i])) break; i++; } if (count != nelem) { /* there is unprintable data, output as byte array */ elem_size = 1; nelem = data_end - data; } } if (!quiet) { mdb_inc_indent(NVPAIR_VALUE_INDENT); mdb_printf("value="); } else { mdb_printf("="); } nvpair_print_value(data, elem_size, nelem, type); if (!quiet) mdb_dec_indent(NVPAIR_VALUE_INDENT); return (DCMD_OK); }
int cycinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { cyc_cpu_t cpu; cpu_t c; cyc_index_t root, i, *heap; size_t hsize; cyclic_t *cyc; uintptr_t caddr; uint_t verbose = FALSE, Verbose = FALSE; int header = 0; cyc_level_t lev; if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk_dcmd("cyccpu", "cycinfo", argc, argv) == -1) { mdb_warn("can't walk 'cyccpu'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 'V', MDB_OPT_SETBITS, TRUE, &Verbose, NULL) != argc) return (DCMD_USAGE); if (!DCMD_HDRSPEC(flags) && (verbose || Verbose)) mdb_printf("\n\n"); if (DCMD_HDRSPEC(flags) || verbose || Verbose) mdb_printf("%3s %*s %7s %6s %*s %15s %s\n", "CPU", CYC_ADDR_WIDTH, "CYC_CPU", "STATE", "NELEMS", CYC_ADDR_WIDTH, "ROOT", "FIRE", "HANDLER"); if (mdb_vread(&cpu, sizeof (cpu), addr) == -1) { mdb_warn("couldn't read cyc_cpu at %p", addr); return (DCMD_ERR); } if (mdb_vread(&c, sizeof (c), (uintptr_t)cpu.cyp_cpu) == -1) { mdb_warn("couldn't read cpu at %p", cpu.cyp_cpu); return (DCMD_ERR); } cyc = mdb_alloc(sizeof (cyclic_t) * cpu.cyp_size, UM_SLEEP | UM_GC); caddr = (uintptr_t)cpu.cyp_cyclics; if (mdb_vread(cyc, sizeof (cyclic_t) * cpu.cyp_size, caddr) == -1) { mdb_warn("couldn't read cyclic at %p", caddr); return (DCMD_ERR); } hsize = sizeof (cyc_index_t) * cpu.cyp_size; heap = mdb_alloc(hsize, UM_SLEEP | UM_GC); if (mdb_vread(heap, hsize, (uintptr_t)cpu.cyp_heap) == -1) { mdb_warn("couldn't read heap at %p", cpu.cyp_heap); return (DCMD_ERR); } root = heap[0]; mdb_printf("%3d %0*p %7s %6d ", c.cpu_id, CYC_ADDR_WIDTH, addr, cpu.cyp_state == CYS_ONLINE ? "online" : cpu.cyp_state == CYS_OFFLINE ? "offline" : cpu.cyp_state == CYS_EXPANDING ? "expand" : cpu.cyp_state == CYS_REMOVING ? "remove" : cpu.cyp_state == CYS_SUSPENDED ? "suspend" : "????", cpu.cyp_nelems); if (cpu.cyp_nelems > 0) mdb_printf("%0*p %15llx %a\n", CYC_ADDR_WIDTH, caddr, cyc[root].cy_expire, cyc[root].cy_handler); else mdb_printf("%*s %15s %s\n", CYC_ADDR_WIDTH, "-", "-", "-"); if (!verbose && !Verbose) return (DCMD_OK); mdb_printf("\n"); cyclic_pretty_dump(&cpu); mdb_inc_indent(2); for (i = 0; i < cpu.cyp_size; i++) { int j; for (j = 0; j < cpu.cyp_size; j++) { if (heap[j] == i) break; } if (!Verbose && j >= cpu.cyp_nelems) continue; if (!header) { header = 1; mdb_printf("\n%*s %3s %4s %4s %5s %15s %7s %s\n", CYC_ADDR_WIDTH, "ADDR", "NDX", "HEAP", "LEVL", "PEND", "FIRE", "USECINT", "HANDLER"); } mdb_printf("%0*p %3d ", CYC_ADDR_WIDTH, caddr + i * sizeof (cyclic_t), i); mdb_printf("%4d ", j); if (j >= cpu.cyp_nelems) { mdb_printf("%4s %5s %15s %7s %s\n", "-", "-", "-", "-", "-"); continue; } mdb_printf("%4s %5d %15llx ", cyc[i].cy_level == CY_HIGH_LEVEL ? "high" : cyc[i].cy_level == CY_LOCK_LEVEL ? "lock" : cyc[i].cy_level == CY_LOW_LEVEL ? "low" : "????", cyc[i].cy_pend, cyc[i].cy_expire); if (cyc[i].cy_interval + cyc[i].cy_expire != INT64_MAX) mdb_printf("%7lld ", cyc[i].cy_interval / (uint64_t)(NANOSEC / MICROSEC)); else mdb_printf("%7s ", "-"); mdb_printf("%a\n", cyc[i].cy_handler); } if (!Verbose) goto out; for (lev = CY_LOW_LEVEL; lev < CY_LOW_LEVEL + CY_SOFT_LEVELS; lev++) { cyc_softbuf_t *softbuf = &cpu.cyp_softbuf[lev]; char which = softbuf->cys_hard, shared = 1; cyc_pcbuffer_t *pc; size_t bufsiz; cyc_index_t *buf; if (softbuf->cys_hard != softbuf->cys_soft) shared = 0; again: pc = &softbuf->cys_buf[which]; bufsiz = (pc->cypc_sizemask + 1) * sizeof (cyc_index_t); buf = mdb_alloc(bufsiz, UM_SLEEP | UM_GC); if (mdb_vread(buf, bufsiz, (uintptr_t)pc->cypc_buf) == -1) { mdb_warn("couldn't read cypc_buf at %p", pc->cypc_buf); continue; } mdb_printf("\n%3s %4s %4s %4s %*s %4s %*s\n", "CPU", "LEVL", "USER", "NDX", CYC_ADDR_WIDTH, "ADDR", "CYC", CYC_ADDR_WIDTH, "CYC_ADDR", "PEND"); for (i = 0; i <= pc->cypc_sizemask && i <= pc->cypc_prodndx; i++) { uintptr_t cyc_addr = caddr + buf[i] * sizeof (cyclic_t); mdb_printf("%3d %4s %4s ", c.cpu_id, lev == CY_HIGH_LEVEL ? "high" : lev == CY_LOCK_LEVEL ? "lock" : lev == CY_LOW_LEVEL ? "low" : "????", shared ? "shrd" : which == softbuf->cys_hard ? "hard" : "soft"); mdb_printf("%4d %0*p ", i, CYC_ADDR_WIDTH, (uintptr_t)&buf[i] - (uintptr_t)&buf[0] + (uintptr_t)pc->cypc_buf, buf[i], caddr + buf[i] * sizeof (cyclic_t)); if (i >= pc->cypc_prodndx) mdb_printf("%4s %*s %5s ", "-", CYC_ADDR_WIDTH, "-", "-"); else { cyclic_t c; if (mdb_vread(&c, sizeof (c), cyc_addr) == -1) { mdb_warn("\ncouldn't read cyclic at " "%p", cyc_addr); continue; } mdb_printf("%4d %0*p %5d ", buf[i], CYC_ADDR_WIDTH, cyc_addr, c.cy_pend); } if (i == (pc->cypc_consndx & pc->cypc_sizemask)) { mdb_printf("<-- consndx"); if (i == (pc->cypc_prodndx & pc->cypc_sizemask)) mdb_printf(",prodndx"); mdb_printf("\n"); continue; } if (i == (pc->cypc_prodndx & pc->cypc_sizemask)) { mdb_printf("<-- prodndx\n"); continue; } mdb_printf("\n"); if (i >= pc->cypc_prodndx) break; } if (!shared && which == softbuf->cys_hard) { which = softbuf->cys_soft; goto again; } } out: mdb_dec_indent(2); return (DCMD_OK); }
static int dof_sect_provider(dof_hdr_t *dofh, uintptr_t addr, dof_sec_t *sec, dof_sec_t *dofs) { dof_provider_t pv; dof_probe_t *pb; char *strtab, *p; uint32_t *offs, *enoffs; uint8_t *args = NULL; size_t sz; int i, j; dof_stridx_t narg, xarg; sz = MIN(sec->dofs_size, sizeof (dof_provider_t)); if (mdb_vread(&pv, sz, addr + sec->dofs_offset) != sz) { mdb_warn("failed to read DOF provider"); return (-1); } sz = dofs[pv.dofpv_strtab].dofs_size; strtab = mdb_alloc(sz, UM_SLEEP | UM_GC); if (mdb_vread(strtab, sz, addr + dofs[pv.dofpv_strtab].dofs_offset) != sz) { mdb_warn("failed to read string table"); return (-1); } mdb_printf("%lx provider %s {\n", (ulong_t)(addr + sec->dofs_offset), strtab + pv.dofpv_name); sz = dofs[pv.dofpv_prargs].dofs_size; if (sz != 0) { args = mdb_alloc(sz, UM_SLEEP | UM_GC); if (mdb_vread(args, sz, addr + dofs[pv.dofpv_prargs].dofs_offset) != sz) { mdb_warn("failed to read args"); return (-1); } } sz = dofs[pv.dofpv_proffs].dofs_size; offs = mdb_alloc(sz, UM_SLEEP | UM_GC); if (mdb_vread(offs, sz, addr + dofs[pv.dofpv_proffs].dofs_offset) != sz) { mdb_warn("failed to read offsets"); return (-1); } enoffs = NULL; if (dofh->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 || pv.dofpv_prenoffs == 0) { sz = dofs[pv.dofpv_prenoffs].dofs_size; enoffs = mdb_alloc(sz, UM_SLEEP | UM_GC); if (mdb_vread(enoffs, sz, addr + dofs[pv.dofpv_prenoffs].dofs_offset) != sz) { mdb_warn("failed to read is-enabled offsets"); return (-1); } } sz = dofs[pv.dofpv_probes].dofs_size; p = mdb_alloc(sz, UM_SLEEP | UM_GC); if (mdb_vread(p, sz, addr + dofs[pv.dofpv_probes].dofs_offset) != sz) { mdb_warn("failed to read probes"); return (-1); } (void) mdb_inc_indent(2); for (i = 0; i < sz / dofs[pv.dofpv_probes].dofs_entsize; i++) { pb = (dof_probe_t *)(uintptr_t)(p + i * dofs[pv.dofpv_probes].dofs_entsize); mdb_printf("%lx probe %s:%s {\n", (ulong_t)(addr + dofs[pv.dofpv_probes].dofs_offset + i * dofs[pv.dofpv_probes].dofs_entsize), strtab + pb->dofpr_func, strtab + pb->dofpr_name); (void) mdb_inc_indent(2); mdb_printf("addr: %p\n", (ulong_t)pb->dofpr_addr); mdb_printf("offs: "); for (j = 0; j < pb->dofpr_noffs; j++) { mdb_printf("%s %x", "," + (j == 0), offs[pb->dofpr_offidx + j]); } mdb_printf("\n"); if (dofh->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1) { mdb_printf("enoffs: "); if (enoffs == NULL) { if (pb->dofpr_nenoffs != 0) mdb_printf("<error>"); } else { for (j = 0; j < pb->dofpr_nenoffs; j++) { mdb_printf("%s %x", "," + (j == 0), enoffs[pb->dofpr_enoffidx + j]); } } mdb_printf("\n"); } mdb_printf("nargs:"); narg = pb->dofpr_nargv; for (j = 0; j < pb->dofpr_nargc; j++) { mdb_printf("%s %s", "," + (j == 0), strtab + narg); narg += strlen(strtab + narg) + 1; } mdb_printf("\n"); mdb_printf("xargs:"); xarg = pb->dofpr_xargv; for (j = 0; j < pb->dofpr_xargc; j++) { mdb_printf("%s %s", "," + (j == 0), strtab + xarg); xarg += strlen(strtab + xarg) + 1; } mdb_printf("\n"); mdb_printf("map: "); for (j = 0; j < pb->dofpr_xargc; j++) { mdb_printf("%s %d->%d", "," + (j == 0), args[pb->dofpr_argidx + j], j); } (void) mdb_dec_indent(2); mdb_printf("\n}\n"); } (void) mdb_dec_indent(2); mdb_printf("}\n"); return (0); }
/* * 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); }
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); }