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/ksynch.h> 28 #include <sys/kmem.h> 29 #include <sys/errno.h> 30 #include <sys/ddi.h> 31 32 #include <sys/mdb_modapi.h> 33 34 #define __NSC_GEN__ 35 #include <sys/nsc_thread.h> 36 #include <sys/nsctl/nsc_dev.h> 37 #include <sys/nsctl/nsc_gen.h> 38 #include <sys/nsctl/nsc_mem.h> 39 #include <sys/nsctl/nsctl.h> 40 #include <sys/nsctl/nsc_disk.h> 41 42 43 /* 44 * Data struct for the complex walks. 45 */ 46 47 struct complex_args { 48 int argc; 49 mdb_arg_t *argv; 50 }; 51 52 53 /* 54 * Bit definitions 55 */ 56 57 #define NSC_RW_BITS \ 58 { "NSC_READ", NSC_READ, NSC_READ }, \ 59 { "NSC_WRITE", NSC_WRITE, NSC_WRITE } 60 61 62 static const mdb_bitmask_t nsc_bhflag_bits[] = { 63 NSC_RW_BITS, 64 { "NSC_PINNABLE", NSC_PINNABLE, NSC_PINNABLE }, 65 { "NSC_NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK }, 66 { "NSC_HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED }, 67 { "NSC_HACTIVE", NSC_HACTIVE, NSC_HACTIVE }, 68 { "NSC_BCOPY", NSC_BCOPY, NSC_BCOPY }, 69 { "NSC_PAGEIO", NSC_PAGEIO, NSC_PAGEIO }, 70 { "NSC_ABUF", NSC_ABUF, NSC_ABUF }, 71 { "NSC_MIXED", NSC_MIXED, NSC_MIXED }, 72 { "NSC_WRTHRU", NSC_WRTHRU, NSC_WRTHRU }, 73 { "NSC_FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU }, 74 { "NSC_NOCACHE", NSC_NOCACHE, NSC_NOCACHE }, 75 { "NSC_QUEUE", NSC_QUEUE, NSC_QUEUE }, 76 { "NSC_RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD }, 77 { "NSC_NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU }, 78 { "NSC_METADATA", NSC_METADATA, NSC_METADATA }, 79 { "NSC_SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO }, 80 { NULL, 0, 0 } 81 }; 82 83 84 static const mdb_bitmask_t nsc_fdflag_bits[] = { 85 NSC_RW_BITS, 86 { NULL, 0, 0 } 87 }; 88 89 90 static const mdb_bitmask_t nsc_fdmode_bits[] = { 91 { "NSC_MULTI", NSC_MULTI, NSC_MULTI }, 92 { NULL, 0, 0 } 93 }; 94 95 96 static const mdb_bitmask_t nsc_type_bits[] = { 97 /* types */ 98 { "NSC_NULL", NSC_NULL, NSC_NULL }, 99 { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, 100 { "NSC_FILE", NSC_FILE, NSC_FILE }, 101 { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, 102 { "NSC_VCHR", NSC_VCHR, NSC_VCHR }, 103 { "NSC_NCALL", NSC_NCALL, NSC_NCALL }, 104 105 /* type flags */ 106 { "NSC_ANON", NSC_ANON, NSC_ANON }, 107 108 /* ids */ 109 { "NSC_RAW_ID", NSC_RAW_ID, NSC_RAW_ID }, 110 { "NSC_FILE_ID", NSC_FILE_ID, NSC_FILE_ID }, 111 { "NSC_FREEZE_ID", NSC_FREEZE_ID, NSC_FREEZE_ID }, 112 { "NSC_VCHR_ID", NSC_VCHR_ID, NSC_VCHR_ID }, 113 { "NSC_NCALL_ID", NSC_NCALL_ID, NSC_NCALL_ID }, 114 { "NSC_SDBC_ID", NSC_SDBC_ID, NSC_SDBC_ID }, 115 { "NSC_RDCLR_ID", NSC_RDCLR_ID, NSC_RDCLR_ID }, 116 { "NSC_RDCL_ID", NSC_RDCL_ID, NSC_RDCL_ID }, 117 { "NSC_IIR_ID", NSC_IIR_ID, NSC_IIR_ID }, 118 { "NSC_II_ID", NSC_II_ID, NSC_II_ID }, 119 { "NSC_RDCHR_ID", NSC_RDCHR_ID, NSC_RDCHR_ID }, 120 { "NSC_RDCH_ID", NSC_RDCH_ID, NSC_RDCH_ID }, 121 { NULL, 0, 0 } 122 }; 123 124 125 static const mdb_bitmask_t nsc_availpend_bits[] = { 126 NSC_RW_BITS, 127 { "_NSC_OPEN", _NSC_OPEN, _NSC_OPEN }, 128 { "_NSC_CLOSE", _NSC_CLOSE, _NSC_CLOSE }, 129 { "_NSC_PINNED", _NSC_PINNED, _NSC_PINNED }, 130 { "_NSC_ATTACH", _NSC_ATTACH, _NSC_ATTACH }, 131 { "_NSC_DETACH", _NSC_DETACH, _NSC_DETACH }, 132 { "_NSC_OWNER", _NSC_OWNER, _NSC_OWNER }, 133 { NULL, 0, 0 } 134 }; 135 136 137 static const mdb_bitmask_t nsc_ioflag_bits[] = { 138 { "NSC_REFCNT", NSC_REFCNT, NSC_REFCNT }, 139 { "NSC_FILTER", NSC_FILTER, NSC_FILTER }, 140 { NULL, 0, 0 } 141 }; 142 143 144 static const mdb_bitmask_t nstset_flag_bits[] = { 145 { "NST_SF_KILL", NST_SF_KILL, NST_SF_KILL }, 146 { NULL, 0, 0 } 147 }; 148 149 150 static const mdb_bitmask_t nst_flag_bits[] = { 151 { "NST_TF_INUSE", NST_TF_INUSE, NST_TF_INUSE }, 152 { "NST_TF_ACTIVE", NST_TF_ACTIVE, NST_TF_ACTIVE }, 153 { "NST_TF_PENDING", NST_TF_PENDING, NST_TF_PENDING }, 154 { "NST_TF_DESTROY", NST_TF_DESTROY, NST_TF_DESTROY }, 155 { "NST_TF_KILL", NST_TF_KILL, NST_TF_KILL }, 156 { NULL, 0, 0 } 157 }; 158 159 160 /* 161 * Global data. 162 */ 163 164 static nsc_mem_t type_mem[20]; 165 static int complex_walk; 166 static int complex_hdr; 167 168 169 /* ---------------------------------------------------------------------- */ 170 171 /* 172 * Walker for an nsc_io chain. 173 * A global walk is assumed to start at _nsc_io_top. 174 */ 175 176 static int 177 nsc_io_winit(mdb_walk_state_t *wsp) 178 { 179 if (wsp->walk_addr == NULL && 180 mdb_readvar(&wsp->walk_addr, "_nsc_io_top") == -1) { 181 mdb_warn("unable to read '_nsc_io_top'"); 182 return (WALK_ERR); 183 } 184 185 return (WALK_NEXT); 186 } 187 188 189 static int 190 nsc_io_wstep(mdb_walk_state_t *wsp) 191 { 192 uintptr_t next; 193 int status; 194 195 if (wsp->walk_addr == NULL) 196 return (WALK_DONE); 197 198 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 199 wsp->walk_cbdata); 200 201 next = wsp->walk_addr + OFFSETOF(nsc_io_t, next); 202 203 if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) { 204 mdb_warn("failed to read nsc_io_t.next at %p", next); 205 return (WALK_DONE); 206 } 207 208 return (status); 209 } 210 211 212 /* ---------------------------------------------------------------------- */ 213 214 /* 215 * Walker for an nsc_dev chain. 216 * A global walk is assumed to start at _nsc_dev_top. 217 */ 218 219 static int 220 nsc_dev_winit(mdb_walk_state_t *wsp) 221 { 222 if (wsp->walk_addr == NULL && 223 mdb_readvar(&wsp->walk_addr, "_nsc_dev_top") == -1) { 224 mdb_warn("unable to read '_nsc_dev_top'"); 225 return (WALK_ERR); 226 } 227 228 return (WALK_NEXT); 229 } 230 231 232 static int 233 nsc_dev_wstep(mdb_walk_state_t *wsp) 234 { 235 uintptr_t next; 236 int status; 237 238 if (wsp->walk_addr == NULL) 239 return (WALK_DONE); 240 241 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 242 wsp->walk_cbdata); 243 244 next = wsp->walk_addr + OFFSETOF(nsc_dev_t, nsc_next); 245 246 if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) { 247 mdb_warn("failed to read nsc_dev_t.nsc_next at %p", next); 248 return (WALK_DONE); 249 } 250 251 return (status); 252 } 253 254 255 /* ARGSUSED */ 256 257 static void 258 nsc_dev_wfini(mdb_walk_state_t *wsp) 259 { 260 complex_walk = 0; 261 } 262 263 264 /* ---------------------------------------------------------------------- */ 265 266 /* 267 * Walker for a chain of nsc_devval_t structures. 268 * Global walks start from _nsc_devval_top; 269 */ 270 271 static int 272 nsc_devval_winit(mdb_walk_state_t *wsp) 273 { 274 if (wsp->walk_addr == NULL && 275 mdb_readvar(&wsp->walk_addr, "_nsc_devval_top") == -1) { 276 mdb_warn("unable to read '_nsc_devval_top'"); 277 return (WALK_ERR); 278 } 279 280 return (WALK_NEXT); 281 } 282 283 284 static int 285 nsc_devval_wstep(mdb_walk_state_t *wsp) 286 { 287 uintptr_t devval = wsp->walk_addr; 288 int status; 289 290 if (!devval) 291 return (WALK_DONE); 292 293 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 294 wsp->walk_cbdata); 295 296 /* move on to next devval */ 297 298 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 299 devval + OFFSETOF(nsc_devval_t, dv_next)) == -1) { 300 mdb_warn("failed to read nsc_devval_t.dv_next"); 301 return (WALK_ERR); 302 } 303 304 return (status); 305 } 306 307 308 /* ---------------------------------------------------------------------- */ 309 310 /* 311 * Walker for a chain of nsc_fd_t structures. 312 * No global walks. 313 */ 314 315 static int 316 nsc_fd_winit(mdb_walk_state_t *wsp) 317 { 318 if (wsp->walk_addr == NULL) { 319 mdb_warn("nsc_fd doesn't support global walks"); 320 return (WALK_ERR); 321 } 322 323 return (WALK_NEXT); 324 } 325 326 327 static int 328 nsc_fd_wstep(mdb_walk_state_t *wsp) 329 { 330 uintptr_t fd = wsp->walk_addr; 331 int status; 332 333 if (!fd) 334 return (WALK_DONE); 335 336 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 337 wsp->walk_cbdata); 338 339 /* move on to next fd */ 340 341 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 342 fd + OFFSETOF(nsc_fd_t, sf_next)) == -1) { 343 mdb_warn("failed to read nsc_fd_t.sf_next"); 344 return (WALK_ERR); 345 } 346 347 return (status); 348 } 349 350 351 /* ---------------------------------------------------------------------- */ 352 353 /* 354 * Walker for a chain of nsc_iodev_t structures. 355 * No global walks. 356 */ 357 358 static int 359 nsc_iodev_winit(mdb_walk_state_t *wsp) 360 { 361 if (wsp->walk_addr == NULL) { 362 mdb_warn("nsc_iodev doesn't support global walks"); 363 return (WALK_ERR); 364 } 365 366 return (WALK_NEXT); 367 } 368 369 370 static int 371 nsc_iodev_wstep(mdb_walk_state_t *wsp) 372 { 373 uintptr_t iodev = wsp->walk_addr; 374 int status; 375 376 if (!iodev) 377 return (WALK_DONE); 378 379 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 380 wsp->walk_cbdata); 381 382 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 383 iodev + OFFSETOF(nsc_iodev_t, si_next)) == -1) { 384 mdb_warn("failed to read nsc_iodev_t.si_next"); 385 return (WALK_ERR); 386 } 387 388 return (status); 389 } 390 391 392 /* ---------------------------------------------------------------------- */ 393 394 /* 395 * Walker for a chain of nsc_service_t structures. 396 * Global walks start at _nsc_services. 397 */ 398 399 static int 400 nsc_service_winit(mdb_walk_state_t *wsp) 401 { 402 if (wsp->walk_addr == NULL && 403 mdb_readvar(&wsp->walk_addr, "_nsc_services") == -1) { 404 mdb_warn("unable to read '_nsc_services'"); 405 return (WALK_ERR); 406 } 407 408 return (WALK_NEXT); 409 } 410 411 412 static int 413 nsc_service_wstep(mdb_walk_state_t *wsp) 414 { 415 uintptr_t service = wsp->walk_addr; 416 int status; 417 418 if (!service) 419 return (WALK_DONE); 420 421 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 422 wsp->walk_cbdata); 423 424 /* move on to next service */ 425 426 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 427 service + OFFSETOF(nsc_service_t, s_next)) == -1) { 428 mdb_warn("failed to read nsc_service_t.s_next"); 429 return (WALK_ERR); 430 } 431 432 return (status); 433 } 434 435 436 /* ---------------------------------------------------------------------- */ 437 438 /* 439 * Walker for a chain of nsc_svc_t structures. 440 * No global walks. 441 */ 442 443 static int 444 nsc_svc_winit(mdb_walk_state_t *wsp) 445 { 446 if (wsp->walk_addr == NULL) { 447 mdb_warn("nsc_svc does not support global walks"); 448 return (WALK_ERR); 449 } 450 451 return (WALK_NEXT); 452 } 453 454 455 static int 456 nsc_svc_wstep(mdb_walk_state_t *wsp) 457 { 458 uintptr_t svc = wsp->walk_addr; 459 int status; 460 461 if (!svc) 462 return (WALK_DONE); 463 464 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 465 wsp->walk_cbdata); 466 467 /* move on to next svc */ 468 469 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 470 svc + OFFSETOF(nsc_svc_t, svc_next)) == -1) { 471 mdb_warn("failed to read nsc_svc_t.svc_next"); 472 return (WALK_ERR); 473 } 474 475 return (status); 476 } 477 478 479 /* ---------------------------------------------------------------------- */ 480 481 /* 482 * Walker for a chain of nsc_val_t structures. 483 * No global walks. 484 */ 485 486 static int 487 nsc_val_winit(mdb_walk_state_t *wsp) 488 { 489 if (wsp->walk_addr == NULL) { 490 mdb_warn("nsc_val doesn't support global walks"); 491 return (WALK_ERR); 492 } 493 494 return (WALK_NEXT); 495 } 496 497 498 static int 499 nsc_val_wstep(mdb_walk_state_t *wsp) 500 { 501 uintptr_t val = wsp->walk_addr; 502 int status; 503 504 if (!val) 505 return (WALK_DONE); 506 507 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 508 wsp->walk_cbdata); 509 510 /* move on to next val */ 511 512 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 513 val + OFFSETOF(nsc_val_t, sv_next)) == -1) { 514 mdb_warn("failed to read nsc_val_t.sv_next"); 515 return (WALK_ERR); 516 } 517 518 return (status); 519 } 520 521 522 /* ---------------------------------------------------------------------- */ 523 524 /* 525 * Walker for a chain of nstset_t structures. 526 * Global walks start at _nst_sets. 527 */ 528 529 static int 530 nstset_winit(mdb_walk_state_t *wsp) 531 { 532 if (wsp->walk_addr == NULL && 533 mdb_readvar(&wsp->walk_addr, "nst_sets") == -1) { 534 mdb_warn("unable to read 'nst_sets'"); 535 return (WALK_ERR); 536 } 537 538 return (WALK_NEXT); 539 } 540 541 542 static int 543 nstset_wstep(mdb_walk_state_t *wsp) 544 { 545 uintptr_t set = wsp->walk_addr; 546 int status; 547 548 if (!set) 549 return (WALK_DONE); 550 551 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 552 wsp->walk_cbdata); 553 554 /* move on to next set */ 555 556 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 557 set + OFFSETOF(nstset_t, set_next)) == -1) { 558 mdb_warn("failed to read nstset_t.set_next"); 559 return (WALK_ERR); 560 } 561 562 return (status); 563 } 564 565 566 /* ---------------------------------------------------------------------- */ 567 568 /* 569 * Walker for a chain of nsthread_t structures. 570 * No global walks. 571 */ 572 573 static int 574 nsthread_winit(mdb_walk_state_t *wsp) 575 { 576 if (wsp->walk_addr == NULL) { 577 mdb_warn("nsthread does not support global walks"); 578 return (WALK_ERR); 579 } 580 581 return (WALK_NEXT); 582 } 583 584 585 static int 586 nsthread_wstep(mdb_walk_state_t *wsp) 587 { 588 uintptr_t thread = wsp->walk_addr; 589 int status; 590 591 if (!thread) 592 return (WALK_DONE); 593 594 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 595 wsp->walk_cbdata); 596 597 /* move on to next iodev */ 598 599 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 600 thread + OFFSETOF(nsthread_t, tp_chain)) == -1) { 601 mdb_warn("failed to read nsthread_t.tp_chain"); 602 return (WALK_ERR); 603 } 604 605 return (status); 606 } 607 608 609 /* ---------------------------------------------------------------------- */ 610 611 /* 612 * Walker for nsthread_t free/reuse chain. 613 * No global walks. 614 */ 615 616 static int 617 nst_free_winit(mdb_walk_state_t *wsp) 618 { 619 if (wsp->walk_addr == NULL) { 620 mdb_warn("nst_free does not support global walks"); 621 return (WALK_ERR); 622 } 623 624 /* store starting address */ 625 626 wsp->walk_data = (void *)wsp->walk_addr; 627 628 /* move on to next thread */ 629 630 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 631 wsp->walk_addr + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) { 632 mdb_warn("failed to read nsthread_t.tp_link.q_forw"); 633 return (WALK_ERR); 634 } 635 636 return (WALK_NEXT); 637 } 638 639 640 static int 641 nst_free_wstep(mdb_walk_state_t *wsp) 642 { 643 uintptr_t thread = wsp->walk_addr; 644 int status; 645 646 if (!thread) 647 return (WALK_DONE); 648 649 if (thread == (uintptr_t)wsp->walk_data) 650 return (WALK_DONE); 651 652 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 653 wsp->walk_cbdata); 654 655 /* move on to next thread */ 656 657 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 658 thread + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) { 659 mdb_warn("failed to read nsthread_t.tp_link.q_forw"); 660 return (WALK_ERR); 661 } 662 663 return (status); 664 } 665 666 667 /* ---------------------------------------------------------------------- */ 668 669 /* 670 * Walker for a chain of nsc_mem_t structures. 671 * Global walks start at _nsc_mem_top. 672 */ 673 674 static int 675 nsc_mem_winit(mdb_walk_state_t *wsp) 676 { 677 if (wsp->walk_addr == NULL && 678 mdb_readvar(&wsp->walk_addr, "_nsc_mem_top") == -1) { 679 mdb_warn("unable to read '_nsc_mem_top'"); 680 return (WALK_ERR); 681 } 682 683 return (WALK_NEXT); 684 } 685 686 687 static int 688 nsc_mem_wstep(mdb_walk_state_t *wsp) 689 { 690 uintptr_t mem = wsp->walk_addr; 691 int status; 692 693 if (!mem) 694 return (WALK_DONE); 695 696 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 697 wsp->walk_cbdata); 698 699 /* move on to next mem */ 700 701 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), 702 mem + OFFSETOF(nsc_mem_t, next)) == -1) { 703 mdb_warn("failed to read nsc_mem_t.next"); 704 return (WALK_ERR); 705 } 706 707 return (status); 708 } 709 710 711 /* ---------------------------------------------------------------------- */ 712 713 struct { 714 char *name; 715 int id; 716 } io_ids[] = { 717 { "NSC_RAW_ID", NSC_RAW_ID }, 718 { "NSC_FILE_ID", NSC_FILE_ID }, 719 { "NSC_FREEZE_ID", NSC_FREEZE_ID }, 720 { "NSC_SDBC_ID", NSC_SDBC_ID }, 721 { "NSC_RDCLR_ID", NSC_RDCLR_ID }, 722 { "NSC_RDCL_ID", NSC_RDCL_ID }, 723 { "NSC_IIR_ID", NSC_IIR_ID }, 724 { "NSC_II_ID", NSC_II_ID }, 725 { "NSC_RDCHR_ID", NSC_RDCHR_ID }, 726 { "NSC_RDCH_ID", NSC_RDCH_ID }, 727 { NULL, 0 } 728 }; 729 730 731 static char * 732 nsc_io_id(const int id) 733 { 734 int i; 735 736 for (i = 0; io_ids[i].name != NULL; i++) { 737 if (io_ids[i].id == id) { 738 return (io_ids[i].name); 739 } 740 } 741 742 return ("unknown"); 743 } 744 745 746 /* 747 * Display a single nsc_io_t structure. 748 * If called with no address, performs a global walk of all nsc_ios. 749 */ 750 static int 751 nsc_io(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 752 { 753 char io_name[128]; 754 nsc_io_t *io; 755 int v_opt; 756 757 v_opt = 0; 758 759 if (mdb_getopts(argc, argv, 760 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 761 return (DCMD_USAGE); 762 763 if (!(flags & DCMD_ADDRSPEC)) { 764 if (mdb_walk_dcmd("nsctl`nsc_io", 765 "nsctl`nsc_io", argc, argv) == -1) { 766 mdb_warn("failed to walk 'nsc_io'"); 767 return (DCMD_ERR); 768 } 769 770 return (DCMD_OK); 771 } 772 773 io = mdb_zalloc(sizeof (*io), UM_SLEEP | UM_GC); 774 memset(io_name, 0, sizeof (io_name)); 775 776 if (mdb_vread(io, sizeof (*io), addr) != sizeof (*io)) { 777 mdb_warn("failed to read nsc_io at %p", addr); 778 return (DCMD_ERR); 779 } 780 781 if (io->name) { 782 if (mdb_readstr(io_name, sizeof (io_name), 783 (uintptr_t)io->name) == -1) { 784 mdb_warn("failed to read nsc_io_t.name"); 785 return (DCMD_ERR); 786 } 787 } 788 789 if (DCMD_HDRSPEC(flags)) { 790 mdb_printf("%-?s %8Tid fl ref abuf name\n", "io"); 791 } 792 793 mdb_printf("%0?p %8T%08x %2x %4d %4d %s\n", 794 addr, io->id, io->flag, io->refcnt, io->abufcnt, io_name); 795 796 if (!v_opt) 797 return (DCMD_OK); 798 799 mdb_inc_indent(4); 800 801 mdb_printf("id: %08x <%s>\n", io->id, nsc_io_id(io->id)); 802 803 mdb_printf("provide: %08x <%b>\n", io->provide, 804 io->provide, nsc_type_bits); 805 806 mdb_printf("flag: %08x <%b>\n", io->flag, io->flag, nsc_ioflag_bits); 807 808 mdb_printf("pend: %d\n", io->pend); 809 810 mdb_dec_indent(4); 811 812 return (DCMD_OK); 813 } 814 815 816 /* ---------------------------------------------------------------------- */ 817 818 /* 819 * Display a single nsc_dev_t structure. 820 * If called with no address, performs a global walk of all nsc_devs. 821 */ 822 static int 823 nsc_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 824 { 825 char path[NSC_MAXPATH+1]; 826 nsc_devval_t *dv; 827 nsc_dev_t *dev; 828 uintptr_t dev_pend; 829 int a_opt, v_opt; 830 831 a_opt = v_opt = 0; 832 833 if (mdb_getopts(argc, argv, 834 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 835 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 836 return (DCMD_USAGE); 837 838 if (!(flags & DCMD_ADDRSPEC)) { 839 mdb_printf("Active device structures:\n"); 840 841 if (mdb_walk_dcmd("nsctl`nsc_dev", 842 "nsctl`nsc_dev", argc, argv) == -1) { 843 mdb_warn("failed to walk 'nsc_dev'"); 844 return (DCMD_ERR); 845 } 846 847 if (a_opt) { 848 if (mdb_readvar(&dev_pend, "_nsc_dev_pend") == -1) { 849 mdb_warn("failed to read _nsc_dev_pend"); 850 return (DCMD_ERR); 851 } 852 853 mdb_printf("\nPending device structures:"); 854 855 if (dev_pend) { 856 mdb_printf("\n"); 857 858 if (mdb_pwalk_dcmd("nsctl`nsc_dev", 859 "nsctl`nsc_dev", argc, argv, 860 dev_pend) == -1) { 861 mdb_warn("failed to walk " 862 "pending dev structs"); 863 return (DCMD_ERR); 864 } 865 } else { 866 mdb_printf(" none\n"); 867 } 868 } 869 870 return (DCMD_OK); 871 } 872 873 memset(path, 0, sizeof (path)); 874 dev = mdb_zalloc(sizeof (*dev), UM_SLEEP | UM_GC); 875 876 if (mdb_vread(dev, sizeof (*dev), addr) != sizeof (*dev)) { 877 mdb_warn("failed to read nsc_dev at %p", addr); 878 return (DCMD_ERR); 879 } 880 881 if (mdb_readstr(path, sizeof (path), (uintptr_t)dev->nsc_path) == -1) { 882 mdb_warn("failed to read nsc_path at %p", dev->nsc_path); 883 return (DCMD_ERR); 884 } 885 886 if (DCMD_HDRSPEC(flags)) { 887 mdb_printf("%-?s %8Tref pend rpnd wait path\n", "dev"); 888 } 889 890 mdb_printf("%0?p %8T%3d %4d %4d %4d %s\n", 891 addr, dev->nsc_refcnt, dev->nsc_pend, dev->nsc_rpend, 892 dev->nsc_wait, path); 893 894 if (!v_opt) 895 return (DCMD_OK); 896 897 mdb_inc_indent(4); 898 899 mdb_printf("next: %0?p %8Tclose: %0?p\n", 900 dev->nsc_next, dev->nsc_close); 901 902 mdb_printf("list: %0?p %8Tlock: %0?p\n", 903 dev->nsc_list, addr + OFFSETOF(nsc_dev_t, nsc_lock)); 904 905 mdb_printf("cv: %0?p %8Tpath: %0?p %8Tphash: %016llx\n", 906 addr + OFFSETOF(nsc_dev_t, nsc_cv), 907 dev->nsc_path, dev->nsc_phash); 908 909 mdb_printf("drop: %d %8Treopen: %d\n", 910 dev->nsc_drop, dev->nsc_reopen); 911 912 if (dev->nsc_values) { 913 dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC); 914 if (mdb_vread(dv, sizeof (*dv), (uintptr_t)dev->nsc_values) != 915 sizeof (*dv)) { 916 mdb_warn("unable to read nsc_dev_t.nsc_values"); 917 mdb_dec_indent(4); 918 return (DCMD_ERR); 919 } 920 921 if (dv->dv_values) { 922 mdb_printf("device/values: (nsc_devval: %0?p)\n", 923 dev->nsc_values); 924 925 mdb_inc_indent(4); 926 927 if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val", 928 0, NULL, (uintptr_t)dv->dv_values) == -1) { 929 mdb_dec_indent(8); 930 return (DCMD_ERR); 931 } 932 933 mdb_dec_indent(4); 934 } 935 } 936 937 mdb_dec_indent(4); 938 939 return (DCMD_OK); 940 } 941 942 943 /* ---------------------------------------------------------------------- */ 944 945 /* 946 * Display a single nsc_devval_t structure. 947 * If called with no address, performs a global walk of all nsc_devs. 948 */ 949 static int 950 nsc_devval(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 951 { 952 nsc_devval_t *dv; 953 int a_opt; 954 955 a_opt = 0; 956 957 if (mdb_getopts(argc, argv, 958 'a', MDB_OPT_SETBITS, TRUE, &a_opt) != argc) 959 return (DCMD_USAGE); 960 961 if (!(flags & DCMD_ADDRSPEC)) { 962 if (mdb_walk_dcmd("nsctl`nsc_devval", 963 "nsctl`nsc_devval", argc, argv) == -1) { 964 mdb_warn("failed to walk 'nsc_devval'"); 965 return (DCMD_ERR); 966 } 967 968 return (DCMD_OK); 969 } 970 971 dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC); 972 973 if (mdb_vread(dv, sizeof (*dv), addr) != sizeof (*dv)) { 974 mdb_warn("failed to read nsc_devval at %p", addr); 975 return (DCMD_ERR); 976 } 977 978 if (!a_opt && !dv->dv_values) { 979 return (DCMD_OK); 980 } 981 982 if (DCMD_HDRSPEC(flags)) { 983 mdb_printf("%-?s %8T%?-s %8Tpath\n", "devval", "phash"); 984 } 985 986 mdb_printf("%0?p %8T%016llx %8T%s\n", addr, 987 dv->dv_phash, dv->dv_path); 988 989 mdb_inc_indent(4); 990 991 if (dv->dv_values) { 992 if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val", 993 0, NULL, (uintptr_t)dv->dv_values) == -1) { 994 return (DCMD_ERR); 995 } 996 } else { 997 mdb_printf("No values\n"); 998 } 999 1000 mdb_dec_indent(4); 1001 1002 return (DCMD_OK); 1003 } 1004 1005 1006 /* ---------------------------------------------------------------------- */ 1007 1008 /* 1009 * Part 2 callback for the all devices and fds walk. Called per iodev. 1010 */ 1011 /* ARGSUSED */ 1012 static int 1013 nsc_fd_iodev(uintptr_t addr, const void *data, void *cbdata) 1014 { 1015 struct complex_args *fdall = cbdata; 1016 struct nsc_fd_t *fd; 1017 1018 if (mdb_vread(&fd, sizeof (fd), 1019 addr + OFFSETOF(nsc_iodev_t, si_open)) == -1) { 1020 mdb_warn("unable to read nsc_iodev_t.si_open"); 1021 return (WALK_ERR); 1022 } 1023 1024 if (fd != NULL) { 1025 if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd", 1026 fdall->argc, fdall->argv, (uintptr_t)fd) == -1) 1027 return (WALK_ERR); 1028 } 1029 1030 return (WALK_NEXT); 1031 } 1032 1033 1034 /* 1035 * Part 1 callback for the all devices and fds walk. Called per device. 1036 */ 1037 /* ARGSUSED */ 1038 static int 1039 nsc_fd_dev(uintptr_t addr, const void *data, void *cbdata) 1040 { 1041 struct complex_args *fdall = cbdata; 1042 nsc_iodev_t *iodev; 1043 nsc_fd_t *fd; 1044 1045 if (mdb_vread(&iodev, sizeof (iodev), 1046 addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) { 1047 mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr); 1048 return (WALK_ERR); 1049 } 1050 1051 /* walk iodev chains */ 1052 1053 if (iodev != NULL) { 1054 if (mdb_pwalk("nsctl`nsc_iodev", 1055 nsc_fd_iodev, fdall, (uintptr_t)iodev) == -1) 1056 return (WALK_ERR); 1057 } 1058 1059 /* walk nsc_close (closing fds) chains */ 1060 1061 if (mdb_vread(&fd, sizeof (fd), 1062 addr + OFFSETOF(nsc_dev_t, nsc_close)) == -1) { 1063 mdb_warn("unable to read nsc_dev_t.nsc_close at %p", addr); 1064 return (WALK_ERR); 1065 } 1066 1067 if (fd != NULL) { 1068 if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd", 1069 fdall->argc, fdall->argv, (uintptr_t)fd) == -1) 1070 return (WALK_ERR); 1071 } 1072 1073 return (WALK_NEXT); 1074 } 1075 1076 1077 /* 1078 * Walk all devices and fds in the system. 1079 */ 1080 static int 1081 nsc_fd_all(int argc, const mdb_arg_t *argv) 1082 { 1083 struct complex_args fdall; 1084 1085 fdall.argc = argc; 1086 fdall.argv = (mdb_arg_t *)argv; 1087 1088 complex_walk = 1; 1089 complex_hdr = 0; 1090 1091 if (mdb_walk("nsctl`nsc_dev", nsc_fd_dev, &fdall) == -1) { 1092 return (DCMD_ERR); 1093 } 1094 1095 return (DCMD_OK); 1096 } 1097 1098 1099 1100 /* 1101 * Display an nsd_fd_t structure, or walk all devices and fds in the system. 1102 */ 1103 static int 1104 nsc_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1105 { 1106 char io_name[128], *io_namep; 1107 char path[NSC_MAXPATH+1]; 1108 uintptr_t pathp; 1109 nsc_fd_t *fd; 1110 nsc_io_t *io; 1111 int v_opt; 1112 int hdr; 1113 1114 v_opt = 0; 1115 1116 if (mdb_getopts(argc, argv, 1117 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1118 return (DCMD_USAGE); 1119 1120 if (!(flags & DCMD_ADDRSPEC)) { 1121 return (nsc_fd_all(argc, argv)); 1122 } 1123 1124 memset(path, 0, sizeof (path)); 1125 fd = mdb_zalloc(sizeof (*fd), UM_SLEEP | UM_GC); 1126 memset(io_name, 0, sizeof (io_name)); 1127 1128 if (mdb_vread(fd, sizeof (*fd), addr) != sizeof (*fd)) { 1129 mdb_warn("failed to read nsc_fd at %p", addr); 1130 return (DCMD_ERR); 1131 } 1132 1133 if (mdb_vread(&pathp, sizeof (pathp), 1134 (uintptr_t)fd->sf_dev + OFFSETOF(nsc_dev_t, nsc_path)) != 1135 sizeof (pathp)) { 1136 mdb_warn("failed to read nsc_dev.nsc_path"); 1137 return (DCMD_ERR); 1138 } 1139 1140 if (mdb_readstr(path, sizeof (path), pathp) == -1) { 1141 mdb_warn("failed to read nsc_path"); 1142 return (DCMD_ERR); 1143 } 1144 1145 if (fd->sf_iodev) { 1146 if (mdb_vread(&io, sizeof (io), 1147 (uintptr_t)fd->sf_iodev + OFFSETOF(nsc_iodev_t, si_io)) != 1148 sizeof (io)) { 1149 mdb_warn("failed to read nsc_iodev.si_io"); 1150 return (DCMD_ERR); 1151 } 1152 1153 if (mdb_vread(&io_namep, sizeof (io_namep), 1154 (uintptr_t)io + OFFSETOF(nsc_io_t, name)) != 1155 sizeof (io_namep)) { 1156 mdb_warn("failed to read nsc_io_t.name"); 1157 return (DCMD_ERR); 1158 } 1159 1160 if (mdb_readstr(io_name, sizeof (io_name), 1161 (uintptr_t)io_namep) == -1) { 1162 mdb_warn("failed to read nsc_io_t.name string"); 1163 return (DCMD_ERR); 1164 } 1165 } 1166 1167 hdr = 0; 1168 if (complex_walk) { 1169 if (!complex_hdr) { 1170 complex_hdr = 1; 1171 hdr = 1; 1172 } 1173 } else if (DCMD_HDRSPEC(flags)) { 1174 hdr = 1; 1175 } 1176 1177 if (hdr) { 1178 mdb_printf("%-?s %8T%-?s %8T%-8s %-?s\n", 1179 "fd", "dev", "io", "cd"); 1180 mdb_printf(" %-?s %8Trv pend av path\n", "arg"); 1181 } 1182 1183 mdb_printf("%0?p %8T%0?p %8T%-8s %p\n", 1184 addr, fd->sf_dev, io_name, fd->sf_cd); 1185 mdb_printf(" %0?p %8T%2d %4x %2x %s\n", 1186 fd->sf_arg, fd->sf_reserve, fd->sf_pend, 1187 fd->sf_avail, path); 1188 1189 if (!v_opt) 1190 return (DCMD_OK); 1191 1192 mdb_inc_indent(4); 1193 1194 mdb_printf("open type: %08x <%b>\n", fd->sf_type, 1195 fd->sf_type, nsc_type_bits); 1196 1197 mdb_printf("avail: %08x <%b>\n", fd->sf_avail, 1198 fd->sf_avail, nsc_availpend_bits); 1199 1200 mdb_printf("flag: %08x <%b>\n", fd->sf_flag, 1201 fd->sf_flag, nsc_fdflag_bits); 1202 1203 mdb_printf("rsrv mode: %08x <%b>\n", fd->sf_mode, 1204 fd->sf_mode, nsc_fdmode_bits); 1205 1206 mdb_printf("open lbolt: %?x %8Treopen: %d\n", fd->sf_lbolt, 1207 fd->sf_reopen); 1208 1209 mdb_dec_indent(4); 1210 1211 return (DCMD_OK); 1212 } 1213 1214 1215 /* ---------------------------------------------------------------------- */ 1216 1217 /* 1218 * Callback for the all devices and iodevs walk. Called per device. 1219 */ 1220 /* ARGSUSED */ 1221 static int 1222 nsc_iodev_dev(uintptr_t addr, const void *data, void *cbdata) 1223 { 1224 struct complex_args *iodevall = cbdata; 1225 uintptr_t iodev; 1226 1227 if (mdb_vread(&iodev, sizeof (iodev), 1228 addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) { 1229 mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr); 1230 return (WALK_ERR); 1231 } 1232 1233 /* walk iodev chains */ 1234 1235 if (iodev != NULL) { 1236 if (mdb_pwalk_dcmd("nsctl`nsc_iodev", "nsctl`nsc_iodev", 1237 iodevall->argc, iodevall->argv, iodev) == -1) 1238 return (WALK_ERR); 1239 } 1240 1241 return (WALK_NEXT); 1242 } 1243 1244 1245 /* 1246 * Walk all devices and iodevs in the system. 1247 */ 1248 static int 1249 nsc_iodev_all(int argc, const mdb_arg_t *argv) 1250 { 1251 struct complex_args iodevall; 1252 1253 iodevall.argc = argc; 1254 iodevall.argv = (mdb_arg_t *)argv; 1255 1256 complex_walk = 1; 1257 complex_hdr = 0; 1258 1259 if (mdb_walk("nsctl`nsc_dev", nsc_iodev_dev, &iodevall) == -1) { 1260 return (DCMD_ERR); 1261 } 1262 1263 return (DCMD_OK); 1264 } 1265 1266 1267 /* 1268 * Display an nsc_iodev_t structure, or walk all devices and 1269 * iodevs in the system. 1270 */ 1271 static int 1272 nsc_iodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1273 { 1274 char io_name[128], *io_namep; 1275 char path[NSC_MAXPATH+1]; 1276 nsc_iodev_t *iodev; 1277 uintptr_t pathp; 1278 int v_opt; 1279 int hdr; 1280 1281 v_opt = 0; 1282 1283 if (mdb_getopts(argc, argv, 1284 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1285 return (DCMD_USAGE); 1286 1287 if (!(flags & DCMD_ADDRSPEC)) { 1288 return (nsc_iodev_all(argc, argv)); 1289 } 1290 1291 memset(path, 0, sizeof (path)); 1292 iodev = mdb_zalloc(sizeof (*iodev), UM_SLEEP | UM_GC); 1293 memset(io_name, 0, sizeof (io_name)); 1294 1295 if (mdb_vread(iodev, sizeof (*iodev), addr) != sizeof (*iodev)) { 1296 mdb_warn("failed to read nsc_iodev at %p", addr); 1297 return (DCMD_ERR); 1298 } 1299 1300 if (mdb_vread(&pathp, sizeof (pathp), 1301 (uintptr_t)iodev->si_dev + OFFSETOF(nsc_dev_t, nsc_path)) != 1302 sizeof (pathp)) { 1303 mdb_warn("failed to read nsc_dev.nsc_path"); 1304 return (DCMD_ERR); 1305 } 1306 1307 if (mdb_readstr(path, sizeof (path), pathp) == -1) { 1308 mdb_warn("failed to read nsc_path"); 1309 return (DCMD_ERR); 1310 } 1311 1312 if (mdb_vread(&io_namep, sizeof (io_namep), 1313 (uintptr_t)iodev->si_io + OFFSETOF(nsc_io_t, name)) != 1314 sizeof (io_namep)) { 1315 mdb_warn("failed to read nsc_io_t.name"); 1316 return (DCMD_ERR); 1317 } 1318 1319 if (mdb_readstr(io_name, sizeof (io_name), 1320 (uintptr_t)io_namep) == -1) { 1321 mdb_warn("failed to read nsc_io_t.name string"); 1322 return (DCMD_ERR); 1323 } 1324 1325 hdr = 0; 1326 if (complex_walk) { 1327 if (!complex_hdr) { 1328 complex_hdr = 1; 1329 hdr = 1; 1330 } 1331 } else if (DCMD_HDRSPEC(flags)) { 1332 hdr = 1; 1333 } 1334 1335 if (hdr) { 1336 mdb_printf("%-?s %8T%-?s ref %-8s path\n", 1337 "iodev", "dev", "io"); 1338 } 1339 1340 mdb_printf("%0?p %8T%0?p %3d %-8s %s\n", 1341 addr, iodev->si_dev, iodev->si_refcnt, io_name, path); 1342 1343 if (!v_opt) 1344 return (DCMD_OK); 1345 1346 mdb_inc_indent(4); 1347 1348 mdb_printf("open fds: %?p %8Tactive ios: %?p\n", 1349 iodev->si_open, iodev->si_active); 1350 1351 mdb_printf("busy: %d %8Trsrv pend: %d\n", 1352 iodev->si_busy, iodev->si_rpend); 1353 1354 mdb_printf("pend: %08x <%b>\n", iodev->si_pend, 1355 iodev->si_pend, nsc_availpend_bits); 1356 1357 mdb_printf("avail: %08x <%b>\n", iodev->si_avail, 1358 iodev->si_avail, nsc_availpend_bits); 1359 1360 mdb_dec_indent(4); 1361 1362 return (DCMD_OK); 1363 } 1364 1365 1366 /* ---------------------------------------------------------------------- */ 1367 1368 /* 1369 * Display an nsc_service_t structure, or walk all services. 1370 */ 1371 static int 1372 nsc_service(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1373 { 1374 nsc_service_t *service; 1375 char s_name[32]; 1376 int v_opt; 1377 1378 v_opt = 0; 1379 1380 if (mdb_getopts(argc, argv, 1381 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1382 return (DCMD_USAGE); 1383 1384 if (!(flags & DCMD_ADDRSPEC)) { 1385 if (mdb_walk_dcmd("nsctl`nsc_service", 1386 "nsctl`nsc_service", argc, argv) == -1) { 1387 mdb_warn("failed to walk 'nsc_service'"); 1388 return (DCMD_ERR); 1389 } 1390 1391 return (DCMD_OK); 1392 } 1393 1394 service = mdb_zalloc(sizeof (*service), UM_SLEEP | UM_GC); 1395 1396 if (mdb_vread(service, sizeof (*service), addr) != sizeof (*service)) { 1397 mdb_warn("failed to read nsc_service at %p", addr); 1398 return (DCMD_ERR); 1399 } 1400 1401 if (DCMD_HDRSPEC(flags)) { 1402 mdb_printf("%-?s %8Tname\n", "service"); 1403 } 1404 1405 memset(s_name, 0, sizeof (s_name)); 1406 if (service->s_name) { 1407 if (mdb_readstr(s_name, sizeof (s_name), 1408 (uintptr_t)service->s_name) == -1) { 1409 mdb_warn("failed to read nsc_io_t.name"); 1410 return (DCMD_ERR); 1411 } 1412 } 1413 1414 mdb_printf("%0?p %8T%s\n", addr, s_name); 1415 1416 if (!v_opt) 1417 return (DCMD_OK); 1418 1419 mdb_inc_indent(4); 1420 1421 mdb_printf("servers:\n"); 1422 if (service->s_servers == NULL) { 1423 mdb_printf("<none>\n"); 1424 } else { 1425 mdb_inc_indent(4); 1426 if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc", 1427 argc, argv, (uintptr_t)service->s_servers) == -1) { 1428 mdb_dec_indent(8); 1429 return (DCMD_ERR); 1430 } 1431 mdb_dec_indent(4); 1432 } 1433 1434 mdb_printf("clients:\n"); 1435 if (service->s_clients == NULL) { 1436 mdb_printf("<none>\n"); 1437 } else { 1438 mdb_inc_indent(4); 1439 if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc", 1440 argc, argv, (uintptr_t)service->s_clients) == -1) { 1441 mdb_dec_indent(8); 1442 return (DCMD_ERR); 1443 } 1444 mdb_dec_indent(4); 1445 } 1446 1447 mdb_dec_indent(4); 1448 1449 return (DCMD_OK); 1450 } 1451 1452 1453 /* ---------------------------------------------------------------------- */ 1454 1455 /* 1456 * Display an nsc_svc_t structure. 1457 */ 1458 /*ARGSUSED*/ 1459 static int 1460 nsc_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1461 { 1462 nsc_svc_t *svc; 1463 1464 if (!(flags & DCMD_ADDRSPEC)) 1465 return (DCMD_USAGE); 1466 1467 svc = mdb_zalloc(sizeof (*svc), UM_SLEEP | UM_GC); 1468 1469 if (mdb_vread(svc, sizeof (*svc), addr) != sizeof (*svc)) { 1470 mdb_warn("failed to read nsc_svc at %p", addr); 1471 return (DCMD_ERR); 1472 } 1473 1474 if (DCMD_HDRSPEC(flags)) { 1475 mdb_printf("%-?s %8T%-?s %8Tfunc\n", "svc", "service"); 1476 } 1477 1478 mdb_printf("%0?p %8T%0?p %8T%a\n", addr, svc->svc_svc, svc->svc_fn); 1479 return (DCMD_OK); 1480 } 1481 1482 1483 /* ---------------------------------------------------------------------- */ 1484 1485 /* 1486 * Display a single nsc_val_t structure. 1487 * If called with no address, performs a global walk of all nsc_devs. 1488 */ 1489 /* ARGSUSED3 */ 1490 static int 1491 nsc_val(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1492 { 1493 nsc_val_t *vp; 1494 1495 if (argc != 0) 1496 return (DCMD_USAGE); 1497 1498 if (!(flags & DCMD_ADDRSPEC)) { 1499 mdb_warn("nsc_val requires an address"); 1500 return (DCMD_ERR); 1501 } 1502 1503 vp = mdb_zalloc(sizeof (*vp), UM_SLEEP | UM_GC); 1504 1505 if (mdb_vread(vp, sizeof (*vp), addr) != sizeof (*vp)) { 1506 mdb_warn("failed to read nsc_val at %p", addr); 1507 return (DCMD_ERR); 1508 } 1509 1510 if (DCMD_HDRSPEC(flags)) { 1511 mdb_printf("%-?s %8T%8-s %8Tname\n", "val", "value"); 1512 } 1513 1514 mdb_printf("%0?p %8T%08x %8T%s\n", addr, vp->sv_value, vp->sv_name); 1515 1516 return (DCMD_OK); 1517 } 1518 1519 1520 /* ---------------------------------------------------------------------- */ 1521 1522 /* 1523 * Display an nstset_t structure, or walk all sets. 1524 */ 1525 1526 static int 1527 nstset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1528 { 1529 nstset_t *set; 1530 int f_opt, r_opt, t_opt, v_opt; 1531 1532 f_opt = r_opt = t_opt = v_opt = 0; 1533 1534 if (mdb_getopts(argc, argv, 1535 'f', MDB_OPT_SETBITS, TRUE, &f_opt, /* free list */ 1536 'r', MDB_OPT_SETBITS, TRUE, &r_opt, /* reuse list */ 1537 't', MDB_OPT_SETBITS, TRUE, &t_opt, /* all threads */ 1538 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1539 return (DCMD_USAGE); 1540 1541 /* displaying threads implies verbose */ 1542 if (f_opt || r_opt || t_opt) 1543 v_opt = 1; 1544 1545 if (!(flags & DCMD_ADDRSPEC)) { 1546 if (mdb_walk_dcmd("nsctl`nstset", 1547 "nsctl`nstset", argc, argv) == -1) { 1548 mdb_warn("failed to walk 'nstset'"); 1549 return (DCMD_ERR); 1550 } 1551 1552 return (DCMD_OK); 1553 } 1554 1555 set = mdb_zalloc(sizeof (*set), UM_SLEEP | UM_GC); 1556 1557 if (mdb_vread(set, sizeof (*set), addr) != sizeof (*set)) { 1558 mdb_warn("failed to read nstset at %p", addr); 1559 return (DCMD_ERR); 1560 } 1561 1562 if (DCMD_HDRSPEC(flags)) { 1563 mdb_printf("%-?s %8T live nthr flag name\n", "set"); 1564 } 1565 1566 mdb_printf("%0?p %8T%6d %6d %4x %s\n", addr, 1567 set->set_nlive, set->set_nthread, set->set_flag, set->set_name); 1568 1569 if (!v_opt) 1570 return (DCMD_OK); 1571 1572 mdb_inc_indent(4); 1573 1574 mdb_printf("chain: %0?p %8Tpending: %4d res_cnt: %4d\n", 1575 set->set_chain, set->set_pending, set->set_res_cnt); 1576 1577 if (set->set_reuse.q_forw == set->set_reuse.q_back && 1578 (uintptr_t)set->set_reuse.q_forw == 1579 (addr + OFFSETOF(nstset_t, set_reuse))) { 1580 mdb_printf("reuse.forw: %-?s %8Treuse.back: %s\n", 1581 "empty", "empty"); 1582 } else { 1583 mdb_printf("reuse.forw: %0?p %8Treuse.back: %0?p\n", 1584 set->set_reuse.q_forw, set->set_reuse.q_back); 1585 1586 /* display all threads in reuse list */ 1587 if (r_opt && 1588 mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread", 1589 0, (const mdb_arg_t *)NULL, 1590 (addr + OFFSETOF(nstset_t, set_reuse))) == -1) { 1591 mdb_dec_indent(4); 1592 return (DCMD_ERR); 1593 } 1594 } 1595 1596 if (set->set_free.q_forw == set->set_free.q_back && 1597 (uintptr_t)set->set_free.q_forw == 1598 (addr + OFFSETOF(nstset_t, set_free))) { 1599 mdb_printf("free.forw: %-?s %8Tfree.back: %s\n", 1600 "empty", "empty"); 1601 } else { 1602 mdb_printf("free.forw: %0?p %8Tfree.back: %0?p\n", 1603 set->set_free.q_forw, set->set_free.q_back); 1604 1605 /* display all threads in free list */ 1606 if (f_opt && 1607 mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread", 1608 0, (const mdb_arg_t *)NULL, 1609 (addr + OFFSETOF(nstset_t, set_free))) == -1) { 1610 mdb_dec_indent(4); 1611 return (DCMD_ERR); 1612 } 1613 } 1614 1615 mdb_printf("flag: %08x <%b>\n", 1616 set->set_flag, set->set_flag, nstset_flag_bits); 1617 1618 /* display all threads in set */ 1619 if (t_opt) { 1620 mdb_printf("all threads in set:\n"); 1621 if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread", 1622 0, (const mdb_arg_t *)NULL, 1623 (uintptr_t)set->set_chain) == -1) { 1624 mdb_dec_indent(4); 1625 return (DCMD_ERR); 1626 } 1627 } 1628 1629 mdb_dec_indent(4); 1630 1631 return (DCMD_OK); 1632 } 1633 1634 1635 /* ---------------------------------------------------------------------- */ 1636 1637 /* 1638 * Callback for the all nstsets and threads walk. Called per set. 1639 */ 1640 /* ARGSUSED */ 1641 static int 1642 nst_thr_set(uintptr_t addr, const void *data, void *cbdata) 1643 { 1644 struct complex_args *thrall = cbdata; 1645 char set_name[48]; 1646 uintptr_t tp; 1647 1648 if (mdb_vread(&tp, sizeof (tp), 1649 addr + OFFSETOF(nstset_t, set_chain)) == -1) { 1650 mdb_warn("unable to read nstset_t.set_chain at %p", addr); 1651 return (WALK_ERR); 1652 } 1653 1654 memset(set_name, 0, sizeof (set_name)); 1655 1656 if (mdb_readstr(set_name, sizeof (set_name), 1657 addr + OFFSETOF(nstset_t, set_name)) == -1) { 1658 mdb_warn("unable to read nstset_t.set_name at %p", addr); 1659 } 1660 1661 mdb_printf("nstset: %0?p (%s)\n", addr, set_name); 1662 1663 /* walk thread chains */ 1664 1665 if (tp != NULL) { 1666 if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread", 1667 thrall->argc, thrall->argv, tp) == -1) 1668 return (WALK_ERR); 1669 } else 1670 mdb_printf(" no threads\n"); 1671 1672 mdb_printf("\n"); 1673 1674 return (WALK_NEXT); 1675 } 1676 1677 1678 /* 1679 * Walk all nstsets and threads in the system. 1680 */ 1681 static int 1682 nst_thr_all(int argc, const mdb_arg_t *argv) 1683 { 1684 struct complex_args thrall; 1685 1686 thrall.argc = argc; 1687 thrall.argv = (mdb_arg_t *)argv; 1688 1689 if (mdb_walk("nsctl`nstset", nst_thr_set, &thrall) == -1) 1690 return (DCMD_ERR); 1691 1692 return (DCMD_OK); 1693 } 1694 1695 1696 /* 1697 * Display an nsthread_t structure, or walk all threads. 1698 */ 1699 1700 static int 1701 nsthread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1702 { 1703 uintptr_t thrpend; 1704 nsthread_t *tp; 1705 int a_opt, v_opt; 1706 int rc; 1707 1708 a_opt = v_opt = 0; 1709 1710 if (mdb_getopts(argc, argv, 1711 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 1712 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1713 return (DCMD_USAGE); 1714 1715 if (!(flags & DCMD_ADDRSPEC)) { 1716 if ((rc = nst_thr_all(argc, argv)) != DCMD_OK) 1717 return (rc); 1718 1719 if (a_opt) { 1720 if (mdb_readvar(&thrpend, "nst_pending") == -1) { 1721 mdb_warn("unable to read 'nst_pending'"); 1722 return (DCMD_ERR); 1723 } 1724 1725 if (thrpend) { 1726 mdb_printf("\nPending threads:\n"); 1727 1728 if (mdb_pwalk_dcmd("nsctl`nsthread", 1729 "nsctl`nsthread", argc, argv, 1730 thrpend) == -1) { 1731 mdb_warn("failed to walk 'nsthread'"); 1732 return (DCMD_ERR); 1733 } 1734 } 1735 } 1736 1737 return (DCMD_OK); 1738 } 1739 1740 tp = mdb_zalloc(sizeof (*tp), UM_SLEEP | UM_GC); 1741 1742 if (mdb_vread(tp, sizeof (*tp), addr) != sizeof (*tp)) { 1743 mdb_warn("failed to read nsthread at %p", addr); 1744 return (DCMD_ERR); 1745 } 1746 1747 if (DCMD_HDRSPEC(flags)) { 1748 mdb_printf("%-?s %8Tflag %-?s %8Tfunc\n", "thread", "arg"); 1749 } 1750 1751 mdb_printf("%0?p %8T%4x %0?p %8T%a\n", 1752 addr, tp->tp_flag, tp->tp_arg, tp->tp_func); 1753 1754 if (!v_opt) 1755 return (DCMD_OK); 1756 1757 mdb_inc_indent(4); 1758 1759 mdb_printf("set: %0?p %8Tchain: %0?p\n", 1760 tp->tp_set, tp->tp_chain); 1761 1762 mdb_printf("link.forw: %0?p %8Tlink.back: %0?p\n", 1763 tp->tp_link.q_forw, tp->tp_link.q_back); 1764 1765 mdb_printf("flag: %08x <%b>\n", 1766 tp->tp_flag, tp->tp_flag, nst_flag_bits); 1767 1768 mdb_dec_indent(4); 1769 1770 return (DCMD_OK); 1771 } 1772 1773 1774 /* ---------------------------------------------------------------------- */ 1775 1776 static void 1777 nsc_rmap(char *name) 1778 { 1779 nsc_rmmap_t slot; 1780 uintptr_t addr; 1781 int nslot; 1782 char *cp; 1783 1784 if (mdb_readvar(&addr, name) == -1) { 1785 mdb_warn("unable to read rmap '%s'", name); 1786 return; 1787 } 1788 1789 if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) { 1790 mdb_warn("unable to read rmap '%s' slot 0", name); 1791 return; 1792 } 1793 1794 mdb_printf("\nmap name offset size nslot\n"); 1795 mdb_printf("%16s %9d %9d %5d\n", 1796 slot.name, slot.offset, slot.size, slot.inuse); 1797 1798 nslot = slot.inuse; 1799 mdb_printf("\nslot name offset size inuse\n"); 1800 1801 while (--nslot) { 1802 addr += sizeof (slot); 1803 1804 if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) { 1805 mdb_warn("unable to read rmap '%s' slot @ %p", 1806 name, addr); 1807 return; 1808 } 1809 1810 if (!slot.inuse || !slot.size) 1811 continue; 1812 1813 for (cp = slot.name; *cp; cp++) 1814 if (*cp == ':') 1815 *cp = ' '; 1816 1817 mdb_printf("%16s %9d %9d %08x\n", 1818 slot.name, slot.offset, slot.size, slot.inuse); 1819 } 1820 } 1821 1822 1823 static void 1824 nsc_rmhdr(void) 1825 { 1826 nsc_rmhdr_t *rmhdr = mdb_zalloc(sizeof (*rmhdr), UM_SLEEP | UM_GC); 1827 uintptr_t addr; 1828 1829 if (mdb_readvar(&addr, "_nsc_rmhdr_ptr") == -1) { 1830 mdb_warn("unable to read _nsc_rmhdr_ptr"); 1831 return; 1832 } 1833 1834 if (!addr) { 1835 mdb_printf("\n\nGlobal header not initialised\n"); 1836 return; 1837 } 1838 1839 if (mdb_vread(rmhdr, sizeof (*rmhdr), addr) != sizeof (*rmhdr)) { 1840 mdb_warn("unable to read global header at %p", addr); 1841 return; 1842 } 1843 1844 mdb_printf("\n\nglobal header (magic %08x, version %d, size %d)\n", 1845 rmhdr->magic, rmhdr->ver, rmhdr->size); 1846 1847 nsc_rmap("_nsc_global_map"); 1848 } 1849 1850 1851 static nsc_mem_t * 1852 memptr(int type, int flag) 1853 { 1854 int i; 1855 1856 type &= NSC_MEM_GLOBAL; 1857 1858 if (type) 1859 flag = 0; 1860 1861 if (!type && !flag) 1862 return (&type_mem[0]); 1863 1864 for (i = 1; i < (sizeof (type_mem) / sizeof (nsc_mem_t)); i++) { 1865 if (!type_mem[i].flag && !type_mem[i].type) { 1866 type_mem[i].flag = flag; 1867 type_mem[i].type = type; 1868 return (&type_mem[i]); 1869 } 1870 1871 if (type_mem[i].flag == flag && type_mem[i].type == type) 1872 return (&type_mem[i]); 1873 } 1874 1875 return (&type_mem[i]); 1876 } 1877 1878 1879 #define typename(t) \ 1880 (((t) & NSC_MEM_GLOBAL) ? "gbl" : " - ") 1881 1882 #define memname(t) \ 1883 (((t) & NSC_MEM_GLOBAL) ? "nsc_global" : "system kmem") 1884 1885 static void 1886 nsc_mem_type(const int first, nsc_mem_t *mp) 1887 { 1888 char *type, *name; 1889 1890 if (first) { 1891 mdb_printf("\nregion typ f "); 1892 mdb_printf("used hwm pgs alloc free\n"); 1893 } 1894 1895 type = typename(mp->type); 1896 name = memname(mp->type); 1897 1898 mdb_printf("%16s %s %2x %9d %9d %6d %5d %5d\n", 1899 name, type, mp->flag, mp->used, mp->hwm, mp->pagehwm, 1900 mp->nalloc, mp->nfree); 1901 } 1902 1903 1904 static int 1905 nsc_mem_all(int argc, const mdb_arg_t *argv, int v_opt) 1906 { 1907 int first; 1908 int i; 1909 1910 memset(type_mem, 0, sizeof (type_mem)); 1911 1912 if (mdb_walk_dcmd("nsctl`nsc_mem", 1913 "nsctl`nsc_mem", argc, argv) == -1) { 1914 mdb_warn("unable to walk 'nsc_mem'"); 1915 return (DCMD_ERR); 1916 } 1917 1918 for (first = 1, i = 0; 1919 i < (sizeof (type_mem) / sizeof (nsc_mem_t)); first = 0, i++) { 1920 if (type_mem[i].nalloc || type_mem[i].hwm) { 1921 nsc_mem_type(first, &type_mem[i]); 1922 } 1923 } 1924 1925 if (v_opt) 1926 nsc_rmhdr(); 1927 1928 return (DCMD_OK); 1929 } 1930 1931 1932 static int 1933 nsc_mem(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1934 { 1935 char name[16], *type, *cp; 1936 nsc_mem_t mem, *mp; 1937 int v_opt; 1938 1939 v_opt = 0; 1940 1941 if (mdb_getopts(argc, argv, 1942 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 1943 return (DCMD_USAGE); 1944 1945 if (!(flags & DCMD_ADDRSPEC)) { 1946 return (nsc_mem_all(argc, argv, v_opt)); 1947 } 1948 1949 if (mdb_vread(&mem, sizeof (mem), addr) != sizeof (mem)) { 1950 mdb_warn("failed to read nsc_mem_t at %p", addr); 1951 return (DCMD_ERR); 1952 } 1953 1954 if (mdb_readstr(name, sizeof (name), (uintptr_t)mem.name) == -1) { 1955 mdb_warn("failed to read nsc_mem_t.name at %p", addr); 1956 return (DCMD_ERR); 1957 } 1958 1959 if (!mem.nalloc && !mem.hwm && !v_opt) 1960 return (DCMD_OK); 1961 1962 if (DCMD_HDRSPEC(flags)) { 1963 mdb_printf("name typ f "); 1964 mdb_printf("used hwm pgs alloc free base\n"); 1965 } 1966 1967 type = typename(mem.type); 1968 mp = memptr(mem.type, mem.flag); 1969 1970 for (cp = name; *cp; cp++) 1971 if (*cp == ':') 1972 *cp = ' '; 1973 1974 mdb_printf("%-16s %s %2x %9d %9d %5d %5d %5d %0?p\n", 1975 name, type, mem.flag, mem.used, mem.hwm, mem.pagehwm, 1976 mem.nalloc, mem.nfree, mem.base); 1977 1978 mp->used += mem.used; 1979 mp->hwm += mem.hwm; 1980 mp->pagehwm += mem.pagehwm; 1981 mp->nalloc += mem.nalloc; 1982 mp->nfree += mem.nfree; 1983 1984 return (DCMD_OK); 1985 } 1986 1987 /*ARGSUSED*/ 1988 static int 1989 nsc_vec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1990 { 1991 nsc_vec_t *vec; 1992 1993 vec = mdb_zalloc(sizeof (*vec), UM_SLEEP | UM_GC); 1994 if (mdb_vread(vec, sizeof (*vec), addr) != sizeof (*vec)) { 1995 mdb_warn("failed to read nsc_vec at %p", addr); 1996 return (DCMD_ERR); 1997 } 1998 mdb_printf("nsc_vec_t @ 0x%p = {\n", addr); 1999 mdb_inc_indent(4); 2000 mdb_printf("sv_addr: %p\n", vec->sv_addr); 2001 mdb_printf("sv_vme: %lu\n", vec->sv_vme); 2002 mdb_printf("sv_len: %d\n", vec->sv_len); 2003 mdb_dec_indent(4); 2004 mdb_printf("};\n"); 2005 if (vec->sv_addr) 2006 return (DCMD_OK); 2007 else 2008 return (DCMD_ERR); 2009 } 2010 2011 /* ---------------------------------------------------------------------- */ 2012 /* 2013 * Display an nsc_buf_t structure. 2014 */ 2015 2016 #ifdef NSC_MULTI_TERABYTE 2017 #define STRCONV "ll" 2018 #else 2019 #define STRCONV "" 2020 #endif 2021 2022 /* ARGSUSED */ 2023 static int 2024 nsc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2025 { 2026 nsc_buf_t *bh; 2027 nsc_vec_t *v; 2028 2029 if (!(flags & DCMD_ADDRSPEC)) 2030 return (DCMD_USAGE); 2031 2032 bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC); 2033 2034 if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) { 2035 mdb_warn("failed to read nsc_buf at %p", addr); 2036 return (DCMD_ERR); 2037 } 2038 2039 mdb_printf("nsc_buf_t @ 0x%p = {\n", addr); 2040 mdb_inc_indent(4); 2041 mdb_printf("sb_fd: 0x%p\n", bh->sb_fd); 2042 mdb_printf("sb_pos: 0x%" STRCONV "x\n", bh->sb_pos); 2043 mdb_printf("sb_len: 0x%" STRCONV "x\n", bh->sb_len); 2044 mdb_printf("sb_flag: 0x%08x <%b>\n", bh->sb_flag, 2045 bh->sb_flag, nsc_bhflag_bits); 2046 mdb_printf("sb_error: %d\n", bh->sb_error); 2047 #ifdef NSC_MULTI_TERABYTE 2048 mdb_printf("sb_user: 0x%p\n", bh->sb_user); 2049 #else 2050 mdb_printf("sb_user: 0x%x\n", bh->sb_user); 2051 #endif 2052 mdb_printf("sb_vec: 0x%p\n", bh->sb_vec); 2053 v = bh->sb_vec++; 2054 while (nsc_vec((uintptr_t)v, flags, argc, argv) == DCMD_OK) 2055 v++; 2056 2057 mdb_dec_indent(4); 2058 mdb_printf("};\n"); 2059 2060 return (DCMD_OK); 2061 } 2062 2063 /* ---------------------------------------------------------------------- */ 2064 2065 /* ARGSUSED */ 2066 static int 2067 nsc_dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2068 { 2069 nsc_dbuf_t *bh; 2070 2071 if (!(flags & DCMD_ADDRSPEC)) 2072 return (DCMD_USAGE); 2073 2074 bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC); 2075 2076 if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) { 2077 mdb_warn("failed to read nsc_dbuf at %p", addr); 2078 return (DCMD_ERR); 2079 } 2080 2081 mdb_printf("nsc_dbuf_t @ 0x%p = {\n", addr); 2082 mdb_inc_indent(4); 2083 mdb_printf("db_disc: 0x%p\n", bh->db_disc); 2084 mdb_printf("db_addr: 0x%p\n", bh->db_addr); 2085 mdb_printf("db_next: 0x%p\n", bh->db_next); 2086 mdb_printf("db_maxfbas: 0x%d\n", bh->db_maxfbas); 2087 2088 2089 mdb_dec_indent(4); 2090 mdb_printf("};\n"); 2091 2092 return (DCMD_OK); 2093 } 2094 /* ---------------------------------------------------------------------- */ 2095 2096 /* 2097 * MDB module linkage information: 2098 */ 2099 2100 static const mdb_dcmd_t dcmds[] = { 2101 #if 0 2102 { "nsctl", NULL, "display nsctl module info", nsctl }, 2103 #endif 2104 { "nsc_buf", ":", "list nsc_buf structure", nsc_buf }, 2105 { "nsc_dbuf", ":", "list nsc_dbuf structure", nsc_dbuf }, 2106 { "nsc_dev", "?[-av]", "list nsc_dev structure", nsc_dev }, 2107 { "nsc_devval", "?[-a]", "list nsc_devval structure", nsc_devval }, 2108 { "nsc_fd", "?[-v]", "list nsc_fd structure", nsc_fd }, 2109 { "nsc_iodev", "?[-v]", "list nsc_iodev structure", nsc_iodev }, 2110 { "nsc_io", "?[-v]", "list nsc_io structure", nsc_io }, 2111 { "nsc_mem", "?[-v]", "list nsc_mem structure", nsc_mem }, 2112 { "nsc_svc", ":", "list nsc_svc structure", nsc_svc }, 2113 { "nsc_service", "?[-v]", "list nsc_service structure", nsc_service }, 2114 { "nsc_val", ":", "list nsc_val structure", nsc_val }, 2115 { "nstset", "?[-frtv]", "list nstset structure", nstset }, 2116 { "nsthread", "?[-av]", "list nsthread structure", nsthread }, 2117 { NULL } 2118 }; 2119 2120 2121 static const mdb_walker_t walkers[] = { 2122 { "nsc_dev", "walk nsc_dev chain", 2123 nsc_dev_winit, nsc_dev_wstep, nsc_dev_wfini, NULL }, 2124 { "nsc_devval", "walk nsc_devval chain", 2125 nsc_devval_winit, nsc_devval_wstep, NULL, NULL }, 2126 { "nsc_fd", "walk nsc_fd chain", 2127 nsc_fd_winit, nsc_fd_wstep, NULL, NULL }, 2128 { "nsc_io", "walk nsc_io chain", 2129 nsc_io_winit, nsc_io_wstep, NULL, NULL }, 2130 { "nsc_iodev", "walk nsc_iodev chain", 2131 nsc_iodev_winit, nsc_iodev_wstep, NULL, NULL }, 2132 { "nsc_mem", "walk nsc_mem chain", 2133 nsc_mem_winit, nsc_mem_wstep, NULL, NULL }, 2134 { "nsc_service", "walk nsc_service chain", 2135 nsc_service_winit, nsc_service_wstep, NULL, NULL }, 2136 { "nsc_svc", "walk nsc_svc chain", 2137 nsc_svc_winit, nsc_svc_wstep, NULL, NULL }, 2138 { "nsc_val", "walk nsc_val chain", 2139 nsc_val_winit, nsc_val_wstep, NULL, NULL }, 2140 { "nstset", "walk nstset chain", 2141 nstset_winit, nstset_wstep, NULL, NULL }, 2142 { "nsthread", "walk nsthread chain", 2143 nsthread_winit, nsthread_wstep, NULL, NULL }, 2144 { "nst_free", "walk nsthread free/reuse list", 2145 nst_free_winit, nst_free_wstep, NULL, NULL }, 2146 { NULL } 2147 }; 2148 2149 2150 static const mdb_modinfo_t modinfo = { 2151 MDB_API_VERSION, dcmds, walkers 2152 }; 2153 2154 2155 const mdb_modinfo_t * 2156 _mdb_init(void) 2157 { 2158 return (&modinfo); 2159 }