17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
556e23938Sbustos  * Common Development and Distribution License (the "License").
656e23938Sbustos  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*f6e214c7SGavin Maltby  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <libuutil.h>
287c478bd9Sstevel@tonic-gate #include <libuutil_impl.h>
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <librestart_priv.h>		/* instance_data_t */
317c478bd9Sstevel@tonic-gate #include <startd.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * To count the elements of a uu_list_t without knowing its implementation, we
367c478bd9Sstevel@tonic-gate  * must walk & count them.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate /* ARGSUSED */
397c478bd9Sstevel@tonic-gate static int
inc_sz(uintptr_t addr,const void * unknown,void * data)407c478bd9Sstevel@tonic-gate inc_sz(uintptr_t addr, const void *unknown, void *data)
417c478bd9Sstevel@tonic-gate {
427c478bd9Sstevel@tonic-gate 	size_t *sz = data;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate 	++(*sz);
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
477c478bd9Sstevel@tonic-gate }
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*ARGSUSED*/
507c478bd9Sstevel@tonic-gate static int
startd_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)517c478bd9Sstevel@tonic-gate startd_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	uu_list_t *dgraphp;
547c478bd9Sstevel@tonic-gate 	restarter_instance_list_t ril;
557c478bd9Sstevel@tonic-gate 	u_longlong_t ns_total;
567c478bd9Sstevel@tonic-gate 	u_longlong_t lookups;
577c478bd9Sstevel@tonic-gate 	u_longlong_t dep_inserts, dep_cycle_ns, dep_insert_ns;
587c478bd9Sstevel@tonic-gate 	size_t graph_num, restarter_num;
59*f6e214c7SGavin Maltby 	uint64_t ct_maint;
60*f6e214c7SGavin Maltby 	uint64_t ct_hwerr;
61*f6e214c7SGavin Maltby 	uint64_t ct_service;
62*f6e214c7SGavin Maltby 	uint64_t ct_global;
63*f6e214c7SGavin Maltby 	uint64_t ct_noprefs;
64*f6e214c7SGavin Maltby 	uint64_t ct_from_uninit;
65*f6e214c7SGavin Maltby 	uint64_t ct_bad_state;
66*f6e214c7SGavin Maltby 	uint64_t ct_ovr_prefs;
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&lookups, "dictionary_lookups") == -1) {
697c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dictionary_lookups' value\n");
707c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
717c478bd9Sstevel@tonic-gate 	}
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&ns_total, "dictionary_ns_total") == -1) {
747c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dictionary_ns_total' value\n");
757c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
767c478bd9Sstevel@tonic-gate 	}
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&dep_inserts, "dep_inserts") == -1) {
797c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dep_inserts' value\n");
807c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
817c478bd9Sstevel@tonic-gate 	}
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&dep_cycle_ns, "dep_cycle_ns") == -1) {
847c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dep_cycle_ns' value\n");
857c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&dep_insert_ns, "dep_insert_ns") == -1) {
897c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dep_insert_ns' value\n");
907c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
917c478bd9Sstevel@tonic-gate 	}
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&dgraphp, "dgraph") == -1) {
947c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'dgraph' value\n");
957c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
967c478bd9Sstevel@tonic-gate 	}
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	graph_num = 0;
997c478bd9Sstevel@tonic-gate 	if (mdb_pwalk("uu_list_node", inc_sz, &graph_num,
1007c478bd9Sstevel@tonic-gate 	    (uintptr_t)dgraphp) == -1) {
1017c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read uu_list\n");
1027c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
1037c478bd9Sstevel@tonic-gate 	}
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&ril, "instance_list") == -1) {
1067c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'instance_list' value\n");
1077c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	restarter_num = 0;
1117c478bd9Sstevel@tonic-gate 	if (mdb_pwalk("uu_list_node", inc_sz, &restarter_num,
1127c478bd9Sstevel@tonic-gate 	    (uintptr_t)ril.ril_instance_list) == -1) {
1137c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read uu_list\n");
1147c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
1157c478bd9Sstevel@tonic-gate 	}
1167c478bd9Sstevel@tonic-gate 
117*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_maint, "stev_ct_maint") == -1) {
118*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_maint'\n");
119*f6e214c7SGavin Maltby 		return (DCMD_ERR);
120*f6e214c7SGavin Maltby 	}
121*f6e214c7SGavin Maltby 
122*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_hwerr, "stev_ct_hwerr") == -1) {
123*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_hwerr'\n");
124*f6e214c7SGavin Maltby 		return (DCMD_ERR);
125*f6e214c7SGavin Maltby 	}
126*f6e214c7SGavin Maltby 
127*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_service, "stev_ct_service") == -1) {
128*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_service'\n");
129*f6e214c7SGavin Maltby 		return (DCMD_ERR);
130*f6e214c7SGavin Maltby 	}
131*f6e214c7SGavin Maltby 
132*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_global, "stev_ct_global") == -1) {
133*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_global'\n");
134*f6e214c7SGavin Maltby 		return (DCMD_ERR);
135*f6e214c7SGavin Maltby 	}
136*f6e214c7SGavin Maltby 
137*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_noprefs, "stev_ct_noprefs") == -1) {
138*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_noprefs'\n");
139*f6e214c7SGavin Maltby 		return (DCMD_ERR);
140*f6e214c7SGavin Maltby 	}
141*f6e214c7SGavin Maltby 
142*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_from_uninit, "stev_ct_from_uninit") == -1) {
143*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_from_uninit'\n");
144*f6e214c7SGavin Maltby 		return (DCMD_ERR);
145*f6e214c7SGavin Maltby 	}
146*f6e214c7SGavin Maltby 
147*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_bad_state, "stev_ct_bad_state") == -1) {
148*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_bad_state'\n");
149*f6e214c7SGavin Maltby 		return (DCMD_ERR);
150*f6e214c7SGavin Maltby 	}
151*f6e214c7SGavin Maltby 
152*f6e214c7SGavin Maltby 	if (mdb_readvar(&ct_ovr_prefs, "stev_ct_ovr_prefs") == -1) {
153*f6e214c7SGavin Maltby 		mdb_warn("failed to read 'stev_ct_ovr_prefs'\n");
154*f6e214c7SGavin Maltby 		return (DCMD_ERR);
155*f6e214c7SGavin Maltby 	}
156*f6e214c7SGavin Maltby 
1577c478bd9Sstevel@tonic-gate 	mdb_printf(
158*f6e214c7SGavin Maltby 	    "General stats\n"
159*f6e214c7SGavin Maltby 	    "              dictionary lookups: %llu\n"
160*f6e214c7SGavin Maltby 	    "             average lookup time: %llu us\n"
161*f6e214c7SGavin Maltby 	    "     graph dependency insertions: %llu\n"
162*f6e214c7SGavin Maltby 	    "        average cycle-check time: %llu us\n"
163*f6e214c7SGavin Maltby 	    "      avg dependency insert time: %llu us\n"
164*f6e214c7SGavin Maltby 	    "       number of nodes in dgraph: %llu\n"
165*f6e214c7SGavin Maltby 	    "number of nodes in instance_list: %llu\n"
166*f6e214c7SGavin Maltby 	    "\nState Transition Events\n"
167*f6e214c7SGavin Maltby 	    "                     maintenance: %llu\n"
168*f6e214c7SGavin Maltby 	    "                  hardware error: %llu\n"
169*f6e214c7SGavin Maltby 	    "           service specific pref: %llu\n"
170*f6e214c7SGavin Maltby 	    "                system wide pref: %llu\n"
171*f6e214c7SGavin Maltby 	    "            no prefs, not raised: %llu\n"
172*f6e214c7SGavin Maltby 	    "          from unint, not raised: %llu\n"
173*f6e214c7SGavin Maltby 	    "           bad state, not raised: %llu\n"
174*f6e214c7SGavin Maltby 	    "           override pref, raised: %llu\n", lookups,
1757c478bd9Sstevel@tonic-gate 	    lookups ? ns_total / (1000 * lookups) : 0, dep_inserts,
1767c478bd9Sstevel@tonic-gate 	    dep_inserts ? dep_cycle_ns / (1000 * dep_inserts) : 0,
1777c478bd9Sstevel@tonic-gate 	    dep_inserts ? dep_insert_ns / (1000 * dep_inserts) : 0,
178*f6e214c7SGavin Maltby 	    (u_longlong_t)graph_num, (u_longlong_t)restarter_num,
179*f6e214c7SGavin Maltby 	    ct_maint, ct_hwerr, ct_service, ct_global, ct_noprefs,
180*f6e214c7SGavin Maltby 	    ct_from_uninit, ct_bad_state, ct_ovr_prefs);
181*f6e214c7SGavin Maltby 
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate static char
xstate2chr(restarter_instance_state_t s)1877c478bd9Sstevel@tonic-gate xstate2chr(restarter_instance_state_t s)
1887c478bd9Sstevel@tonic-gate {
1897c478bd9Sstevel@tonic-gate 	switch (s) {
1907c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_UNINIT:	return ('u');
1917c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_DISABLED:	return ('d');
1927c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_OFFLINE:	return ('0');
1937c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_DEGRADED:	return ('D');
1947c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_ONLINE:	return ('1');
1957c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_MAINT:	return ('m');
1967c478bd9Sstevel@tonic-gate 	case RESTARTER_STATE_NONE:	return ('n');
1977c478bd9Sstevel@tonic-gate 	default:			return ('?');
1987c478bd9Sstevel@tonic-gate 	}
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2027c478bd9Sstevel@tonic-gate static int
pr_instance(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2037c478bd9Sstevel@tonic-gate pr_instance(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2047c478bd9Sstevel@tonic-gate {
2057c478bd9Sstevel@tonic-gate 	restarter_instance_list_t ril;
2067c478bd9Sstevel@tonic-gate 	restarter_inst_t ri;
2077c478bd9Sstevel@tonic-gate 	char *iname;
2087c478bd9Sstevel@tonic-gate 	char statechr = '-';
2097c478bd9Sstevel@tonic-gate 	char typechr;
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0) {
2127c478bd9Sstevel@tonic-gate 		if (mdb_readvar(&ril, "instance_list") == -1) {
2137c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read 'instance_list' value\n");
2147c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 		if (mdb_pwalk_dcmd("uu_list_node", "instance", 0, NULL,
2187c478bd9Sstevel@tonic-gate 		    (uintptr_t)ril.ril_instance_list) == -1) {
2197c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk instances\n");
2207c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
2217c478bd9Sstevel@tonic-gate 		}
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
2247c478bd9Sstevel@tonic-gate 	}
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ri, sizeof (restarter_inst_t), addr) == -1) {
2277c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read instance at %a\n");
2287c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2297c478bd9Sstevel@tonic-gate 	}
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
2327c478bd9Sstevel@tonic-gate 		mdb_printf("%-10s %-3s %1s %1s %4s\n", "ADDR", "ID", "T", "S",
2337c478bd9Sstevel@tonic-gate 		    "FMRI");
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	iname = mdb_alloc(1024, UM_SLEEP | UM_GC);
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	if (mdb_readstr(iname, 1024, (uintptr_t)ri.ri_i.i_fmri) == -1) {
2387c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read instance name\n");
2397c478bd9Sstevel@tonic-gate 		strcpy(iname, "-");
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	statechr = xstate2chr(ri.ri_i.i_state);
2437c478bd9Sstevel@tonic-gate 	typechr = (ri.ri_i.i_enabled) ? 'I' : 'i';
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	mdb_printf("%-10a %3x %c %c %s\n", addr, ri.ri_id, typechr, statechr,
2467c478bd9Sstevel@tonic-gate 	    iname);
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2527c478bd9Sstevel@tonic-gate static int
pr_vertex(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2537c478bd9Sstevel@tonic-gate pr_vertex(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate 	uu_list_t *dgraphp;
2567c478bd9Sstevel@tonic-gate 	graph_vertex_t gv;
2577c478bd9Sstevel@tonic-gate 	char *vname;
2587c478bd9Sstevel@tonic-gate 	int id;
2597c478bd9Sstevel@tonic-gate 	char typechr;
2607c478bd9Sstevel@tonic-gate 	char statechr = '-';
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_ADDRSPEC) == 0) {
2637c478bd9Sstevel@tonic-gate 		if (mdb_readvar(&dgraphp, "dgraph") == -1) {
2647c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read 'dgraph' value\n");
2657c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
2667c478bd9Sstevel@tonic-gate 		}
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 		if (mdb_pwalk_dcmd("uu_list_node", "vertex", 0, NULL,
2697c478bd9Sstevel@tonic-gate 		    (uintptr_t)dgraphp) == -1) {
2707c478bd9Sstevel@tonic-gate 			mdb_warn("can't walk vertices");
2717c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
2727c478bd9Sstevel@tonic-gate 		}
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	if (mdb_vread(&gv, sizeof (graph_vertex_t), addr) == -1) {
2787c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read vertex at %a\n");
2797c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2807c478bd9Sstevel@tonic-gate 	}
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	if (DCMD_HDRSPEC(flags))
2837c478bd9Sstevel@tonic-gate 		mdb_printf("%-10s %-3s %1s %1s %4s\n", "ADDR", "ID", "T", "S",
2847c478bd9Sstevel@tonic-gate 		    "FMRI");
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	vname = mdb_alloc(1024, UM_SLEEP | UM_GC);
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	if (mdb_readstr(vname, 1024, (uintptr_t)gv.gv_name) == -1) {
2897c478bd9Sstevel@tonic-gate 		mdb_warn("couldn't read vertex name\n");
2907c478bd9Sstevel@tonic-gate 		strcpy(vname, "-");
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	id = gv.gv_id;
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	switch (gv.gv_type) {
2967c478bd9Sstevel@tonic-gate 	case GVT_FILE:
2977c478bd9Sstevel@tonic-gate 		typechr = 'f';
2987c478bd9Sstevel@tonic-gate 		break;
2997c478bd9Sstevel@tonic-gate 	case GVT_GROUP:
3007c478bd9Sstevel@tonic-gate 		switch (gv.gv_depgroup) {
3017c478bd9Sstevel@tonic-gate 		case DEPGRP_REQUIRE_ANY:
3027c478bd9Sstevel@tonic-gate 			typechr = 'r';
3037c478bd9Sstevel@tonic-gate 			break;
3047c478bd9Sstevel@tonic-gate 		case DEPGRP_REQUIRE_ALL:
3057c478bd9Sstevel@tonic-gate 			typechr = 'R';
3067c478bd9Sstevel@tonic-gate 			break;
3077c478bd9Sstevel@tonic-gate 		case DEPGRP_EXCLUDE_ALL:
3087c478bd9Sstevel@tonic-gate 			typechr = 'X';
3097c478bd9Sstevel@tonic-gate 			break;
3107c478bd9Sstevel@tonic-gate 		case DEPGRP_OPTIONAL_ALL:
3117c478bd9Sstevel@tonic-gate 			typechr = 'o';
3127c478bd9Sstevel@tonic-gate 			break;
3137c478bd9Sstevel@tonic-gate 		default:
3147c478bd9Sstevel@tonic-gate 			typechr = '?';
3157c478bd9Sstevel@tonic-gate 			break;
3167c478bd9Sstevel@tonic-gate 		}
3177c478bd9Sstevel@tonic-gate 		break;
3187c478bd9Sstevel@tonic-gate 	case GVT_INST:
3197c478bd9Sstevel@tonic-gate 		typechr = (gv.gv_flags & GV_ENABLED) ? 'I' : 'i';
3207c478bd9Sstevel@tonic-gate 		statechr = xstate2chr(gv.gv_state);
3217c478bd9Sstevel@tonic-gate 		break;
3227c478bd9Sstevel@tonic-gate 	case GVT_SVC:
3237c478bd9Sstevel@tonic-gate 		typechr = 's';
3247c478bd9Sstevel@tonic-gate 		break;
3257c478bd9Sstevel@tonic-gate 	default:
3267c478bd9Sstevel@tonic-gate 		typechr = '?';
3277c478bd9Sstevel@tonic-gate 		break;
3287c478bd9Sstevel@tonic-gate 	}
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	mdb_printf("%-10a %3x %c %c %s\n", addr, id, typechr, statechr, vname);
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate /* ARGSUSED */
3367c478bd9Sstevel@tonic-gate static int
logbuf(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3377c478bd9Sstevel@tonic-gate logbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3387c478bd9Sstevel@tonic-gate {
33956e23938Sbustos 	GElf_Sym sym;
3407c478bd9Sstevel@tonic-gate 	char *buf;
3417c478bd9Sstevel@tonic-gate 	char *cp;
3427c478bd9Sstevel@tonic-gate 
34356e23938Sbustos 	if (mdb_lookup_by_name("logbuf", &sym) == -1) {
34456e23938Sbustos 		mdb_warn("The 'logbuf' symbol is missing.\n");
3457c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate 
34856e23938Sbustos 	buf = mdb_alloc(sym.st_size, UM_SLEEP | UM_GC);
3497c478bd9Sstevel@tonic-gate 
35056e23938Sbustos 	if (mdb_vread(buf, sym.st_size, sym.st_value) == -1) {
3517c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read 'logbuf'\n");
3527c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
3537c478bd9Sstevel@tonic-gate 	}
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	cp = strchr(buf, '\0');
3567c478bd9Sstevel@tonic-gate 
3577c478bd9Sstevel@tonic-gate 	if (cp == buf)
3587c478bd9Sstevel@tonic-gate 		/* Empty */
3597c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
3607c478bd9Sstevel@tonic-gate 
36156e23938Sbustos 	if (cp >= buf + sym.st_size ||
36256e23938Sbustos 	    strchr(cp + 1, '\0') >= buf + sym.st_size) {
3637c478bd9Sstevel@tonic-gate 		mdb_warn("'logbuf' is corrupt\n");
3647c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
3657c478bd9Sstevel@tonic-gate 	}
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	mdb_printf("%s", cp + 1);
3687c478bd9Sstevel@tonic-gate 	mdb_printf("%s", buf);
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
3747c478bd9Sstevel@tonic-gate 	{ "instance", NULL, "display svc.startd restarter instance",
3757c478bd9Sstevel@tonic-gate 	    pr_instance },
3767c478bd9Sstevel@tonic-gate 	{ "startd_log", NULL, "display svc.startd debug message buffer",
3777c478bd9Sstevel@tonic-gate 	    logbuf },
3787c478bd9Sstevel@tonic-gate 	{ "startd_status", NULL, "svc.startd status summary", startd_status },
3797c478bd9Sstevel@tonic-gate 	{ "vertex", NULL, "display svc.startd dependency graph vertex",
3807c478bd9Sstevel@tonic-gate 	    pr_vertex },
3817c478bd9Sstevel@tonic-gate 	{ NULL }
3827c478bd9Sstevel@tonic-gate };
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
3857c478bd9Sstevel@tonic-gate 	{ NULL }
3867c478bd9Sstevel@tonic-gate };
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = {
3897c478bd9Sstevel@tonic-gate 	MDB_API_VERSION, dcmds, walkers
3907c478bd9Sstevel@tonic-gate };
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)3937c478bd9Sstevel@tonic-gate _mdb_init(void)
3947c478bd9Sstevel@tonic-gate {
3957c478bd9Sstevel@tonic-gate 	return (&modinfo);
3967c478bd9Sstevel@tonic-gate }
397