1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include "mdinclude.h"
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate /* array of the sets */
32*0Sstevel@tonic-gate md_set_t mdset[MD_MAXSETS];
33*0Sstevel@tonic-gate mddb_set_t set_dbs[MD_MAXSETS];
34*0Sstevel@tonic-gate /* for the addresses of each set above */
35*0Sstevel@tonic-gate uintptr_t mdset_addrs[MD_MAXSETS];
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate unit_t md_nunits = 0;
38*0Sstevel@tonic-gate set_t md_nsets = 0;
39*0Sstevel@tonic-gate int snarfed = 0;
40*0Sstevel@tonic-gate int active_sets = 0;
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate /*
43*0Sstevel@tonic-gate * routines to snarf the metaset information
44*0Sstevel@tonic-gate *
45*0Sstevel@tonic-gate * usage: ::dumpsetaddr [-s setname]
46*0Sstevel@tonic-gate */
47*0Sstevel@tonic-gate /* ARGSUSED */
48*0Sstevel@tonic-gate int
dumpsetaddr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)49*0Sstevel@tonic-gate dumpsetaddr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
50*0Sstevel@tonic-gate {
51*0Sstevel@tonic-gate int i;
52*0Sstevel@tonic-gate int setno;
53*0Sstevel@tonic-gate char *s_opt = (char *)NULL;
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate if (mdb_getopts(argc, argv, 's', MDB_OPT_STR, &s_opt,
56*0Sstevel@tonic-gate NULL) != argc) {
57*0Sstevel@tonic-gate /* left over arguments ?? */
58*0Sstevel@tonic-gate return (DCMD_USAGE);
59*0Sstevel@tonic-gate }
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gate if (!snarfed) {
62*0Sstevel@tonic-gate mdb_warn("No sets read in yet - try ::metaset\n");
63*0Sstevel@tonic-gate return (DCMD_ERR);
64*0Sstevel@tonic-gate }
65*0Sstevel@tonic-gate if (argc == 0) { /* dump all sets */
66*0Sstevel@tonic-gate for (i = 0; i < md_nsets; i++) {
67*0Sstevel@tonic-gate if (mdset_addrs[i] != (uintptr_t)0)
68*0Sstevel@tonic-gate mdb_printf("%d %p\n", i, mdset_addrs[i]);
69*0Sstevel@tonic-gate }
70*0Sstevel@tonic-gate } else {
71*0Sstevel@tonic-gate setno = findset(s_opt);
72*0Sstevel@tonic-gate if (setno == -1) {
73*0Sstevel@tonic-gate mdb_warn("no such set: %s\n", s_opt);
74*0Sstevel@tonic-gate return (DCMD_ERR);
75*0Sstevel@tonic-gate }
76*0Sstevel@tonic-gate if (mdset_addrs[setno] != (uintptr_t)0)
77*0Sstevel@tonic-gate mdb_printf("%d %p\n", setno,
78*0Sstevel@tonic-gate mdset_addrs[setno]);
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate return (DCMD_OK);
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate
84*0Sstevel@tonic-gate /*
85*0Sstevel@tonic-gate * Function: snarf_ui_anchor
86*0Sstevel@tonic-gate * Purpose: to read in the s_ui part of a metaset.
87*0Sstevel@tonic-gate * Returns: <n> - number of configured metadevices
88*0Sstevel@tonic-gate * -1 - not configured
89*0Sstevel@tonic-gate */
90*0Sstevel@tonic-gate int
snarf_ui_anchor(int i)91*0Sstevel@tonic-gate snarf_ui_anchor(int i)
92*0Sstevel@tonic-gate {
93*0Sstevel@tonic-gate int j;
94*0Sstevel@tonic-gate int num_found = 0;
95*0Sstevel@tonic-gate void **ptr = mdset[i].s_ui;
96*0Sstevel@tonic-gate void *addr;
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate for (j = 0; j < md_nunits; j++) {
99*0Sstevel@tonic-gate if (mdb_vread(&addr, sizeof (void *), (uintptr_t)ptr) == -1) {
100*0Sstevel@tonic-gate ptr++;
101*0Sstevel@tonic-gate continue;
102*0Sstevel@tonic-gate }
103*0Sstevel@tonic-gate if (addr != NULL) {
104*0Sstevel@tonic-gate num_found++;
105*0Sstevel@tonic-gate }
106*0Sstevel@tonic-gate ptr++;
107*0Sstevel@tonic-gate }
108*0Sstevel@tonic-gate return (num_found);
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate /*
112*0Sstevel@tonic-gate * Function: snarf_sets
113*0Sstevel@tonic-gate * Purpose: Entry point into the module that reads the kernel's version
114*0Sstevel@tonic-gate * of the SVM configuration.
115*0Sstevel@tonic-gate * First of all populates the mdset array and then for each
116*0Sstevel@tonic-gate * component that makes up an "md_set_t" reads it in, via calls
117*0Sstevel@tonic-gate * to other functions.
118*0Sstevel@tonic-gate */
119*0Sstevel@tonic-gate int
snarf_sets(void)120*0Sstevel@tonic-gate snarf_sets(void)
121*0Sstevel@tonic-gate {
122*0Sstevel@tonic-gate GElf_Sym setsym;
123*0Sstevel@tonic-gate GElf_Sym nmdsym;
124*0Sstevel@tonic-gate GElf_Sym mdsetsym;
125*0Sstevel@tonic-gate int i;
126*0Sstevel@tonic-gate size_t offset = 0;
127*0Sstevel@tonic-gate
128*0Sstevel@tonic-gate if (snarfed)
129*0Sstevel@tonic-gate return (DCMD_OK);
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate /* find the SVM hook - md_set */
132*0Sstevel@tonic-gate if (mdb_lookup_by_name("md_set", &setsym) == -1) {
133*0Sstevel@tonic-gate mdb_warn("SVM is not configured on this machine\n");
134*0Sstevel@tonic-gate return (DCMD_ERR);
135*0Sstevel@tonic-gate }
136*0Sstevel@tonic-gate /* find out how many metadevices are configured per set */
137*0Sstevel@tonic-gate if (mdb_lookup_by_name("md_nunits", &nmdsym) == -1) {
138*0Sstevel@tonic-gate mdb_warn("unable to find md_nunits\n");
139*0Sstevel@tonic-gate return (DCMD_ERR);
140*0Sstevel@tonic-gate }
141*0Sstevel@tonic-gate if (mdb_vread(&md_nunits, sizeof (unit_t), nmdsym.st_value) == -1) {
142*0Sstevel@tonic-gate mdb_warn("failed to read md_nunits at %p\n", nmdsym.st_value);
143*0Sstevel@tonic-gate return (DCMD_ERR);
144*0Sstevel@tonic-gate }
145*0Sstevel@tonic-gate
146*0Sstevel@tonic-gate if (mdb_lookup_by_name("md_nsets", &mdsetsym) == -1) {
147*0Sstevel@tonic-gate mdb_warn("unable to find md_nsets\n");
148*0Sstevel@tonic-gate return (DCMD_ERR);
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate if (mdb_vread(&md_nsets, sizeof (set_t), mdsetsym.st_value) == -1) {
151*0Sstevel@tonic-gate mdb_warn("failed to read md_nsets at %p\n", mdsetsym.st_value);
152*0Sstevel@tonic-gate return (DCMD_ERR);
153*0Sstevel@tonic-gate }
154*0Sstevel@tonic-gate
155*0Sstevel@tonic-gate if (md_verbose) {
156*0Sstevel@tonic-gate mdb_printf("mdset array addr: 0x%lx size is: 0x%lx\n",
157*0Sstevel@tonic-gate (uintptr_t)setsym.st_value, sizeof (md_set_t));
158*0Sstevel@tonic-gate }
159*0Sstevel@tonic-gate
160*0Sstevel@tonic-gate offset = setsym.st_value;
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate for (i = 0; i < md_nsets; i++) {
163*0Sstevel@tonic-gate if (mdb_vread(&mdset[i], sizeof (md_set_t), offset) == -1) {
164*0Sstevel@tonic-gate mdb_warn("failed to read md_set_t at 0x%lx\n",
165*0Sstevel@tonic-gate (uintptr_t)(setsym.st_value + offset));
166*0Sstevel@tonic-gate }
167*0Sstevel@tonic-gate /* Should check the status flags */
168*0Sstevel@tonic-gate if (mdset[i].s_status & MD_SET_NM_LOADED) {
169*0Sstevel@tonic-gate if (md_verbose)
170*0Sstevel@tonic-gate mdb_printf("Set %d (0x%lx) has a name space\n",
171*0Sstevel@tonic-gate i, (uintptr_t)(setsym.st_value + offset));
172*0Sstevel@tonic-gate } else {
173*0Sstevel@tonic-gate offset += sizeof (md_set_t);
174*0Sstevel@tonic-gate continue;
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate if (mdb_vread(&set_dbs[i], sizeof (mddb_set_t),
178*0Sstevel@tonic-gate (uintptr_t)mdset[i].s_db) == -1) {
179*0Sstevel@tonic-gate if (mdset[i].s_db != 0) {
180*0Sstevel@tonic-gate mdb_warn("failed to read mddb_set_t at 0x%p\n",
181*0Sstevel@tonic-gate mdset[i].s_db);
182*0Sstevel@tonic-gate return (DCMD_ERR);
183*0Sstevel@tonic-gate } else {
184*0Sstevel@tonic-gate mdb_warn("%d - no set configured\n", i);
185*0Sstevel@tonic-gate return (DCMD_ERR);
186*0Sstevel@tonic-gate }
187*0Sstevel@tonic-gate }
188*0Sstevel@tonic-gate active_sets++;
189*0Sstevel@tonic-gate
190*0Sstevel@tonic-gate mdset_addrs[i] = (uintptr_t)(offset);
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate (void) snarf_ui_anchor(i);
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate /* have the set now read in the various bits and pieces */
195*0Sstevel@tonic-gate offset += sizeof (md_set_t);
196*0Sstevel@tonic-gate }
197*0Sstevel@tonic-gate snarfed = 1;
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate if (md_verbose) {
200*0Sstevel@tonic-gate mdb_printf("Number of active sets: %d\n", active_sets);
201*0Sstevel@tonic-gate mdb_printf("Max number of metadevices: %u\n", md_nunits);
202*0Sstevel@tonic-gate mdb_printf("Max number of sets: %u\n", md_nsets);
203*0Sstevel@tonic-gate }
204*0Sstevel@tonic-gate return (DCMD_OK);
205*0Sstevel@tonic-gate }
206