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