Example #1
0
int
sysevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	uint_t sys_flags = FALSE;

	if (mdb_getopts(argc, argv,
	    's', MDB_OPT_SETBITS, SYSEVENT_SENTQ, &sys_flags,
	    'v', MDB_OPT_SETBITS, SYSEVENT_VERBOSE, &sys_flags, NULL) != argc)
		return (DCMD_USAGE);

	if ((flags & DCMD_ADDRSPEC) == 0) {
		if (sys_flags & SYSEVENT_SENTQ) {
			if (mdb_walk_dcmd("sysevent_sent", "sysevent", argc,
			    argv) == -1) {
				mdb_warn("can not walk sent queue");
				return (DCMD_ERR);
			}
		} else {
			if (mdb_walk_dcmd("sysevent_pend", "sysevent", argc,
			    argv) == -1) {
				mdb_warn("can not walk pending queue");
				return (DCMD_ERR);
			}
		}
		return (DCMD_OK);
	}

	return (sysevent_buf(addr, flags, sys_flags));
}
Example #2
0
static int
fmd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	fmd_thread_t thr;

	if (!(flags & DCMD_ADDRSPEC))
		return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc, argv));

	if (argc != 0)
		return (DCMD_USAGE);

	if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
		mdb_warn("failed to read fmd_thread at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n",
		    "ADDR", "MOD", "TID", "FUNC");
	}

	mdb_printf("%-11p %-11p %-8u %a\n",
	    addr, thr.thr_mod, thr.thr_tid, thr.thr_func);

	return (DCMD_OK);
}
Example #3
0
/*
 * Parse the arguments passed to the dcmd and print all or one flow_entry_t
 * structures
 */
