10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*8452SJohn.Wren.Kennedy@Sun.COM * Common Development and Distribution License (the "License").
6*8452SJohn.Wren.Kennedy@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*8452SJohn.Wren.Kennedy@Sun.COM
220Sstevel@tonic-gate /*
23*8452SJohn.Wren.Kennedy@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include "mdinclude.h"
280Sstevel@tonic-gate
290Sstevel@tonic-gate typedef struct submirror_cb {
300Sstevel@tonic-gate minor_t un_self_id;
310Sstevel@tonic-gate int un_nsm;
320Sstevel@tonic-gate ushort_t mm_un_nsm;
330Sstevel@tonic-gate }submirror_cb_t;
340Sstevel@tonic-gate
350Sstevel@tonic-gate void
print_setname(int setno)360Sstevel@tonic-gate print_setname(int setno)
370Sstevel@tonic-gate {
380Sstevel@tonic-gate char setname[1024];
390Sstevel@tonic-gate
400Sstevel@tonic-gate if (setno != 0) {
410Sstevel@tonic-gate if (mdb_readstr(setname, 1024,
420Sstevel@tonic-gate (uintptr_t)set_dbs[setno].s_setname) == -1) {
430Sstevel@tonic-gate mdb_warn("failed to read setname at 0x%p\n",
440Sstevel@tonic-gate set_dbs[setno].s_setname);
450Sstevel@tonic-gate }
460Sstevel@tonic-gate mdb_printf("%s/", setname);
470Sstevel@tonic-gate }
480Sstevel@tonic-gate }
490Sstevel@tonic-gate
500Sstevel@tonic-gate void
print_stripe(void * un_addr,void * mdcptr,uint_t verbose)510Sstevel@tonic-gate print_stripe(void *un_addr, void *mdcptr, uint_t verbose)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate ms_unit_t ms;
540Sstevel@tonic-gate int setno;
550Sstevel@tonic-gate minor_t un_self_id;
560Sstevel@tonic-gate md_parent_t un_parent;
570Sstevel@tonic-gate diskaddr_t un_total_blocks;
580Sstevel@tonic-gate
590Sstevel@tonic-gate /* read in the device */
600Sstevel@tonic-gate un_self_id = ((mdc_unit_t *)mdcptr)->un_self_id;
610Sstevel@tonic-gate un_parent = ((mdc_unit_t *)mdcptr)->un_parent;
620Sstevel@tonic-gate un_total_blocks = ((mdc_unit_t *)mdcptr)->un_total_blocks;
630Sstevel@tonic-gate if (mdb_vread(&ms, sizeof (ms_unit_t),
640Sstevel@tonic-gate (uintptr_t)un_addr) == -1) {
650Sstevel@tonic-gate mdb_warn("failed to read ms_unit_t at %p\n", un_addr);
660Sstevel@tonic-gate return;
670Sstevel@tonic-gate }
680Sstevel@tonic-gate
690Sstevel@tonic-gate setno = MD_MIN2SET(un_self_id);
700Sstevel@tonic-gate print_setname(setno);
710Sstevel@tonic-gate
720Sstevel@tonic-gate mdb_printf("d%u: ", MD_MIN2UNIT(un_self_id));
730Sstevel@tonic-gate if (un_parent == ((unit_t)-1)) {
740Sstevel@tonic-gate mdb_printf("Concat/Stripe");
750Sstevel@tonic-gate } else {
760Sstevel@tonic-gate mdb_printf("Subdevice of d%u", MD_MIN2UNIT(un_parent));
770Sstevel@tonic-gate }
780Sstevel@tonic-gate if (verbose) {
790Sstevel@tonic-gate mdb_printf("\t< %p::print ms_unit_t >\n", un_addr);
800Sstevel@tonic-gate } else {
810Sstevel@tonic-gate mdb_printf("\t< %p>\n", un_addr);
820Sstevel@tonic-gate }
830Sstevel@tonic-gate mdb_inc_indent(2);
840Sstevel@tonic-gate mdb_printf("Size: %llu blocks\n", un_total_blocks);
850Sstevel@tonic-gate mdb_printf("Rows: %u\n", ms.un_nrows);
860Sstevel@tonic-gate mdb_dec_indent(2);
870Sstevel@tonic-gate }
880Sstevel@tonic-gate
890Sstevel@tonic-gate /* ARGSUSED */
900Sstevel@tonic-gate int
print_submirror(uintptr_t addr,void * arg,submirror_cb_t * data)910Sstevel@tonic-gate print_submirror(uintptr_t addr, void *arg, submirror_cb_t *data)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate uintptr_t un_addr;
940Sstevel@tonic-gate mdc_unit_t mdc_sm;
950Sstevel@tonic-gate
960Sstevel@tonic-gate if (mdb_vread(&un_addr, sizeof (void *), addr) == -1) {
970Sstevel@tonic-gate mdb_warn("failed to read submirror at %p\n", addr);
980Sstevel@tonic-gate return (WALK_ERR);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate if (un_addr != NULL) {
1010Sstevel@tonic-gate if (mdb_vread(&mdc_sm, sizeof (mdc_unit_t), un_addr) == -1) {
1020Sstevel@tonic-gate mdb_warn("failed to read mdc_unit_t at %p", un_addr);
1030Sstevel@tonic-gate return (WALK_ERR);
1040Sstevel@tonic-gate }
1050Sstevel@tonic-gate if (mdc_sm.un_parent == data->un_self_id) {
1060Sstevel@tonic-gate /* this is one of the sub mirrors */
1070Sstevel@tonic-gate mdb_printf("Submirror %u: d%u ",
1080Sstevel@tonic-gate data->un_nsm, MD_MIN2UNIT(mdc_sm.un_self_id));
1090Sstevel@tonic-gate mdb_printf("Size: %llu\n", mdc_sm.un_total_blocks);
1100Sstevel@tonic-gate data->un_nsm++;
1110Sstevel@tonic-gate if (data->un_nsm == data->mm_un_nsm)
1120Sstevel@tonic-gate return (WALK_DONE);
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate return (WALK_NEXT);
1160Sstevel@tonic-gate }
1170Sstevel@tonic-gate
118*8452SJohn.Wren.Kennedy@Sun.COM /*
119*8452SJohn.Wren.Kennedy@Sun.COM * Construct an RLE count for the number of 'cleared' bits in the given 'bm'
120*8452SJohn.Wren.Kennedy@Sun.COM * Output the RLE count in form: [<set>.<cleared>.<set>.<cleared>...]
121*8452SJohn.Wren.Kennedy@Sun.COM * RLE is Run Length Encoding, a method for compactly describing a bitmap
122*8452SJohn.Wren.Kennedy@Sun.COM * as a series of numbers indicating the count of consecutive set or cleared
123*8452SJohn.Wren.Kennedy@Sun.COM * bits.
124*8452SJohn.Wren.Kennedy@Sun.COM *
125*8452SJohn.Wren.Kennedy@Sun.COM * Input:
126*8452SJohn.Wren.Kennedy@Sun.COM * <bm> bitmap to scan
127*8452SJohn.Wren.Kennedy@Sun.COM * <size> length of bitmap (in bits)
128*8452SJohn.Wren.Kennedy@Sun.COM * <comp_bm> RLE count array to be updated
129*8452SJohn.Wren.Kennedy@Sun.COM * <opstr> Descriptive text for bitmap RLE count display
130*8452SJohn.Wren.Kennedy@Sun.COM */
131*8452SJohn.Wren.Kennedy@Sun.COM static void
print_comp_bm(unsigned char * bm,uint_t size,ushort_t * comp_bm,char * opstr)132*8452SJohn.Wren.Kennedy@Sun.COM print_comp_bm(unsigned char *bm, uint_t size, ushort_t *comp_bm, char *opstr)
133*8452SJohn.Wren.Kennedy@Sun.COM {
134*8452SJohn.Wren.Kennedy@Sun.COM int cnt_clean, tot_dirty, cur_idx;
135*8452SJohn.Wren.Kennedy@Sun.COM int i, cur_clean, cur_dirty, printit, max_set_cnt, max_reset_cnt;
136*8452SJohn.Wren.Kennedy@Sun.COM
137*8452SJohn.Wren.Kennedy@Sun.COM cnt_clean = 1;
138*8452SJohn.Wren.Kennedy@Sun.COM printit = 0;
139*8452SJohn.Wren.Kennedy@Sun.COM cur_clean = 0;
140*8452SJohn.Wren.Kennedy@Sun.COM cur_dirty = 0;
141*8452SJohn.Wren.Kennedy@Sun.COM cur_idx = 0;
142*8452SJohn.Wren.Kennedy@Sun.COM tot_dirty = 0;
143*8452SJohn.Wren.Kennedy@Sun.COM max_set_cnt = max_reset_cnt = 0;
144*8452SJohn.Wren.Kennedy@Sun.COM for (i = 0; i < size; i++) {
145*8452SJohn.Wren.Kennedy@Sun.COM if (isset(bm, i)) {
146*8452SJohn.Wren.Kennedy@Sun.COM /* If we're counting clean bits, flush the count out */
147*8452SJohn.Wren.Kennedy@Sun.COM if (cnt_clean) {
148*8452SJohn.Wren.Kennedy@Sun.COM cnt_clean = 0;
149*8452SJohn.Wren.Kennedy@Sun.COM comp_bm[cur_idx] = cur_clean;
150*8452SJohn.Wren.Kennedy@Sun.COM printit = 1;
151*8452SJohn.Wren.Kennedy@Sun.COM if (cur_clean > max_reset_cnt) {
152*8452SJohn.Wren.Kennedy@Sun.COM max_reset_cnt = cur_clean;
153*8452SJohn.Wren.Kennedy@Sun.COM }
154*8452SJohn.Wren.Kennedy@Sun.COM }
155*8452SJohn.Wren.Kennedy@Sun.COM cur_clean = 0;
156*8452SJohn.Wren.Kennedy@Sun.COM cur_dirty++;
157*8452SJohn.Wren.Kennedy@Sun.COM tot_dirty++;
158*8452SJohn.Wren.Kennedy@Sun.COM } else {
159*8452SJohn.Wren.Kennedy@Sun.COM if (!cnt_clean) {
160*8452SJohn.Wren.Kennedy@Sun.COM cnt_clean = 1;
161*8452SJohn.Wren.Kennedy@Sun.COM comp_bm[cur_idx] = cur_dirty;
162*8452SJohn.Wren.Kennedy@Sun.COM printit = 1;
163*8452SJohn.Wren.Kennedy@Sun.COM if (cur_dirty > max_set_cnt) {
164*8452SJohn.Wren.Kennedy@Sun.COM max_set_cnt = cur_dirty;
165*8452SJohn.Wren.Kennedy@Sun.COM }
166*8452SJohn.Wren.Kennedy@Sun.COM }
167*8452SJohn.Wren.Kennedy@Sun.COM cur_dirty = 0;
168*8452SJohn.Wren.Kennedy@Sun.COM cur_clean++;
169*8452SJohn.Wren.Kennedy@Sun.COM }
170*8452SJohn.Wren.Kennedy@Sun.COM if (printit) {
171*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("%u.", comp_bm[cur_idx++]);
172*8452SJohn.Wren.Kennedy@Sun.COM printit = 0;
173*8452SJohn.Wren.Kennedy@Sun.COM }
174*8452SJohn.Wren.Kennedy@Sun.COM }
175*8452SJohn.Wren.Kennedy@Sun.COM
176*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("\nTotal %s bits = %lu\n", opstr, tot_dirty);
177*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("Total %s transactions = %lu\n", opstr, cur_idx);
178*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("Maximum %s set count = %lu, reset count = %lu\n", opstr,
179*8452SJohn.Wren.Kennedy@Sun.COM max_set_cnt, max_reset_cnt);
180*8452SJohn.Wren.Kennedy@Sun.COM }
181*8452SJohn.Wren.Kennedy@Sun.COM
1820Sstevel@tonic-gate void
print_mirror(void * un_addr,void * mdcptr,uint_t verbose)1830Sstevel@tonic-gate print_mirror(void *un_addr, void *mdcptr, uint_t verbose)
1840Sstevel@tonic-gate {
185*8452SJohn.Wren.Kennedy@Sun.COM mm_unit_t mm, *mmp;
1860Sstevel@tonic-gate void **ptr;
1870Sstevel@tonic-gate int setno = 0;
1880Sstevel@tonic-gate minor_t un_self_id;
1890Sstevel@tonic-gate diskaddr_t un_total_blocks;
1900Sstevel@tonic-gate ushort_t mm_un_nsm;
1910Sstevel@tonic-gate submirror_cb_t data;
192*8452SJohn.Wren.Kennedy@Sun.COM uint_t num_rr, rr_blksize;
193*8452SJohn.Wren.Kennedy@Sun.COM ushort_t *comp_rr;
194*8452SJohn.Wren.Kennedy@Sun.COM unsigned char *rr_dirty_bm, *rr_goingclean_bm;
195*8452SJohn.Wren.Kennedy@Sun.COM uintptr_t un_dbm, un_gcbm;
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate /* read in the device */
1980Sstevel@tonic-gate if (mdb_vread(&mm, sizeof (mm_unit_t),
1990Sstevel@tonic-gate (uintptr_t)un_addr) == -1) {
2000Sstevel@tonic-gate mdb_warn("failed to read mm_unit_t at %p\n", un_addr);
2010Sstevel@tonic-gate return;
2020Sstevel@tonic-gate }
203*8452SJohn.Wren.Kennedy@Sun.COM
204*8452SJohn.Wren.Kennedy@Sun.COM mmp = &mm;
205*8452SJohn.Wren.Kennedy@Sun.COM
2060Sstevel@tonic-gate un_self_id = ((mdc_unit_t *)mdcptr)->un_self_id;
2070Sstevel@tonic-gate un_total_blocks = ((mdc_unit_t *)mdcptr)->un_total_blocks;
2080Sstevel@tonic-gate mm_un_nsm = mm.un_nsm;
2090Sstevel@tonic-gate setno = MD_MIN2SET(un_self_id);
2100Sstevel@tonic-gate print_setname(setno);
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate mdb_printf("d%u: Mirror", MD_MIN2UNIT(un_self_id));
2130Sstevel@tonic-gate if (verbose) {
2140Sstevel@tonic-gate mdb_printf("\t< %p::print mm_unit_t >\n", un_addr);
2150Sstevel@tonic-gate } else {
2160Sstevel@tonic-gate mdb_printf("\t< %p >\n", un_addr);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate mdb_inc_indent(2);
2190Sstevel@tonic-gate mdb_printf("Size: %llu blocks\n", un_total_blocks);
220*8452SJohn.Wren.Kennedy@Sun.COM
221*8452SJohn.Wren.Kennedy@Sun.COM /*
222*8452SJohn.Wren.Kennedy@Sun.COM * Dump out the current un_dirty_bm together with its size
223*8452SJohn.Wren.Kennedy@Sun.COM * Also, attempt to Run Length encode the bitmap to see if this
224*8452SJohn.Wren.Kennedy@Sun.COM * is a viable option
225*8452SJohn.Wren.Kennedy@Sun.COM */
226*8452SJohn.Wren.Kennedy@Sun.COM num_rr = mm.un_rrd_num;
227*8452SJohn.Wren.Kennedy@Sun.COM rr_blksize = mm.un_rrd_blksize;
228*8452SJohn.Wren.Kennedy@Sun.COM
229*8452SJohn.Wren.Kennedy@Sun.COM un_dbm = (uintptr_t)mmp->un_dirty_bm;
230*8452SJohn.Wren.Kennedy@Sun.COM un_gcbm = (uintptr_t)mmp->un_goingclean_bm;
231*8452SJohn.Wren.Kennedy@Sun.COM
232*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("RR size: %lu bits\n", num_rr);
233*8452SJohn.Wren.Kennedy@Sun.COM mdb_printf("RR block size: %lu blocks\n", rr_blksize);
234*8452SJohn.Wren.Kennedy@Sun.COM
235*8452SJohn.Wren.Kennedy@Sun.COM rr_dirty_bm = (unsigned char *)mdb_alloc(num_rr, UM_SLEEP|UM_GC);
236*8452SJohn.Wren.Kennedy@Sun.COM rr_goingclean_bm = (unsigned char *)mdb_alloc(num_rr, UM_SLEEP|UM_GC);
237*8452SJohn.Wren.Kennedy@Sun.COM comp_rr = (ushort_t *)mdb_alloc(num_rr * sizeof (ushort_t),
238*8452SJohn.Wren.Kennedy@Sun.COM UM_SLEEP|UM_GC);
239*8452SJohn.Wren.Kennedy@Sun.COM
240*8452SJohn.Wren.Kennedy@Sun.COM if (mdb_vread(rr_dirty_bm, num_rr, un_dbm) == -1) {
241*8452SJohn.Wren.Kennedy@Sun.COM mdb_warn("failed to read un_dirty_bm at %p\n", un_dbm);
242*8452SJohn.Wren.Kennedy@Sun.COM return;
243*8452SJohn.Wren.Kennedy@Sun.COM }
244*8452SJohn.Wren.Kennedy@Sun.COM if (mdb_vread(rr_goingclean_bm, num_rr, un_gcbm) == -1) {
245*8452SJohn.Wren.Kennedy@Sun.COM mdb_warn("failed to read un_goingclean_bm at %p\n", un_gcbm);
246*8452SJohn.Wren.Kennedy@Sun.COM return;
247*8452SJohn.Wren.Kennedy@Sun.COM }
248*8452SJohn.Wren.Kennedy@Sun.COM
249*8452SJohn.Wren.Kennedy@Sun.COM print_comp_bm(rr_dirty_bm, num_rr, comp_rr, "dirty");
250*8452SJohn.Wren.Kennedy@Sun.COM
251*8452SJohn.Wren.Kennedy@Sun.COM print_comp_bm(rr_goingclean_bm, num_rr, comp_rr, "clean");
252*8452SJohn.Wren.Kennedy@Sun.COM
2530Sstevel@tonic-gate /*
2540Sstevel@tonic-gate * find the sub mirrors, search through each metadevice looking
2550Sstevel@tonic-gate * at the un_parent.
2560Sstevel@tonic-gate */
2570Sstevel@tonic-gate ptr = mdset[setno].s_un;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate data.un_self_id = un_self_id;
2600Sstevel@tonic-gate data.un_nsm = 0;
2610Sstevel@tonic-gate data.mm_un_nsm = mm_un_nsm;
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate if (mdb_pwalk("md_units", (mdb_walk_cb_t)print_submirror, &data,
2640Sstevel@tonic-gate (uintptr_t)ptr) == -1) {
2650Sstevel@tonic-gate mdb_warn("unable to walk units\n");
2660Sstevel@tonic-gate return;
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate mdb_dec_indent(2);
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate void
print_raid(void * un_addr,void * mdcptr,uint_t verbose)2730Sstevel@tonic-gate print_raid(void *un_addr, void *mdcptr, uint_t verbose)
2740Sstevel@tonic-gate {
2750Sstevel@tonic-gate mr_unit_t mr;
2760Sstevel@tonic-gate minor_t un_self_id;
2770Sstevel@tonic-gate diskaddr_t un_total_blocks;
2780Sstevel@tonic-gate mdc_unit_t mdc_sc;
2790Sstevel@tonic-gate void **ptr;
2800Sstevel@tonic-gate void *addr;
2810Sstevel@tonic-gate int setno = 0;
2820Sstevel@tonic-gate int i;
2830Sstevel@tonic-gate minor_t sc_un_self_id;
2840Sstevel@tonic-gate md_parent_t sc_parent;
2850Sstevel@tonic-gate diskaddr_t sc_total_blocks;
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate /* read in the device */
2880Sstevel@tonic-gate if (mdb_vread(&mr, sizeof (mr_unit_t), (uintptr_t)un_addr) == -1) {
2890Sstevel@tonic-gate mdb_warn("failed to read mr_unit_t at %p\n", un_addr);
2900Sstevel@tonic-gate return;
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate un_self_id = ((mdc_unit_t *)mdcptr)->un_self_id;
2930Sstevel@tonic-gate un_total_blocks = ((mdc_unit_t *)mdcptr)->un_total_blocks;
2940Sstevel@tonic-gate setno = MD_MIN2SET(un_self_id);
2950Sstevel@tonic-gate print_setname(setno);
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate mdb_printf("d%u: Raid", MD_MIN2UNIT(un_self_id));
2980Sstevel@tonic-gate if (verbose) {
2990Sstevel@tonic-gate mdb_printf("\t< %p ::print mr_unit_t>\n", un_addr);
3000Sstevel@tonic-gate } else {
3010Sstevel@tonic-gate mdb_printf("\t< %p >\n", un_addr);
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate mdb_inc_indent(2);
3040Sstevel@tonic-gate mdb_printf("Size: %llu\n", un_total_blocks);
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate /*
3070Sstevel@tonic-gate * find the sub components if any, search through each metadevice
3080Sstevel@tonic-gate * looking at the un_parent.
3090Sstevel@tonic-gate */
3100Sstevel@tonic-gate ptr = mdset[setno].s_un;
3110Sstevel@tonic-gate for (i = 0; i < md_nunits; i++, ptr++) {
3120Sstevel@tonic-gate if (mdb_vread(&addr, sizeof (void *), (uintptr_t)ptr) == -1) {
3130Sstevel@tonic-gate mdb_warn("failed to read addr at %p\n", ptr);
3140Sstevel@tonic-gate continue;
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate if (addr != NULL) {
3170Sstevel@tonic-gate if (mdb_vread(&mdc_sc, sizeof (mdc_unit_t),
3180Sstevel@tonic-gate (uintptr_t)addr) == -1) {
3190Sstevel@tonic-gate mdb_warn("failed to read mdc_unit_t at %p",
3200Sstevel@tonic-gate un_addr);
3210Sstevel@tonic-gate continue;
3220Sstevel@tonic-gate }
3230Sstevel@tonic-gate sc_parent = mdc_sc.un_parent;
3240Sstevel@tonic-gate sc_un_self_id = mdc_sc.un_self_id;
3250Sstevel@tonic-gate sc_total_blocks = mdc_sc.un_total_blocks;
3260Sstevel@tonic-gate if (sc_parent == un_self_id) {
3270Sstevel@tonic-gate /* this is one of the sub components */
3280Sstevel@tonic-gate mdb_printf("Subdevice %u ",
3290Sstevel@tonic-gate MD_MIN2UNIT(sc_un_self_id));
3300Sstevel@tonic-gate mdb_printf("Size: %llu\n", sc_total_blocks);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate mdb_dec_indent(2);
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate void
print_sp(void * un_addr,void * mdcptr,uint_t verbose)3380Sstevel@tonic-gate print_sp(void *un_addr, void *mdcptr, uint_t verbose)
3390Sstevel@tonic-gate {
3400Sstevel@tonic-gate mp_unit_t mp;
3410Sstevel@tonic-gate minor_t un_self_id;
3420Sstevel@tonic-gate diskaddr_t un_total_blocks;
3430Sstevel@tonic-gate int setno = 0;
3440Sstevel@tonic-gate uintptr_t extaddr;
3450Sstevel@tonic-gate int i;
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate /* read in the device */
3480Sstevel@tonic-gate if (mdb_vread(&mp, sizeof (mp_unit_t), (uintptr_t)un_addr) == -1) {
3490Sstevel@tonic-gate mdb_warn("failed to read mp_unit_t at %p\n", un_addr);
3500Sstevel@tonic-gate return;
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate un_self_id = ((mdc_unit_t *)mdcptr)->un_self_id;
3530Sstevel@tonic-gate un_total_blocks = ((mdc_unit_t *)mdcptr)->un_total_blocks;
3540Sstevel@tonic-gate setno = MD_MIN2SET(un_self_id);
3550Sstevel@tonic-gate print_setname(setno);
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate mdb_printf("d%u: Soft Partition", MD_MIN2UNIT(un_self_id));
3580Sstevel@tonic-gate if (verbose) {
3590Sstevel@tonic-gate mdb_printf("\t< %p ::print mp_unit_t >\n", un_addr);
3600Sstevel@tonic-gate } else {
3610Sstevel@tonic-gate mdb_printf("\t< %p >\n", un_addr);
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate mdb_inc_indent(2);
3640Sstevel@tonic-gate mdb_printf("Size: %llu\n", un_total_blocks);
3650Sstevel@tonic-gate mdb_inc_indent(2);
3660Sstevel@tonic-gate mdb_printf("Extent\tStart Block\tBlock count\n");
3670Sstevel@tonic-gate extaddr = (uintptr_t)un_addr + sizeof (mp_unit_t) - sizeof (mp_ext_t);
3680Sstevel@tonic-gate for (i = 0; i < mp.un_numexts; i++) {
3690Sstevel@tonic-gate mp_ext_t mpext;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate if (mdb_vread(&mpext, sizeof (mp_ext_t), extaddr) == -1) {
3720Sstevel@tonic-gate mdb_warn("failed to read mp_ext_t at %p\n", extaddr);
3730Sstevel@tonic-gate return;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate mdb_printf(" %d \t %llu\t %llu\n",
3760Sstevel@tonic-gate i, mpext.un_poff, mpext.un_len);
3770Sstevel@tonic-gate extaddr += sizeof (mp_ext_t);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate mdb_dec_indent(2);
3800Sstevel@tonic-gate mdb_dec_indent(2);
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate void
print_trans(void * un_addr,void * mdcptr,uint_t verbose)3850Sstevel@tonic-gate print_trans(void *un_addr, void *mdcptr, uint_t verbose)
3860Sstevel@tonic-gate {
3870Sstevel@tonic-gate mt_unit_t mt;
3880Sstevel@tonic-gate minor_t un_self_id;
3890Sstevel@tonic-gate int setno = 0;
3900Sstevel@tonic-gate
3910Sstevel@tonic-gate /* read in the device */
3920Sstevel@tonic-gate if (mdb_vread(&mt, sizeof (mt_unit_t), (uintptr_t)un_addr) == -1) {
3930Sstevel@tonic-gate mdb_warn("failed to read mt_unit_t at %p\n", un_addr);
3940Sstevel@tonic-gate return;
3950Sstevel@tonic-gate }
3960Sstevel@tonic-gate un_self_id = ((mdc_unit32_od_t *)mdcptr)->un_self_id;
3970Sstevel@tonic-gate setno = MD_MIN2SET(un_self_id);
3980Sstevel@tonic-gate print_setname(setno);
3990Sstevel@tonic-gate
4000Sstevel@tonic-gate mdb_printf("d%u: Trans", MD_MIN2UNIT(un_self_id));
4010Sstevel@tonic-gate if (verbose) {
4020Sstevel@tonic-gate mdb_printf("\t< %p ::print mt_unit_t>\n", un_addr);
4030Sstevel@tonic-gate } else {
4040Sstevel@tonic-gate mdb_printf("\t< %p >\n", un_addr);
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate void
print_device(void * un_addr,void * mdcptr,uint_t verbose)4100Sstevel@tonic-gate print_device(void *un_addr, void *mdcptr, uint_t verbose)
4110Sstevel@tonic-gate {
4120Sstevel@tonic-gate u_longlong_t un_type;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate un_type = ((mdc_unit_t *)mdcptr)->un_type;
4150Sstevel@tonic-gate
4160Sstevel@tonic-gate switch (un_type) {
4170Sstevel@tonic-gate case MD_DEVICE: /* stripe/concat */
4180Sstevel@tonic-gate print_stripe(un_addr, mdcptr, verbose);
4190Sstevel@tonic-gate break;
4200Sstevel@tonic-gate case MD_METAMIRROR:
4210Sstevel@tonic-gate print_mirror(un_addr, mdcptr, verbose);
4220Sstevel@tonic-gate break;
4230Sstevel@tonic-gate case MD_METATRANS:
4240Sstevel@tonic-gate print_trans(un_addr, mdcptr, verbose);
4250Sstevel@tonic-gate break;
4260Sstevel@tonic-gate case MD_METARAID:
4270Sstevel@tonic-gate print_raid(un_addr, mdcptr, verbose);
4280Sstevel@tonic-gate break;
4290Sstevel@tonic-gate case MD_METASP:
4300Sstevel@tonic-gate print_sp(un_addr, mdcptr, verbose);
4310Sstevel@tonic-gate break;
4320Sstevel@tonic-gate case MD_UNDEFINED:
4330Sstevel@tonic-gate mdb_warn("undefined metadevice at %p\n", un_addr);
4340Sstevel@tonic-gate break;
4350Sstevel@tonic-gate default:
4360Sstevel@tonic-gate mdb_warn("invalid metadevice at %p\n", un_addr);
4370Sstevel@tonic-gate break;
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate
4410Sstevel@tonic-gate /* ARGSUSED */
4420Sstevel@tonic-gate /*
4430Sstevel@tonic-gate * usage: ::metastat [-v]
4440Sstevel@tonic-gate */
4450Sstevel@tonic-gate int
metastat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4460Sstevel@tonic-gate metastat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4470Sstevel@tonic-gate {
4480Sstevel@tonic-gate mdc_unit_t mdc;
4490Sstevel@tonic-gate uintptr_t un_addr;
4500Sstevel@tonic-gate uint_t verbose = FALSE;
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate snarf_sets();
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL)
4550Sstevel@tonic-gate != argc) {
4560Sstevel@tonic-gate return (DCMD_USAGE);
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
4600Sstevel@tonic-gate if (mdb_walk_dcmd("md_units", "metastat", argc,
4610Sstevel@tonic-gate argv) == -1) {
4620Sstevel@tonic-gate mdb_warn("failed to walk units");
4630Sstevel@tonic-gate return (DCMD_ERR);
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate return (DCMD_OK);
4660Sstevel@tonic-gate }
4670Sstevel@tonic-gate if (!(flags & DCMD_LOOP)) {
4680Sstevel@tonic-gate /* user passed set addr */
4690Sstevel@tonic-gate if (mdb_pwalk_dcmd("md_units", "metastat", argc,
4700Sstevel@tonic-gate argv, addr) == -1) {
4710Sstevel@tonic-gate mdb_warn("failed to walk units");
4720Sstevel@tonic-gate return (DCMD_ERR);
4730Sstevel@tonic-gate }
4740Sstevel@tonic-gate return (DCMD_OK);
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate if (mdb_vread(&un_addr, sizeof (void *), addr) == -1) {
4780Sstevel@tonic-gate mdb_warn("failed to read un_addr at %p", addr);
4790Sstevel@tonic-gate return (DCMD_ERR);
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate if (un_addr != NULL) {
4830Sstevel@tonic-gate if (mdb_vread(&mdc, sizeof (mdc_unit_t), un_addr) == -1) {
4840Sstevel@tonic-gate mdb_warn("failed to read mdc_unit_t at %p", un_addr);
4850Sstevel@tonic-gate return (DCMD_ERR);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate print_device((void *)un_addr, (void *)&mdc, verbose);
4880Sstevel@tonic-gate mdb_dec_indent(2);
4890Sstevel@tonic-gate }
4900Sstevel@tonic-gate return (DCMD_OK);
4910Sstevel@tonic-gate }
492