xref: /titanic_52/usr/src/cmd/mdb/common/modules/ii/ii.c (revision 7014882c6a3672fd0e5d60200af8643ae53c5928)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/mdb_modapi.h>
28 
29 #include <sys/nsctl/nsctl.h>
30 #include <sys/unistat/spcs_s.h>
31 #include <sys/unistat/spcs_s_k.h>
32 
33 
34 #include <sys/nsctl/dsw.h>
35 #include <sys/nsctl/dsw_dev.h>
36 
37 #include <sys/nsctl/nsvers.h>
38 
39 #define	offsetof(s, m)  ((size_t)(&((s *)0)->m))
40 
41 
42 const mdb_bitmask_t bi_flags_bits[] = {
43 	{ "DSW_GOLDEN", DSW_GOLDEN, DSW_GOLDEN },
44 	{ "DSW_COPYINGP", DSW_COPYINGP, DSW_COPYINGP },
45 	{ "DSW_COPYINGM", DSW_COPYINGM, DSW_COPYINGM },
46 	{ "DSW_COPYINGS", DSW_COPYINGS, DSW_COPYINGS },
47 	{ "DSW_COPYINGX", DSW_COPYINGX, DSW_COPYINGX },
48 	{ "DSW_BMPOFFLINE", DSW_BMPOFFLINE, DSW_BMPOFFLINE },
49 	{ "DSW_SHDOFFLINE", DSW_SHDOFFLINE, DSW_SHDOFFLINE },
50 	{ "DSW_MSTOFFLINE", DSW_MSTOFFLINE, DSW_MSTOFFLINE },
51 	{ "DSW_OVROFFLINE", DSW_OVROFFLINE, DSW_OVROFFLINE },
52 	{ "DSW_TREEMAP", DSW_TREEMAP, DSW_TREEMAP },
53 	{ "DSW_OVERFLOW", DSW_OVERFLOW, DSW_OVERFLOW },
54 	{ "DSW_SHDEXPORT", DSW_SHDEXPORT, DSW_SHDEXPORT },
55 	{ "DSW_SHDIMPORT", DSW_SHDIMPORT, DSW_SHDIMPORT },
56 	{ "DSW_VOVERFLOW", DSW_VOVERFLOW, DSW_VOVERFLOW },
57 	{ "DSW_HANGING", DSW_HANGING, DSW_HANGING },
58 	{ "DSW_CFGOFFLINE", DSW_CFGOFFLINE, DSW_CFGOFFLINE },
59 	{ "DSW_OVRHDRDRTY", DSW_OVRHDRDRTY, DSW_OVRHDRDRTY },
60 	{ "DSW_RESIZED", DSW_RESIZED, DSW_RESIZED },
61 	{ "DSW_FRECLAIM", DSW_FRECLAIM, DSW_FRECLAIM },
62 	{ NULL, 0, 0 }
63 };
64 
65 const mdb_bitmask_t bi_state_bits[] = {
66 	{ "DSW_IOCTL", DSW_IOCTL, DSW_IOCTL },
67 	{ "DSW_CLOSING", DSW_CLOSING, DSW_CLOSING },
68 	{ "DSW_MSTTARGET", DSW_MSTTARGET, DSW_MSTTARGET },
69 	{ "DSW_MULTIMST", DSW_MULTIMST, DSW_MULTIMST },
70 	{ NULL, 0, 0 }
71 };
72 static uintptr_t nextaddr;
73 /*
74  * Display a ii_fd_t
75  * Requires an address.
76  */
77 /*ARGSUSED*/
78 static int
79 ii_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
80 {
81 	ii_fd_t fd;
82 
83 	if (!(flags & DCMD_ADDRSPEC))
84 		return (DCMD_USAGE);
85 
86 	if (mdb_vread(&fd, sizeof (fd), addr) != sizeof (fd)) {
87 		mdb_warn("failed to read ii_fd_t at 0x%p", addr);
88 		return (DCMD_ERR);
89 	}
90 
91 	mdb_inc_indent(4);
92 	mdb_printf("ii_info: 0x%p ii_bmp: %d ii_shd: %d ii_ovr: %d ii_optr: "
93 	    "0x%p\nii_oflags: 0x%x\n", fd.ii_info, fd.ii_bmp, fd.ii_shd,
94 	    fd.ii_ovr, fd.ii_optr, fd.ii_oflags);
95 	mdb_dec_indent(4);
96 
97 	return (DCMD_OK);
98 }
99 
100 /*
101  * displays a ii_info_dev structure.
102  */
103 /*ARGSUSED*/
104 static int
105 ii_info_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
106 {
107 	_ii_info_dev_t ipdev;
108 
109 	if (!(flags & DCMD_ADDRSPEC))
110 		return (DCMD_USAGE);
111 
112 	if (mdb_vread(&ipdev, sizeof (ipdev), addr) != sizeof (ipdev)) {
113 		mdb_warn("failed to read ii_info_dev_t at 0x%p", addr);
114 		return (DCMD_ERR);
115 	}
116 
117 	mdb_inc_indent(4);
118 	mdb_printf("bi_fd: 0x%p bi_iodev: 0x%p bi_tok: 0x%p\n",
119 	    ipdev.bi_fd, ipdev.bi_iodev, ipdev.bi_tok);
120 	mdb_printf("bi_ref: %d bi_rsrv: %d bi_orsrv: %d\n",
121 	    ipdev.bi_ref, ipdev.bi_rsrv, ipdev.bi_orsrv);
122 
123 	/*
124 	 * use nsc_fd to dump the fd details.... if present.
125 	 */
126 	if (ipdev.bi_fd) {
127 		mdb_printf("nsc_fd structure:\n");
128 		mdb_inc_indent(4);
129 		mdb_call_dcmd("nsc_fd", (uintptr_t)(ipdev.bi_fd),
130 		    flags, 0, NULL);
131 		mdb_dec_indent(4);
132 	}
133 	mdb_dec_indent(4);
134 	return (DCMD_OK);
135 }
136 
137 /*
138  * Displays an _ii_overflow structure
139  */
140 /*ARGSUSED*/
141 static int
142 ii_overflow(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
143 {
144 	_ii_overflow_t ii_overflow;
145 
146 	nextaddr = 0;
147 	if (!(flags & DCMD_ADDRSPEC))
148 		return (DCMD_USAGE);
149 
150 	if (mdb_vread(&ii_overflow, sizeof (ii_overflow), addr)
151 		!= sizeof (ii_overflow)) {
152 		mdb_warn("failed to read ii_overflow_t at 0x%p", addr);
153 		return (DCMD_ERR);
154 	}
155 
156 	mdb_inc_indent(4);
157 	mdb_printf("_ii_overflow at 0x%p\n", addr);
158 	mdb_printf("_ii_doverflow_t\n");
159 	mdb_inc_indent(4);
160 	mdb_printf("ii_dvolname: %s\n", ii_overflow.ii_volname);
161 	mdb_printf("ii_dhmagic: %x\n", ii_overflow.ii_hmagic);
162 	mdb_printf("ii_dhversion: %x\n", ii_overflow.ii_hversion);
163 	mdb_printf("ii_ddrefcnt: %x\n", ii_overflow.ii_drefcnt);
164 	mdb_printf("ii_dflags: %x\n", ii_overflow.ii_flags);
165 	mdb_printf("ii_dfreehead: %x\n", ii_overflow.ii_freehead);
166 	mdb_printf("ii_dnchunks: %x\n", ii_overflow.ii_nchunks);
167 	mdb_printf("ii_dunused: %x\n", ii_overflow.ii_unused);
168 	mdb_printf("ii_dused: %x\n", ii_overflow.ii_used);
169 	mdb_printf("ii_urefcnt: %x\n", ii_overflow.ii_urefcnt);
170 	mdb_dec_indent(4);
171 
172 	mdb_printf("ii_mutex: %x\n", ii_overflow.ii_mutex);
173 	mdb_printf("ii_kstat_mutex: %x\n", ii_overflow.ii_kstat_mutex);
174 	mdb_printf("ii_crefcnt: %d\n", ii_overflow.ii_crefcnt);
175 	mdb_printf("ii_detachcnt: %d\n", ii_overflow.ii_detachcnt);
176 	mdb_printf("ii_next: %x\n", ii_overflow.ii_next);
177 
178 	mdb_printf("Overflow volume:\n");
179 	if (ii_overflow.ii_dev)
180 		ii_info_dev((uintptr_t)ii_overflow.ii_dev, flags, 0, NULL);
181 
182 	mdb_printf("  ii_ioname: %s\n", &ii_overflow.ii_ioname);
183 	mdb_dec_indent(4);
184 
185 	nextaddr = (uintptr_t)ii_overflow.ii_next;
186 	return (DCMD_OK);
187 }
188 /*ARGSUSED*/
189 static int
190 ii_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
191 {
192 	_ii_info_t ii_info = {0};
193 	char string[DSW_NAMELEN];
194 
195 	nextaddr = 0;
196 	if (!(flags & DCMD_ADDRSPEC))
197 		return (DCMD_USAGE);
198 
199 	if (mdb_vread(&ii_info, sizeof (ii_info), addr) != sizeof (ii_info)) {
200 		mdb_warn("failed to read ii_info_t at 0x%p", addr);
201 		return (DCMD_ERR);
202 	}
203 
204 	mdb_printf(
205 		"bi_next: 0x%p\n"
206 		"bi_head: 0x%p\t"
207 		"bi_sibling: 0x%p\n"
208 		"bi_master: 0x%p\t"
209 		"bi_nextmst: 0x%p\n",
210 		ii_info.bi_next, ii_info.bi_head, ii_info.bi_sibling,
211 		ii_info.bi_master, ii_info.bi_nextmst);
212 
213 	mdb_printf("bi_mutex: 0x%p\n", ii_info.bi_mutex);
214 
215 	/*
216 	 * Print out all the fds by using ii_info_dev
217 	 */
218 	mdb_printf("Cache master:\n");
219 	if (ii_info.bi_mstdev)
220 		ii_info_dev((uintptr_t)ii_info.bi_mstdev, flags, 0, NULL);
221 
222 	mdb_printf("Raw master:\n");
223 	if (ii_info.bi_mstrdev)
224 		ii_info_dev((uintptr_t)ii_info.bi_mstrdev, flags, 0, NULL);
225 
226 	mdb_printf("Cache shadow:\n");
227 	ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shddev)),
228 	    flags, 0, NULL);
229 
230 	mdb_printf("Raw shadow:\n");
231 	ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shdrdev)),
232 	    flags, 0, NULL);
233 
234 	mdb_printf("Bitmap:\n");
235 	ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_bmpdev)),
236 	    flags, 0, NULL);
237 
238 	mdb_printf("bi_keyname: %-*s\n", DSW_NAMELEN, ii_info.bi_keyname);
239 	mdb_printf("bi_bitmap: 0x%p\n", ii_info.bi_bitmap);
240 
241 	if ((ii_info.bi_cluster == NULL) ||
242 	    (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_cluster)
243 		!= sizeof (string)))
244 		string[0] = 0;
245 	mdb_printf("bi_cluster: %s\n", string);
246 
247 	if ((ii_info.bi_group == NULL) ||
248 	    (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_group)
249 			!= sizeof (string)))
250 		string[0] = 0;
251 	mdb_printf("bi_group: %s\n", string);
252 
253 	mdb_printf("bi_busy: 0x%p\n", ii_info.bi_busy);
254 
255 	mdb_printf("bi_shdfba: %0x\t", ii_info.bi_shdfba);
256 	mdb_printf("bi_shdbits: %0x\n", ii_info.bi_shdbits);
257 	mdb_printf("bi_copyfba: %0x\t", ii_info.bi_copyfba);
258 	mdb_printf("bi_copybits: %0x\n", ii_info.bi_copybits);
259 
260 	mdb_printf("bi_size: %0x\n", ii_info.bi_size);
261 
262 	mdb_printf("bi_flags: 0x%x <%b>\n",
263 		ii_info.bi_flags, ii_info.bi_flags, bi_flags_bits);
264 
265 	mdb_printf("bi_state: 0x%x <%b>\n",
266 		ii_info.bi_state, ii_info.bi_state, bi_state_bits);
267 
268 	mdb_printf("bi_disabled: %d\n", ii_info.bi_disabled);
269 	mdb_printf("bi_ioctl: %d\n", ii_info.bi_ioctl);
270 	mdb_printf("bi_release: %d\t", ii_info.bi_release);
271 	mdb_printf("bi_rsrvcnt: %d\n", ii_info.bi_rsrvcnt);
272 
273 	mdb_printf("bi_copydonecv: %x\t", ii_info.bi_copydonecv);
274 	mdb_printf("bi_reservecv: %x\n", ii_info.bi_reservecv);
275 	mdb_printf("bi_releasecv: %x\t", ii_info.bi_releasecv);
276 	mdb_printf("bi_closingcv: %x\n", ii_info.bi_closingcv);
277 	mdb_printf("bi_ioctlcv: %x\t", ii_info.bi_ioctlcv);
278 	mdb_printf("bi_busycv: %x\n", ii_info.bi_busycv);
279 	mdb_call_dcmd("rwlock", (uintptr_t)(addr +
280 	    offsetof(_ii_info_t, bi_busyrw)), flags, 0, NULL);
281 	mdb_printf("bi_bitmap_ops: 0x%p\n", ii_info.bi_bitmap_ops);
282 
283 	mdb_printf("bi_rsrvmutex: %x\t", ii_info.bi_rsrvmutex);
284 	mdb_printf("bi_rlsemutex: %x\n", ii_info.bi_rlsemutex);
285 	mdb_printf("bi_bmpmutex: %x\n", ii_info.bi_bmpmutex);
286 
287 	mdb_printf("bi_mstchks: %d\t", ii_info.bi_mstchks);
288 	mdb_printf("bi_shdchks: %d\n", ii_info.bi_shdchks);
289 	mdb_printf("bi_shdchkused: %d\t", ii_info.bi_shdchkused);
290 	mdb_printf("bi_shdfchk: %d\n", ii_info.bi_shdfchk);
291 
292 	mdb_printf("bi_overflow\n");
293 	if (ii_info.bi_overflow)
294 		ii_overflow((uintptr_t)ii_info.bi_overflow, flags, 0, NULL);
295 
296 	mdb_printf("bi_iifd:\n");
297 	if (ii_info.bi_iifd)
298 		(void) ii_fd((uintptr_t)ii_info.bi_iifd, flags, 0, NULL);
299 
300 	mdb_printf("bi_throttle_unit: %d\t", ii_info.bi_throttle_unit);
301 	mdb_printf("bi_throttle_delay: %d\n", ii_info.bi_throttle_delay);
302 
303 	mdb_printf("bi_linkrw:\n");
304 	mdb_call_dcmd("rwlock", (uintptr_t)(addr +
305 	    offsetof(_ii_info_t, bi_linkrw)), flags, 0, NULL);
306 
307 	mdb_printf("bi_chksmutex: %x\n", ii_info.bi_chksmutex);
308 	mdb_printf("bi_locked_pid: %x\n", ii_info.bi_locked_pid);
309 	mdb_printf("bi_kstat: 0x%p\n", ii_info.bi_kstat);
310 	/* ii_kstat_info_t bi_kstat_io; */
311 
312 	nextaddr = (uintptr_t)ii_info.bi_next;
313 	return (DCMD_OK);
314 }
315 
316 /*
317  * This should be a walker surely.
318  */
319 /*ARGSUSED*/
320 static int
321 ii_info_all(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
322 {
323 	uintptr_t myaddr;
324 	/*
325 	 * we use the global address.
326 	 */
327 	if (flags & DCMD_ADDRSPEC)
328 		return (DCMD_USAGE);
329 
330 	if (mdb_readsym(&myaddr, sizeof (myaddr), "_ii_info_top") !=
331 	    sizeof (myaddr)) {
332 		return (DCMD_ERR);
333 	}
334 
335 	mdb_printf("_ii_info_top contains 0x%lx\n", myaddr);
336 
337 	while (myaddr) {
338 		ii_info(myaddr, DCMD_ADDRSPEC, 0, NULL);
339 		myaddr = nextaddr;
340 	}
341 	return (DCMD_OK);
342 }
343 
344 /*
345  * Display general ii module information.
346  */
347 
348 #define	ii_get_print(kvar, str, fmt, val)		\
349 	if (mdb_readvar(&(val), #kvar) == -1) {		\
350 		mdb_dec_indent(4);			\
351 		mdb_warn("unable to read '" #kvar "'");	\
352 		return (DCMD_ERR);			\
353 	}						\
354 	mdb_printf("%-20s" fmt "\n", str ":", val)
355 
356 /* ARGSUSED */
357 static int
358 ii(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
359 {
360 	int maj, min, mic, baseline, i;
361 
362 	if (argc != 0)
363 		return (DCMD_USAGE);
364 
365 	if (mdb_readvar(&maj, "dsw_major_rev") == -1) {
366 		mdb_warn("unable to read 'dsw_major_rev'");
367 		return (DCMD_ERR);
368 	}
369 
370 	if (mdb_readvar(&min, "dsw_minor_rev") == -1) {
371 		mdb_warn("unable to read 'dsw_minor_rev'");
372 		return (DCMD_ERR);
373 	}
374 
375 	if (mdb_readvar(&mic, "dsw_micro_rev") == -1) {
376 		mdb_warn("unable to read 'dsw_micro_rev'");
377 		return (DCMD_ERR);
378 	}
379 
380 	if (mdb_readvar(&baseline, "dsw_baseline_rev") == -1) {
381 		mdb_warn("unable to read 'dsw_baseline_rev'");
382 		return (DCMD_ERR);
383 	}
384 
385 	mdb_printf("Point-in-Time Copy module version: kernel %d.%d.%d.%d; "
386 	    "mdb %d.%d.%d.%d\n", maj, min, mic, baseline,
387 	    ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM);
388 
389 	mdb_inc_indent(4);
390 	ii_get_print(ii_debug, "debug", "%d", i);
391 	ii_get_print(ii_bitmap, "bitmaps", "%d", i);
392 	mdb_dec_indent(4);
393 
394 	return (DCMD_OK);
395 }
396 
397 
398 /*
399  * MDB module linkage information:
400  */
401 
402 static const mdb_dcmd_t dcmds[] = {
403 { "ii", NULL, "display ii module info", ii },
404 { "ii_fd", NULL, "display ii_fd structure", ii_fd },
405 { "ii_info", NULL, "display ii_info structure", ii_info },
406 { "ii_info_all", NULL, "display all ii_info structures", ii_info_all },
407 { "ii_info_dev", NULL, "display ii_info_dev structure", ii_info_dev},
408 { "ii_overflow", NULL, "display ii_overflow structure", ii_overflow},
409 { NULL }
410 };
411 
412 
413 static const mdb_walker_t walkers[] = {
414 	{ NULL }
415 };
416 
417 
418 static const mdb_modinfo_t modinfo = {
419 	MDB_API_VERSION, dcmds, walkers
420 };
421 
422 
423 const mdb_modinfo_t *
424 _mdb_init(void)
425 {
426 	return (&modinfo);
427 }
428