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 }