static int
mac_flow_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	uint_t	args = 0;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("mac_flow", "mac_flow", argc, argv) == -1) {
			mdb_warn("failed to walk 'mac_flow'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}
	if ((mdb_getopts(argc, argv,
	    'a', MDB_OPT_SETBITS, MAC_FLOW_ATTR, &args,
	    'p', MDB_OPT_SETBITS, MAC_FLOW_PROP, &args,
	    'm', MDB_OPT_SETBITS, MAC_FLOW_MISC, &args,
	    'r', MDB_OPT_SETBITS, MAC_FLOW_RX, &args,
	    't', MDB_OPT_SETBITS, MAC_FLOW_TX, &args,
	    's', MDB_OPT_SETBITS, MAC_FLOW_STATS, &args,
	    'u', MDB_OPT_SETBITS, MAC_FLOW_USER, &args,
	    NULL) != argc)) {
		return (DCMD_USAGE);
	}
	if (argc > 2 || (argc == 2 && !(args & MAC_FLOW_USER)))
		return (DCMD_USAGE);
	/*
	 * If no arguments was specified or just "-u" was specified then
	 * we default to printing basic information of flows.
	 */
	if (args == 0 || args == MAC_FLOW_USER)
		args |= MAC_FLOW_NONE;

	return (mac_flow_dcmd_output(addr, flags, args));
}
Example #4
0
static int
fmd_module(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	fmd_module_t mod;
	char name[PATH_MAX];

	if (!(flags & DCMD_ADDRSPEC))
		return (mdb_walk_dcmd("fmd_module", "fmd_module", argc, argv));

	if (argc != 0)
		return (DCMD_USAGE);

	if (mdb_vread(&mod, sizeof (mod), addr) != sizeof (mod)) {
		mdb_warn("failed to read fmd_module at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n",
		    "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME");
	}

	if (mdb_readstr(name, sizeof (name), (uintptr_t)mod.mod_name) <= 0)
		(void) mdb_snprintf(name, sizeof (name), "<%p>", mod.mod_name);

	mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr,
	    mod.mod_ops, mod.mod_data, mod.mod_flags, mod.mod_ustat, name);

	return (DCMD_OK);
}
Example #5
0
/*ARGSUSED*/
static int
configd_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	int num_servers;
	int num_started;

	if (argc != 0)
		return (DCMD_USAGE);

	if (mdb_readvar(&num_servers, "num_servers") == -1) {
		mdb_warn("unable to read num_servers");
		return (DCMD_ERR);
	}
	if (mdb_readvar(&num_started, "num_started") == -1) {
		mdb_warn("unable to read num_started");
		return (DCMD_ERR);
	}
	mdb_printf(
	    "\nserver threads:\t%d running, %d starting\n\n", num_servers,
	    num_started - num_servers);

	if (mdb_walk_dcmd("configd_threads", "configd_thread", argc,
	    argv) == -1) {
		mdb_warn("can't walk 'configd_threads'");
		return (DCMD_ERR);
	}
	return (DCMD_OK);
}
Example #6
0
/*ARGSUSED*/
static int
uutil_listpool(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	uu_list_pool_t ulp;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("uu_list_pool", "uu_list_pool", argc,
		    argv) == -1) {
			mdb_warn("can't walk uu_list_pool");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (argc != 0)
		return (DCMD_USAGE);

	if (DCMD_HDRSPEC(flags))
		mdb_printf("%-?s %-30s %?s %5s\n",
		    "ADDR", "NAME", "COMPARE", "FLAGS");

	if (mdb_vread(&ulp, sizeof (uu_list_pool_t), addr) == -1) {
		mdb_warn("failed to read uu_list_pool\n");
		return (DCMD_ERR);
	}

	mdb_printf("%0?p %-30s %08x     %c\n", addr, ulp.ulp_name, ulp.ulp_cmp,
	    ulp.ulp_debug ? 'D' : ' ');

	return (DCMD_OK);
}
Example #7
0
int
swapinfof(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	struct swapinfo	si;
	char		*name;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("swapinfo", "swapinfo", argc, argv) == -1) {
			mdb_warn("can't walk swapinfo");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%?s %?s %9s %9s %s%</u>\n",
		    "ADDR", "VNODE", "PAGES", "FREE", "NAME");
	}

	if (mdb_vread(&si, sizeof (struct swapinfo), addr) == -1) {
		mdb_warn("can't read swapinfo at %#lx", addr);
		return (DCMD_ERR);
	}

	name = mdb_alloc(si.si_pnamelen, UM_SLEEP | UM_GC);
	if (mdb_vread(name, si.si_pnamelen, (uintptr_t)si.si_pname) == -1)
		name = "*error*";

	mdb_printf("%0?lx %?p %9d %9d %s\n",
	    addr, si.si_vp, si.si_npgs, si.si_nfpgs, name);

	return (DCMD_OK);
}
Example #8
0
int
page(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	page_t	p;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("page", "page", argc, argv) == -1) {
			mdb_warn("can't walk pages");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%?s %?s %16s %8s %3s %3s %2s %2s %2s%</u>\n",
		    "PAGE", "VNODE", "OFFSET", "SELOCK",
		    "LCT", "COW", "IO", "FS", "ST");
	}

	if (mdb_vread(&p, sizeof (page_t), addr) == -1) {
		mdb_warn("can't read page_t at %#lx", addr);
		return (DCMD_ERR);
	}

	mdb_printf("%0?lx %?p %16llx %8x %3d %3d %2x %2x %2x\n",
	    addr, p.p_vnode, p.p_offset, p.p_selock, p.p_lckcnt, p.p_cowcnt,
	    p.p_iolock_state, p.p_fsdata, p.p_state);

	return (DCMD_OK);
}
Example #9
0
static int
fmd_asru_link(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	char uuid[48], name[PATH_MAX];
	fmd_asru_link_t a;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("fmd_asru_link", "fmd_asru_link", argc,
		    argv) != 0) {
			mdb_warn("failed to walk fmd_asru_link hash");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
		mdb_warn("failed to read fmd_asru_link at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags))
		mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");

	if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.al_uuid) <= 0)
		(void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.al_uuid);
	if (mdb_readstr(name, sizeof (name), (uintptr_t)a.al_rsrc_name) <= 0)
		(void) mdb_snprintf(name, sizeof (name), "<%p>",
		    a.al_rsrc_name);

	mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
	return (DCMD_OK);
}
Example #10
0
static int
mac_group_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	uint_t		args = MAC_SRS_NONE;
	mac_group_t	mg;
	int		clients;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("mac_group", "mac_group", argc, argv) == -1) {
			mdb_warn("failed to walk 'mac_group'");
			return (DCMD_ERR);
		}

		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'r', MDB_OPT_SETBITS, MAC_GROUP_RX, &args,
	    't', MDB_OPT_SETBITS, MAC_GROUP_TX, &args,
	    'u', MDB_OPT_SETBITS, MAC_GROUP_UNINIT, &args,
	    NULL) != argc)
		return (DCMD_USAGE);

	if (mdb_vread(&mg, sizeof (mac_group_t), addr) == -1) {
		mdb_warn("failed to read mac_group_t at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags) && !(flags & DCMD_PIPE_OUT)) {
		mdb_printf("%<u>%-?s %-8s %-10s %6s %8s %-?s%</u>\n",
		    "ADDR", "TYPE", "STATE", "NRINGS", "NCLIENTS", "RINGS");
	}

	if ((args & MAC_GROUP_RX) != 0 && mg.mrg_type != MAC_RING_TYPE_RX)
		return (DCMD_OK);
	if ((args & MAC_GROUP_TX) != 0 && mg.mrg_type != MAC_RING_TYPE_TX)
		return (DCMD_OK);

	/*
	 * By default, don't show uninitialized groups. They're not very
	 * interesting. They have no rings and no clients.
	 */
	if (mg.mrg_state == MAC_GROUP_STATE_UNINIT &&
	    (args & MAC_GROUP_UNINIT) == 0)
		return (DCMD_OK);

	if (flags & DCMD_PIPE_OUT) {
		mdb_printf("%lr\n", addr);
		return (DCMD_OK);
	}

	clients = mac_group_count_clients(&mg);
	mdb_printf("%?p %-8s %-10s %6d %8d %?p\n", addr, mac_group_type(&mg),
	    mac_group_state(&mg), mg.mrg_cur_count, clients, mg.mrg_rings);

	return (DCMD_OK);
}
Example #11
0
static int
fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	char uuid[48], name[16];
	fmd_case_impl_t ci;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("fmd_case", "fmd_case", argc, argv) != 0) {
			mdb_warn("failed to walk fmd_case hash");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
		mdb_warn("failed to read fmd_case at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n",
		    "ADDR", "STATE", "REF", "DATA", "UUID");
	}

	if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)ci.ci_uuid) <= 0)
		(void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", ci.ci_uuid);

	switch (ci.ci_state) {
	case FMD_CASE_UNSOLVED:
		(void) strcpy(name, "UNSLV");
		break;
	case FMD_CASE_SOLVED:
		(void) strcpy(name, "SOLVE");
		break;
	case FMD_CASE_CLOSE_WAIT:
		(void) strcpy(name, "CWAIT");
		break;
	case FMD_CASE_CLOSED:
		(void) strcpy(name, "CLOSE");
		break;
	case FMD_CASE_REPAIRED:
		(void) strcpy(name, "RPAIR");
		break;
	case FMD_CASE_RESOLVED:
		(void) strcpy(name, "RSLVD");
		break;
	default:
		(void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state);
	}

	mdb_printf("%-11p %-5s %-3u %-?p %s\n",
	    addr, name, ci.ci_refs, ci.ci_data, uuid);

	return (DCMD_OK);
}
Example #12
0
int
rctl_dict(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	rctl_dict_entry_t dict;
	char name[256], *type = NULL;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("rctl_dict_list", "rctl_dict", argc,
		    argv) == -1) {
			mdb_warn("failed to walk 'rctl_dict_list'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (DCMD_HDRSPEC(flags))
		mdb_printf("%<u>%2s %-27s %?s %7s %s%</u>\n",
		    "ID", "NAME", "ADDR", "TYPE", "GLOBAL_FLAGS");

	if (mdb_vread(&dict, sizeof (dict), addr) == -1) {
		mdb_warn("failed to read rctl_dict at %p", addr);
		return (DCMD_ERR);
	}
	if (mdb_readstr(name, 256, (uintptr_t)(dict.rcd_name)) == -1) {
		mdb_warn("failed to read rctl_dict name for %p", addr);
		return (DCMD_ERR);
	}

	switch (dict.rcd_entity) {
	case RCENTITY_PROCESS:
		type = "process";
		break;
	case RCENTITY_TASK:
		type = "task";
		break;
	case RCENTITY_PROJECT:
		type = "project";
		break;
	case RCENTITY_ZONE:
		type = "zone";
		break;
	default:
		type = "unknown";
		break;
	}

	mdb_printf("%2d %-27s %0?p %7s 0x%08x", dict.rcd_id, name, addr,
	    type, dict.rcd_flagaction);

	return (DCMD_OK);
}
Example #13
0
/*ARGSUSED*/
int
cycid(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av)
{
	cyc_id_t id;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("cyclic_id_cache", "cycid", ac, av) == -1) {
			mdb_warn("can't walk cyclic_id_cache");
			return (DCMD_ERR);
		}

		return (DCMD_OK);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%?s %4s %3s %?s %s\n", "ADDR", "CPU", "NDX",
		    "CYCLIC", "HANDLER");
	}

	if (mdb_vread(&id, sizeof (id), addr) == -1) {
		mdb_warn("couldn't read cyc_id_t at %p", addr);
		return (DCMD_ERR);
	}

	if (id.cyi_cpu == NULL) {
		/*
		 * This is an omnipresent cyclic.
		 */
		mdb_printf("%?p %4s %3s %?s %a\n", addr, "omni", "-", "-",
		    id.cyi_omni_hdlr.cyo_online);
		mdb_printf("%?s    |\n", "");
		mdb_printf("%?s    +-->%4s %3s %?s %s\n", "",
		    "CPU", "NDX", "CYCLIC", "HANDLER");

		if (mdb_pwalk("cycomni",
		    (mdb_walk_cb_t)cycid_walk_omni, NULL, addr) == -1) {
			mdb_warn("couldn't walk cycomni for %p", addr);
			return (DCMD_ERR);
		}

		mdb_printf("\n");

		return (DCMD_OK);
	}

	mdb_printf("%?p ", addr);

	return (cycid_cpu(id.cyi_cpu, id.cyi_ndx));
}
Example #14
0
int
sysevent_channel(uintptr_t addr, uint_t flags, int argc,
    const mdb_arg_t *argv)
{
	ssize_t channel_name_sz;
	char channel_name[CHAN_FIELD_MAX];
	sysevent_channel_descriptor_t chan_tbl;

	if (argc != 0)
		return (DCMD_USAGE);

	if ((flags & DCMD_ADDRSPEC) == 0) {
		if (mdb_walk_dcmd("sysevent_channel", "sysevent_channel",
		    argc, argv) == -1) {
			mdb_warn("can't walk sysevent channel");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}


	if (DCMD_HDRSPEC(flags))
		mdb_printf("%<u>%-?s %-16s %-8s %-?s%</u>\n",
		    "ADDR", "NAME", "REF CNT", "CLASS LST ADDR");

	if (mdb_vread(&chan_tbl, sizeof (chan_tbl),
	    (uintptr_t)addr) == -1) {
		mdb_warn("failed to read channel table at %p", addr);
		return (DCMD_ERR);
	}
	if ((channel_name_sz = mdb_readstr(channel_name, CHAN_FIELD_MAX,
	    (uintptr_t)chan_tbl.scd_channel_name)) == -1) {
		mdb_warn("failed to read channel name at %p",
		    chan_tbl.scd_channel_name);
		return (DCMD_ERR);
	}
	if (channel_name_sz >= CHAN_FIELD_MAX - 1)
		(void) strcpy(&channel_name[CHAN_FIELD_MAX - 4], "...");

	mdb_printf("%-?p %-16s %-8lu %-?p\n",
	    addr, channel_name, chan_tbl.scd_ref_cnt,
	    addr + offsetof(sysevent_channel_descriptor_t,
	    scd_class_list_tbl));

	return (DCMD_OK);
}
Example #15
0
/* ARGSUSED */
int
metaset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	snarf_sets();

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("md_sets", "metaset", argc,
		    argv) == -1) {
			mdb_warn("failed to walk sets");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}
	print_set(addr);

	return (DCMD_OK);
}
Example #16
0
static int
fcip(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	fcip_port_info_t	pinfo;

	if (argc != 0) {
		return (DCMD_USAGE);
	}

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("fcip", "fcip",
		    argc, argv) == -1) {
			mdb_warn("failed to walk 'fcip_port_head'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (DCMD_HDRSPEC(flags))
		mdb_printf("%12s %12s %12s %16s %16s\n",
		    "FCIP Struct", "Handle", "DIP", "Port WWN", "Node WWN");

	/*
	 * For each port, we just need to read the fc_fca_port_t struct, read
	 * the port_handle
	 */
	if (mdb_vread(&pinfo, sizeof (fcip_port_info_t), addr) ==
	    sizeof (fcip_port_info_t)) {
		mdb_printf("%12p %12p %12p %02x%02x%02x%02x%02x%02x%02x%02x "
		    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
		    pinfo.fcipp_fcip, pinfo.fcipp_handle, pinfo.fcipp_dip,
		    pinfo.fcipp_pwwn.raw_wwn[0], pinfo.fcipp_pwwn.raw_wwn[1],
		    pinfo.fcipp_pwwn.raw_wwn[2], pinfo.fcipp_pwwn.raw_wwn[3],
		    pinfo.fcipp_pwwn.raw_wwn[4], pinfo.fcipp_pwwn.raw_wwn[5],
		    pinfo.fcipp_pwwn.raw_wwn[6], pinfo.fcipp_pwwn.raw_wwn[7],
		    pinfo.fcipp_nwwn.raw_wwn[0], pinfo.fcipp_nwwn.raw_wwn[1],
		    pinfo.fcipp_nwwn.raw_wwn[2], pinfo.fcipp_nwwn.raw_wwn[3],
		    pinfo.fcipp_nwwn.raw_wwn[4], pinfo.fcipp_nwwn.raw_wwn[5],
		    pinfo.fcipp_nwwn.raw_wwn[6], pinfo.fcipp_nwwn.raw_wwn[7]);

	} else
		mdb_warn("failed to read port info at %p", addr);

	return (DCMD_OK);
}
Example #17
0
/*ARGSUSED*/
static int
configd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	thread_info_t t;
	char state[20];
	char oldstate[20];

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("configd_threads", "configd_thread", argc,
		    argv) == -1) {
			mdb_warn("can't walk 'configd_threads'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (argc != 0)
		return (DCMD_USAGE);

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-?s %5s %-12s %-12s %-?s %-?s %-?s%</u>\n",
		    "ADDR", "TID", "STATE", "PREV_STATE", "CLIENT", "CLIENTRQ",
		    "MAINREQ");
	}

	if (mdb_vread(&t, sizeof (t), addr) == -1) {
		mdb_warn("failed to read thread_info_t at %p", addr);
		return (DCMD_ERR);
	}

	enum_lookup(state, sizeof (state), thread_state_enum,
	    t.ti_state, "TI_", "");
	make_lower(state, sizeof (state));

	enum_lookup(oldstate, sizeof (oldstate), thread_state_enum,
	    t.ti_prev_state, "TI_", "");
	make_lower(oldstate, sizeof (oldstate));

	mdb_printf("%0?p %5d %-12s %-12s %?p %?p %?p\n",
	    (void *)addr, t.ti_thread, state, oldstate,
	    t.ti_active_client, t.ti_client_request, t.ti_main_door_request);

	return (DCMD_OK);
}
Example #18
0
/*
 * Display a single sv_glcient_t structure.
 * If called with no address, performs a global walk of all sv_gclients.
 */
