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