static int
sv_gclient(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	sv_gclient_t sg;
	char name[64];

	if (argc != 0)
		return (DCMD_USAGE);

	if (!(flags & DCMD_ADDRSPEC)) {
		/*
		 * paranoid mode on: qualify walker name with module name
		 * using '`' syntax.
		 */
		if (mdb_walk_dcmd("sv`sv_gclient",
		    "sv`sv_gclient", argc, argv) == -1) {
			mdb_warn("failed to walk 'sv_gclient'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) {
		mdb_warn("failed to read sv_gclient at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%-?s  %8T%-?s  %8T%-16s  %8T%s\n",
		    "ADDR", "NEXT", "ID", "NAME");
	}

	if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) == -1) {
		mdb_warn("failed to read sv_gclient name at %p", addr);
		return (DCMD_ERR);
	}

	mdb_printf("%p  %8T%p  %8T%llx  %8T%s",
	    addr, sg.sg_next, sg.sg_id, name);

	return (DCMD_OK);
}
Example #19
0
static int
mac_ring_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	mac_ring_t		ring;
	mac_group_t		group;
	flow_entry_t		flent;
	mac_soft_ring_set_t	srs;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("mac_ring", "mac_ring", argc, argv) == -1) {
			mdb_warn("failed to walk 'mac_ring'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}
	if (mdb_vread(&ring, sizeof (ring), addr) == -1) {
		mdb_warn("failed to read struct mac_ring_s at %p", addr);
		return (DCMD_ERR);
	}
	bzero(&flent, sizeof (flent));
	if (mdb_vread(&srs, sizeof (srs), (uintptr_t)ring.mr_srs) != -1) {
		(void) mdb_vread(&flent, sizeof (flent),
		    (uintptr_t)srs.srs_flent);
	}
	(void) mdb_vread(&group, sizeof (group), (uintptr_t)ring.mr_gh);
	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%?s %4s %5s %4s %?s "
		    "%5s %?s %?s %s %</u>\n",
		    "ADDR", "TYPE", "STATE", "FLAG", "GROUP",
		    "CLASS", "MIP", "SRS", "FLOW NAME");
	}
	mdb_printf("%?p %-4s "
	    "%5s %04x "
	    "%?p %-5s "
	    "%?p %?p %s\n",
	    addr, ((ring.mr_type == 1)? "RX" : "TX"),
	    mac_ring_state2str(ring.mr_state), ring.mr_flag,
	    ring.mr_gh, mac_ring_classify2str(ring.mr_classify_type),
	    group.mrg_mh, ring.mr_srs, flent.fe_flow_name);
	return (DCMD_OK);
}
Example #20
0
/*
 * speedmap()
 *    is used to print node information (speed map, node number, GUID, etc.)
 *    about the 1394 devices currently attached to the 1394 bus.
 */
static int
speedmap(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	s1394_hal_t	hal;
	int		ret;

	if (flags & DCMD_ADDRSPEC) {
		if (mdb_vread(&hal, sizeof (s1394_hal_t), addr) == -1) {
			mdb_warn("failed to read the HAL structure");
			return (DCMD_ERR);
		}

		ret = print_node_info(&hal);
		if (ret == DCMD_ERR)
		    return (DCMD_ERR);
	} else {
		(void) mdb_walk_dcmd("speedmap", "speedmap", argc, argv);
	}

	return (DCMD_OK);
}
Example #21
0
static int
fmd_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	char name[32], func[MDB_SYM_NAMLEN];
	fmd_timer_t t;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc, argv) != 0) {
			mdb_warn("failed to walk fmd_timerq");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
		mdb_warn("failed to read fmd_timer at %p", addr);
		return (DCMD_ERR);
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n",
		    "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC");
	}

	if (mdb_readstr(name, sizeof (name), (uintptr_t)
	    t.tmr_ids + OFFSETOF(fmd_idspace_t, ids_name)) <= 0)
		(void) mdb_snprintf(name, sizeof (name), "<%p>", t.tmr_ids);

	if (mdb_lookup_by_addr((uintptr_t)t.tmr_func, MDB_SYM_FUZZY,
	    func, sizeof (func), NULL) != 0)
		(void) mdb_snprintf(func, sizeof (func), "<%p>", t.tmr_func);

	mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n",
	    addr, name, t.tmr_id, t.tmr_hrt, t.tmr_arg, func);
	return (DCMD_OK);
}
Example #22
0
/*ARGSUSED*/
int
usba_device(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	int		status;
	char		pathname[MAXNAMELEN];
	char		dname[MODMAXNAMELEN + 1] = "<unatt>"; /* Driver name */
	char		drv_statep[MODMAXNAMELEN+ 10];
	uint_t		usb_flag  = NULL;
	boolean_t	no_driver_attached = FALSE;
	uintptr_t	dip_addr;
	struct dev_info	devinfo;

	if (!(flags & DCMD_ADDRSPEC)) {
		/* Global walk */
		if (mdb_walk_dcmd("usba_device", "usba_device", argc,
		    argv) == -1) {
			mdb_warn("failed to walk usba_device");

			return (DCMD_ERR);
		}

		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'p', MDB_OPT_SETBITS, USB_DUMP_ACTIVE_PIPES, &usb_flag,
	    'v', MDB_OPT_SETBITS, USB_DUMP_VERBOSE, &usb_flag, NULL) != argc) {

		return (DCMD_USAGE);
	}

	if (usb_flag && !(DCMD_HDRSPEC(flags))) {
		mdb_printf("\n");
	}

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-15s %4s %-?s %-42s%</u>\n",
		    "NAME", "INST", "DIP", "PATH                             ");
	}

	status = usba_device2dip(addr, &dip_addr);
	/*
	 * -1 = error
	 * 0 = no error, no match
	 * 1 = no error, match
	 */
	if (status != 1) {
		if (status == -1) {
			mdb_warn("error looking for dip for usba_device %p",
			    addr);
		} else {
			mdb_warn("failed to find dip for usba_device %p\n",
			    addr);
		}
		mdb_warn("dip and statep unobtainable\n");

		return (DCMD_ERR);
	}

	/* Figure out what driver (name) is attached to this node. */
	(void) mdb_devinfo2driver(dip_addr, (char *)dname, sizeof (dname));

	if (mdb_vread(&devinfo, sizeof (struct dev_info),
	    dip_addr) == -1) {
		mdb_warn("failed to read devinfo");

		return (DCMD_ERR);
	}

	if (!(DDI_CF2(&devinfo))) {
		no_driver_attached = TRUE;
	}

	(void) mdb_ddi_pathname(dip_addr, pathname, sizeof (pathname));
	mdb_printf("%-15s %2d   %-?p %s\n", dname, devinfo.devi_instance,
	    dip_addr, pathname);

	if (usb_flag & USB_DUMP_VERBOSE) {
		int		i;
		uintptr_t	statep = NULL;
		char		*string_descr;
		char		**config_cloud, **conf_str_descr;
		usb_dev_descr_t	usb_dev_descr;
		usba_device_t	usba_device_struct;

		if (mdb_vread(&usba_device_struct,
		    sizeof (usba_device_t), addr) == -1) {
			mdb_warn("failed to read usba_device struct");

			return (DCMD_ERR);
		}

		mdb_printf("    usba_device: %-16p\n\n", (usba_device_t *)addr);

		if (mdb_vread(&usb_dev_descr, sizeof (usb_dev_descr),
		    (uintptr_t)usba_device_struct.usb_dev_descr) == -1) {
			mdb_warn("failed to read usb_dev_descr_t struct");

			return (DCMD_ERR);
		}

		mdb_printf("\n    idVendor: 0x%04x idProduct: 0x%04x "
		    "usb_addr: 0x%02x\n", usb_dev_descr.idVendor,
		    usb_dev_descr.idProduct, usba_device_struct.usb_addr);

		/* Get the string descriptor string into local space. */
		string_descr = (char *)mdb_alloc(USB_MAXSTRINGLEN, UM_GC);

		if (usba_device_struct.usb_mfg_str == NULL) {
			(void) strcpy(string_descr, "<No Manufacturer String>");
		} else {
			if (mdb_readstr(string_descr, USB_MAXSTRINGLEN,
			    (uintptr_t)usba_device_struct.usb_mfg_str) == -1) {
				mdb_warn("failed to read manufacturer "
				    "string descriptor");
				(void) strcpy(string_descr, "???");
			}
		}
		mdb_printf("\n    Manufacturer String:\t%s\n", string_descr);

		if (usba_device_struct.usb_product_str == NULL) {
			(void) strcpy(string_descr, "<No Product String>");
		} else {
			if (mdb_readstr(string_descr, USB_MAXSTRINGLEN,
			    (uintptr_t)usba_device_struct.usb_product_str) ==
			    -1) {
				mdb_warn("failed to read product string "
				    "descriptor");
				(void) strcpy(string_descr, "???");
			}
		}
		mdb_printf("    Product String:\t\t%s\n", string_descr);

		if (usba_device_struct.usb_serialno_str == NULL) {
			(void) strcpy(string_descr, "<No SerialNumber String>");
		} else {
			if (mdb_readstr(string_descr, USB_MAXSTRINGLEN,
			    (uintptr_t)usba_device_struct.usb_serialno_str) ==
			    -1) {
				mdb_warn("failed to read serial number string "
				    "descriptor");
				(void) strcpy(string_descr, "???");
			}
		}
		mdb_printf("    SerialNumber String:\t%s\n", string_descr);

		if (no_driver_attached) {
			mdb_printf("\n");
		} else {
			mdb_printf("      state_p: ");

			/*
			 * Given the dip, find the associated statep. The
			 * convention to generate this soft state anchor is:
			 *	<driver_name>_statep
			 */
			(void) mdb_snprintf(drv_statep, sizeof (drv_statep),
			    "%s_statep", dname);
			if (mdb_devinfo2statep(dip_addr, drv_statep,
			    &statep) == -1) {
				mdb_warn("failed to find %s state struct for "
				    "dip %p", drv_statep, dip_addr);

				return (DCMD_ERR);
			}
			mdb_printf("%-?p\n", statep);
		}

		config_cloud = (char **)mdb_alloc(sizeof (void *) *
		    usba_device_struct.usb_n_cfgs, UM_GC);

		conf_str_descr = (char **)mdb_alloc(sizeof (void *) *
		    usba_device_struct.usb_n_cfgs, UM_GC);

		if ((usba_device_struct.usb_cfg_array) &&
		    (usba_device_struct.usb_cfg_str_descr)) {
			if ((mdb_vread(config_cloud,  sizeof (void *) *
			    usba_device_struct.usb_n_cfgs,
			    (uintptr_t)usba_device_struct.usb_cfg_array) ==
			    -1) || (mdb_vread(conf_str_descr, sizeof (void *)
			    * usba_device_struct.usb_n_cfgs, (uintptr_t)
			    usba_device_struct.usb_cfg_str_descr)) == -1) {

			    mdb_warn("failed to read config cloud pointers");

			} else {

				mdb_printf("\n    Device Config Clouds:\n"
				    "    Index\tConfig\t\tConfiguration "
				    "String\n"
				    "    -----\t------\t\t"
				    "--------------------\n");

				for (i = 0; i < usba_device_struct.usb_n_cfgs;
				    i++) {
					if (mdb_readstr(string_descr,
					    USB_MAXSTRINGLEN,
					    (uintptr_t)conf_str_descr[i]) ==
					    -1) {
						(void) strcpy(string_descr,
						    "<No Configuration "
						    "String>");
					}
					mdb_printf("    %4d\t0x%p\t%s\n", i,
					    config_cloud[i], string_descr);
				}
			}
		}

		mdb_printf("\n    Active configuration index: %d\n",
		    usba_device_struct.usb_active_cfg_ndx);
	}

	if (usb_flag & USB_DUMP_ACTIVE_PIPES) {

		if (mdb_pwalk_dcmd("usb_pipe_handle", "usb_pipe_handle",
		    0, NULL, addr) == -1) {
			mdb_warn("failed to walk usb_pipe_handle");
			return (DCMD_ERR);
		}
	}

	return (DCMD_OK);
}
Example #23
0
static int
request_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	request_log_entry_t cur;
	hrtime_t dur;
	hrtime_t dursec;
	hrtime_t durnsec;
	char durstr[20];
	char stampstr[20];
	char requstr[30];
	char respstr[30];
	char typestr[30];
	uintptr_t node = 0;
	uintptr_t client = 0;
	uint64_t clientid = 0;

	int idx;
	int opt_v = FALSE;			/* verbose */

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("configd_log", "configd_log", argc,
		    argv) == -1) {
			mdb_warn("can't walk 'configd_log'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'c', MDB_OPT_UINTPTR, &client,
	    'i', MDB_OPT_UINT64, &clientid,
	    'n', MDB_OPT_UINTPTR, &node,
	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
		return (DCMD_USAGE);

	if (DCMD_HDRSPEC(flags)) {
		mdb_printf("%<u>%-?s %-4s %-14s %9s %-22s %-17s\n%</u>",
		    "ADDR", "THRD", "START", "DURATION", "REQUEST",
		    "RESPONSE");
	}

	if (mdb_vread(&cur, sizeof (cur), addr) == -1) {
		mdb_warn("couldn't read log entry at %p", addr);
		return (DCMD_ERR);
	}

	/*
	 * apply filters, if any.
	 */
	if (clientid != 0 && clientid != cur.rl_clientid)
		return (DCMD_OK);

	if (client != 0 && client != (uintptr_t)cur.rl_client)
		return (DCMD_OK);

	if (node != 0) {
		for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
			if ((uintptr_t)cur.rl_ptrs[idx].rlp_data == node) {
				node = 0;		/* found it */
				break;
			}
		}
		if (node != 0)
			return (DCMD_OK);
	}

	enum_lookup(requstr, sizeof (requstr), request_enum, cur.rl_request,
	    "REP_PROTOCOL_", "");

	if (cur.rl_end != 0) {
		enum_lookup(respstr, sizeof (respstr), response_enum,
		    cur.rl_response, "REP_PROTOCOL_", "FAIL_");

		dur = cur.rl_end - cur.rl_start;
		dursec = dur / NANOSEC;
		durnsec = dur % NANOSEC;

		if (dursec <= 9)
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld.%06lld",
			    dursec, durnsec / (NANOSEC / MICROSEC));
		else if (dursec <= 9999)
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld.%03lld",
			    dursec, NSEC2MSEC(durnsec));
		else
			mdb_snprintf(durstr, sizeof (durstr),
			    "%lld", dursec);
	} else {
		(void) strcpy(durstr, "-");
		(void) strcpy(respstr, "-");
	}

	if (max_time_seen != 0 && max_time_seen >= cur.rl_start) {
		dur = max_time_seen - cur.rl_start;
		dursec = dur / NANOSEC;
		durnsec = dur % NANOSEC;

		if (dursec <= 99ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%09lld", dursec, durnsec);
		else if (dursec <= 99999ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%06lld",
			    dursec, durnsec / (NANOSEC / MICROSEC));
		else if (dursec <= 99999999ULL)
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld.%03lld",
			    dursec, NSEC2MSEC(durnsec));
		else
			mdb_snprintf(stampstr, sizeof (stampstr),
			    "-%lld", dursec);
	} else {
		(void) strcpy(stampstr, "-");
	}

	mdb_printf("%0?x %4d T%13s %9s %-22s %-17s\n",
	    addr, cur.rl_tid, stampstr, durstr, requstr, respstr);

	if (opt_v) {
		mdb_printf("\tclient: %?p (%d)\tptrs: %d\tstamp: %llx\n",
		    cur.rl_client, cur.rl_clientid, cur.rl_num_ptrs,
		    cur.rl_start);
		for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
			enum_lookup(typestr, sizeof (typestr), ptr_type_enum,
			    cur.rl_ptrs[idx].rlp_type, "RC_PTR_TYPE_", "");
			mdb_printf("\t\t%-7s %5d %?p %?p\n", typestr,
			    cur.rl_ptrs[idx].rlp_id, cur.rl_ptrs[idx].rlp_ptr,
			    cur.rl_ptrs[idx].rlp_data);
		}
		mdb_printf("\n");
	}
	return (DCMD_OK);
}
Example #24
0
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);
}
Example #25
0
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);
}
Example #26
0
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);
}
Example #27
0
/*ARGSUSED*/
int
fsinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	vfs_t vfs;
	int len;
	int opt_v = 0;
	char buf[MAXPATHLEN];
	char fsname[_ST_FSTYPSZ];
	mntopt_t *mntopts;
	size_t size;
	int i;
	int first = 1;
	char opt[MAX_MNTOPT_STR];
	uintptr_t global_zone;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("vfs", "fsinfo", argc, argv) == -1) {
			mdb_warn("failed to walk file system list");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
		return (DCMD_USAGE);

	if (DCMD_HDRSPEC(flags))
		mdb_printf("%<u>%?s %-15s %s%</u>\n",
		    "VFSP", "FS", "MOUNT");

	if (mdb_vread(&vfs, sizeof (vfs), addr) == -1) {
		mdb_warn("failed to read vfs_t %p", addr);
		return (DCMD_ERR);
	}

	if ((len = mdb_read_refstr((uintptr_t)vfs.vfs_mntpt, buf,
	    sizeof (buf))) <= 0)
		strcpy(buf, "??");

	else if (!opt_v && (len >= FSINFO_MNTLEN))
		/*
		 * In normal mode, we truncate the path to keep the output
		 * clean.  In -v mode, we just print the full path.
		 */
		strcpy(&buf[FSINFO_MNTLEN - 4], "...");

	if (read_fsname(addr, fsname) == -1)
		return (DCMD_ERR);

	mdb_printf("%0?p %-15s %s\n", addr, fsname, buf);

	if (!opt_v)
		return (DCMD_OK);

	/*
	 * Print 'resource' string; this shows what we're mounted upon.
	 */
	if (mdb_read_refstr((uintptr_t)vfs.vfs_resource, buf,
	    MAXPATHLEN) <= 0)
		strcpy(buf, "??");

	mdb_printf("%?s %s\n", "R:", buf);

	/*
	 * Print mount options array; it sucks to be a mimic, but we copy
	 * the same logic as in mntvnops.c for adding zone= tags, and we
	 * don't bother with the obsolete dev= option.
	 */
	size = vfs.vfs_mntopts.mo_count * sizeof (mntopt_t);
	mntopts = mdb_alloc(size, UM_SLEEP | UM_GC);

	if (mdb_vread(mntopts, size,
	    (uintptr_t)vfs.vfs_mntopts.mo_list) == -1) {
		mdb_warn("failed to read mntopts %p", vfs.vfs_mntopts.mo_list);
		return (DCMD_ERR);
	}

	for (i = 0; i < vfs.vfs_mntopts.mo_count; i++) {
		if (mntopts[i].mo_flags & MO_SET) {
			if (mdb_readstr(opt, sizeof (opt),
			    (uintptr_t)mntopts[i].mo_name) == -1) {
				mdb_warn("failed to read mntopt name %p",
				    mntopts[i].mo_name);
				return (DCMD_ERR);
			}
			if (first) {
				mdb_printf("%?s ", "O:");
				first = 0;
			} else {
				mdb_printf(",");
			}
			mdb_printf("%s", opt);
			if (mntopts[i].mo_flags & MO_HASVALUE) {
				if (mdb_readstr(opt, sizeof (opt),
				    (uintptr_t)mntopts[i].mo_arg) == -1) {
					mdb_warn("failed to read mntopt "
					    "value %p", mntopts[i].mo_arg);
					return (DCMD_ERR);
				}
				mdb_printf("=%s", opt);
			}
		}
	}

	if (mdb_readvar(&global_zone, "global_zone") == -1) {
		mdb_warn("failed to locate global_zone");
		return (DCMD_ERR);
	}

	if ((vfs.vfs_zone != NULL) &&
	    ((uintptr_t)vfs.vfs_zone != global_zone)) {
		zone_t z;

		if (mdb_vread(&z, sizeof (z), (uintptr_t)vfs.vfs_zone) == -1) {
			mdb_warn("failed to read zone");
			return (DCMD_ERR);
		}
		/*
		 * zone names are much shorter than MAX_MNTOPT_STR
		 */
		if (mdb_readstr(opt, sizeof (opt),
		    (uintptr_t)z.zone_name) == -1) {
			mdb_warn("failed to read zone name");
			return (DCMD_ERR);
		}
		if (first) {
			mdb_printf("%?s ", "O:");
		} else {
			mdb_printf(",");
		}
		mdb_printf("zone=%s", opt);
	}
	return (DCMD_OK);
}
Example #28
0
int
sonode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	const char *optf = NULL;
	const char *optt = NULL;
	const char *optp = NULL;
	int family, type, proto;
	int filter = 0;
	struct sonode so;

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("genunix`sonode", "genunix`sonode", argc,
		    argv) == -1) {
			mdb_warn("failed to walk sonode");
			return (DCMD_ERR);
		}

		return (DCMD_OK);
	}

	if (mdb_getopts(argc, argv,
	    'f', MDB_OPT_STR, &optf,
	    't', MDB_OPT_STR, &optt,
	    'p', MDB_OPT_STR, &optp,
	    NULL) != argc)
		return (DCMD_USAGE);

	if (optf != NULL) {
		if (strcmp("inet", optf) == 0)
			family = AF_INET;
		else if (strcmp("inet6", optf) == 0)
			family = AF_INET6;
		else if (strcmp("unix", optf) == 0)
			family = AF_UNIX;
		else
			family = mdb_strtoull(optf);
		filter = 1;
	}

	if (optt != NULL) {
		if (strcmp("stream", optt) == 0)
			type = SOCK_STREAM;
		else if (strcmp("dgram", optt) == 0)
			type = SOCK_DGRAM;
		else if (strcmp("raw", optt) == 0)
			type = SOCK_RAW;
		else
			type = mdb_strtoull(optt);
		filter = 1;
	}

	if (optp != NULL) {
		proto = mdb_strtoull(optp);
		filter = 1;
	}

	if (DCMD_HDRSPEC(flags) && !filter) {
		mdb_printf("%<u>%-?s Family Type Proto State Mode Flag "
		    "AccessVP%</u>\n", "Sonode:");
	}

	if (mdb_vread(&so, sizeof (so), addr) == -1) {
		mdb_warn("failed to read sonode at %p", addr);
		return (DCMD_ERR);
	}

	if ((optf != NULL) && (so.so_family != family))
		return (DCMD_OK);

	if ((optt != NULL) && (so.so_type != type))
		return (DCMD_OK);

	if ((optp != NULL) && (so.so_protocol != proto))
		return (DCMD_OK);

	if (filter) {
		mdb_printf("%0?p\n", addr);
		return (DCMD_OK);
	}

	mdb_printf("%0?p ", addr);

	switch (so.so_family) {
	case AF_UNIX:
		mdb_printf("unix  ");
		break;
	case AF_INET:
		mdb_printf("inet  ");
		break;
	case AF_INET6:
		mdb_printf("inet6 ");
		break;
	default:
		mdb_printf("%6hi", so.so_family);
	}

	switch (so.so_type) {
	case SOCK_STREAM:
		mdb_printf(" strm");
		break;
	case SOCK_DGRAM:
		mdb_printf(" dgrm");
		break;
	case SOCK_RAW:
		mdb_printf(" raw ");
		break;
	default:
		mdb_printf(" %4hi", so.so_type);
	}

	mdb_printf(" %5hi %05x %04x %04hx\n",
	    so.so_protocol, so.so_state, so.so_mode,
	    so.so_flag);

	return (DCMD_OK);
}
Example #29
0
static int
fcp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	struct fcp_port		pinfo;

	if (argc != 0) {
		return (DCMD_USAGE);
	}

	if (!(flags & DCMD_ADDRSPEC)) {
		if (mdb_walk_dcmd("fcp", "fcp",
		    argc, argv) == -1) {
			mdb_warn("failed to walk 'fcp_port_head'");
			return (DCMD_ERR);
		}
		return (DCMD_OK);
	}

	mdb_printf("FCP structure at %p\n", addr);

	/*
	 * For each port, we just need to read the fc_fca_port_t struct, read
	 * the port_handle
	 */
	if (mdb_vread(&pinfo, sizeof (struct fcp_port), addr) !=
	    sizeof (struct fcp_port)) {
		mdb_warn("failed to read fcp_port at %p", addr);
		return (DCMD_OK);
	}

	mdb_printf("  mutex             : 0x%-08x\n", pinfo.port_mutex);
	mdb_printf("  ipkt_list         : 0x%p\n", pinfo.port_ipkt_list);
	mdb_printf("  state             : 0x%-08x\n", pinfo.port_state);
	mdb_printf("  phys_state        : 0x%-08x\n", pinfo.port_phys_state);
	mdb_printf("  top               : %u\n", pinfo.port_topology);
	mdb_printf("  sid               : 0x%-06x\n", pinfo.port_id);
	mdb_printf("  reset_list        : 0x%p\n", pinfo.port_reset_list);
	mdb_printf("  link_cnt          : %u\n", pinfo.port_link_cnt);
	mdb_printf("  deadline          : %d\n", pinfo.port_deadline);
	mdb_printf("  port wwn          : "
	    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
	    pinfo.port_pwwn.raw_wwn[0], pinfo.port_pwwn.raw_wwn[1],
	    pinfo.port_pwwn.raw_wwn[2], pinfo.port_pwwn.raw_wwn[3],
	    pinfo.port_pwwn.raw_wwn[4], pinfo.port_pwwn.raw_wwn[5],
	    pinfo.port_pwwn.raw_wwn[6], pinfo.port_pwwn.raw_wwn[7]);
	mdb_printf("  node wwn          : "
	    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
	    pinfo.port_nwwn.raw_wwn[0], pinfo.port_nwwn.raw_wwn[1],
	    pinfo.port_nwwn.raw_wwn[2], pinfo.port_nwwn.raw_wwn[3],
	    pinfo.port_nwwn.raw_wwn[4], pinfo.port_nwwn.raw_wwn[5],
	    pinfo.port_nwwn.raw_wwn[6], pinfo.port_nwwn.raw_wwn[7]);
	mdb_printf("  handle            : 0x%p\n", pinfo.port_fp_handle);
	mdb_printf("  cmd_mutex         : 0x%-08x\n", pinfo.port_pkt_mutex);
	mdb_printf("  ncmds             : %u\n", pinfo.port_npkts);
	mdb_printf("  pkt_head          : 0x%p\n", pinfo.port_pkt_head);
	mdb_printf("  pkt_tail          : 0x%p\n", pinfo.port_pkt_tail);
	mdb_printf("  ipkt_cnt          : %d\n", pinfo.port_ipkt_cnt);
	mdb_printf("  instance          : %u\n", pinfo.port_instance);
	mdb_printf("  max_exch          : %u\n", pinfo.port_max_exch);
	mdb_printf("  cmds_aborted      : 0x%-08x\n",
	    pinfo.port_reset_action);
	mdb_printf("  cmds_dma_flags    : 0x%-08x\n",
	    pinfo.port_cmds_dma_flags);
	mdb_printf("  fcp_dma           : 0x%-08x\n", pinfo.port_fcp_dma);
	mdb_printf("  priv_pkt_len      : %u\n", pinfo.port_priv_pkt_len);
	mdb_printf("  data_dma_attr     : 0x%-08x\n",
	    pinfo.port_data_dma_attr);
	mdb_printf("  cmd_dma_attr      : 0x%-08x\n",
	    pinfo.port_cmd_dma_attr);
	mdb_printf("  resp_dma_attr     : 0x%-08x\n",
	    pinfo.port_resp_dma_attr);
	mdb_printf("  dma_acc_attr      : 0x%-08x\n",
	    pinfo.port_dma_acc_attr);
	mdb_printf("  tran              : 0x%p\n", pinfo.port_tran);
	mdb_printf("  dip               : 0x%p\n", pinfo.port_dip);
	mdb_printf("  reset_notify_listf: 0x%p\n",
	    pinfo.port_reset_notify_listf);
	mdb_printf("  event_defs        : 0x%p\n", pinfo.port_ndi_event_defs);
	mdb_printf("  event_hdl         : 0x%p\n", pinfo.port_ndi_event_hdl);
	mdb_printf("  events            : 0x%p\n", pinfo.port_ndi_events);
	mdb_printf("  tgt_hash_table    : 0x%p\n", pinfo.port_tgt_hash_table);
	mdb_printf("  mpxio             : %d\n", pinfo.port_mpxio);

	mdb_printf("\n");

	return (DCMD_OK);
}
Example #30
0
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);
}