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 #include <rpc/auth.h> 34 #include <rpc/auth_unix.h> 35 #include <rpc/auth_des.h> 36 #include <rpc/svc.h> 37 #include <rpc/xdr.h> 38 #include <rpc/svc_soc.h> 39 40 /* HACK HACK so we can bring in rdc_io.h and friends */ 41 #define nstset_t char 42 43 #include <sys/nsctl/rdc.h> 44 #include <sys/nsctl/rdc_prot.h> 45 #include <sys/nsctl/rdc_ioctl.h> 46 #include <sys/nsctl/rdc_io.h> 47 #include <sys/nsctl/rdc_bitmap.h> 48 49 #include <sys/nsctl/nsvers.h> 50 51 52 /* 53 * Walker for an array of rdc_k_info_t structures. 54 * A global walk is assumed to start at rdc_k_info. 55 */ 56 57 struct rdc_kinfo_winfo { 58 uintptr_t start; 59 uintptr_t end; 60 }; 61 62 char bitstr[33] = { '0' }; 63 64 static int 65 rdc_k_info_winit(mdb_walk_state_t *wsp) 66 { 67 struct rdc_kinfo_winfo *winfo; 68 rdc_k_info_t *rdc_k_info; 69 int rdc_max_sets; 70 71 winfo = mdb_zalloc(sizeof (struct rdc_kinfo_winfo), UM_SLEEP); 72 73 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 74 mdb_warn("failed to read 'rdc_k_info'"); 75 mdb_free(winfo, sizeof (struct rdc_kinfo_winfo)); 76 return (WALK_ERR); 77 } 78 79 if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) { 80 mdb_warn("failed to read 'rdc_max_sets'"); 81 mdb_free(winfo, sizeof (struct rdc_kinfo_winfo)); 82 return (WALK_ERR); 83 } 84 85 winfo->start = (uintptr_t)rdc_k_info; 86 winfo->end = (uintptr_t)(rdc_k_info + rdc_max_sets); 87 88 if (wsp->walk_addr == NULL) 89 wsp->walk_addr = winfo->start; 90 91 wsp->walk_data = winfo; 92 return (WALK_NEXT); 93 } 94 95 96 static int 97 rdc_k_info_wstep(mdb_walk_state_t *wsp) 98 { 99 struct rdc_kinfo_winfo *winfo = wsp->walk_data; 100 int status; 101 102 if (wsp->walk_addr == NULL) 103 return (WALK_DONE); 104 105 if (wsp->walk_addr >= winfo->end) 106 return (WALK_DONE); 107 108 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 109 wsp->walk_cbdata); 110 111 wsp->walk_addr += sizeof (rdc_k_info_t); 112 return (status); 113 } 114 115 116 static void 117 rdc_k_info_wfini(mdb_walk_state_t *wsp) 118 { 119 mdb_free(wsp->walk_data, sizeof (struct rdc_kinfo_winfo)); 120 } 121 122 /* 123 * Walker for an array of rdc_u_info_t structures. 124 * A global walk is assumed to start at rdc_u_info. 125 */ 126 127 struct rdc_uinfo_winfo { 128 uintptr_t start; 129 uintptr_t end; 130 }; 131 132 133 static int 134 rdc_u_info_winit(mdb_walk_state_t *wsp) 135 { 136 struct rdc_uinfo_winfo *winfo; 137 rdc_u_info_t *rdc_u_info; 138 int rdc_max_sets; 139 140 winfo = mdb_zalloc(sizeof (struct rdc_uinfo_winfo), UM_SLEEP); 141 142 if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { 143 mdb_warn("failed to read 'rdc_u_info'"); 144 mdb_free(winfo, sizeof (struct rdc_uinfo_winfo)); 145 return (WALK_ERR); 146 } 147 148 if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) { 149 mdb_warn("failed to read 'rdc_max_sets'"); 150 mdb_free(winfo, sizeof (struct rdc_uinfo_winfo)); 151 return (WALK_ERR); 152 } 153 154 winfo->start = (uintptr_t)rdc_u_info; 155 winfo->end = (uintptr_t)(rdc_u_info + rdc_max_sets); 156 157 if (wsp->walk_addr == NULL) 158 wsp->walk_addr = winfo->start; 159 160 wsp->walk_data = winfo; 161 return (WALK_NEXT); 162 } 163 164 165 static int 166 rdc_u_info_wstep(mdb_walk_state_t *wsp) 167 { 168 struct rdc_uinfo_winfo *winfo = wsp->walk_data; 169 int status; 170 171 if (wsp->walk_addr == NULL) 172 return (WALK_DONE); 173 174 if (wsp->walk_addr >= winfo->end) 175 return (WALK_DONE); 176 177 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 178 wsp->walk_cbdata); 179 180 wsp->walk_addr += sizeof (rdc_u_info_t); 181 return (status); 182 } 183 184 185 static void 186 rdc_u_info_wfini(mdb_walk_state_t *wsp) 187 { 188 mdb_free(wsp->walk_data, sizeof (struct rdc_uinfo_winfo)); 189 } 190 191 /* 192 * Walker for the rdc_if chain. 193 * A global walk is assumed to start at rdc_if_top. 194 */ 195 196 static int 197 rdc_if_winit(mdb_walk_state_t *wsp) 198 { 199 if (wsp->walk_addr == NULL && 200 mdb_readvar(&wsp->walk_addr, "rdc_if_top") == -1) { 201 mdb_warn("unable to read 'rdc_if_top'"); 202 return (WALK_ERR); 203 } 204 205 wsp->walk_data = mdb_zalloc(sizeof (rdc_if_t), UM_SLEEP); 206 207 return (WALK_NEXT); 208 } 209 210 211 static int 212 rdc_if_wstep(mdb_walk_state_t *wsp) 213 { 214 int status; 215 216 if (wsp->walk_addr == NULL) 217 return (WALK_DONE); 218 219 if (mdb_vread(wsp->walk_data, 220 sizeof (rdc_if_t), wsp->walk_addr) == -1) { 221 mdb_warn("failed to read rdc_if at %p", wsp->walk_addr); 222 return (WALK_DONE); 223 } 224 225 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 226 wsp->walk_cbdata); 227 228 wsp->walk_addr = (uintptr_t)(((rdc_if_t *)wsp->walk_data)->next); 229 return (status); 230 } 231 232 233 static void 234 rdc_if_wfini(mdb_walk_state_t *wsp) 235 { 236 mdb_free(wsp->walk_data, sizeof (rdc_if_t)); 237 } 238 239 /* 240 * Displays the asynchronous sleep q on the server. 241 */ 242 /*ARGSUSED*/ 243 static int 244 rdc_sleepq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 245 { 246 rdc_sleepq_t sq; 247 248 if (!(flags & DCMD_ADDRSPEC)) 249 return (DCMD_USAGE); 250 while (addr) { 251 if (mdb_vread(&sq, sizeof (sq), addr) != sizeof (sq)) { 252 mdb_warn("failed to read rdc_sleepq at %p", addr); 253 return (DCMD_ERR); 254 } 255 mdb_printf("sequence number %u qpos %d \n", sq.seq, sq.qpos); 256 addr = (uintptr_t)sq.next; 257 } 258 return (DCMD_OK); 259 } 260 261 /* 262 * display the header info for the pending diskq requests 263 */ 264 /*ARGSUSED*/ 265 static int 266 rdc_iohdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 267 { 268 io_hdr hdr; 269 270 if (!(flags & DCMD_ADDRSPEC)) 271 return (DCMD_USAGE); 272 273 while (addr) { 274 if (mdb_vread(&hdr, sizeof (io_hdr), addr) != sizeof (io_hdr)) { 275 mdb_warn("failed to read io_hdr at %p", addr); 276 return (DCMD_ERR); 277 } 278 mdb_printf("iohdr: type %d pos %d qpos %d len %d flag 0x%x" 279 " iostatus %x setid %d next %p\n", hdr.dat.type, hdr.dat.pos, 280 hdr.dat.qpos, hdr.dat.len, hdr.dat.flag, hdr.dat.iostatus, 281 hdr.dat.setid, hdr.dat.next); 282 283 addr = (uintptr_t)hdr.dat.next; 284 } 285 return (DCMD_OK); 286 } 287 288 /* 289 * Display a krdc->group. 290 * Requires an address. 291 */ 292 /*ARGSUSED*/ 293 static int 294 rdc_group(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 295 { 296 struct rdc_group *group; 297 disk_queue *dq; 298 299 if (!(flags & DCMD_ADDRSPEC)) 300 return (DCMD_USAGE); 301 302 303 group = mdb_zalloc(sizeof (*group), UM_GC); 304 305 if (mdb_vread(group, sizeof (*group), addr) != sizeof (*group)) { 306 mdb_warn("failed to read rdc_group at %p", addr); 307 return (DCMD_ERR); 308 } 309 #ifdef XXXJET 310 if (DCMD_HDRSPEC(flags)) { 311 mdb_printf("%-?s %8T%-8s %8T%s\n", "ADDR", "MAJOR", "INUSE"); 312 } 313 #endif 314 mdb_printf("count: %d %8Twriter: %d %8T flags: %d\n", 315 group->count, group->rdc_writer, group->flags); 316 mdb_printf("thread num %d\n", group->rdc_thrnum); 317 318 dq = &group->diskq; 319 if (RDC_IS_MEMQ(group)) { 320 mdb_printf("queue type: Memory based\n"); 321 } else if (RDC_IS_DISKQ(group)) { 322 mdb_printf("queue type: Disk based %8Tqstate 0x%x\n", 323 QSTATE(dq)); 324 } 325 mdb_printf("ra_queue head: 0x%p %8Ttail 0x%p\n", 326 group->ra_queue.net_qhead, group->ra_queue.net_qtail); 327 mdb_printf("ra_queue blocks: %d %8Titems %d\n", 328 group->ra_queue.blocks, group->ra_queue.nitems); 329 mdb_printf("ra_queue blockhwm: %d itemhwm: %d\n", 330 group->ra_queue.blocks_hwm, group->ra_queue.nitems_hwm); 331 mdb_printf("ra_queue hwmhit: %d qfillsleep: %d\n", 332 group->ra_queue.hwmhit, group->ra_queue.qfill_sleeping); 333 mdb_printf("ra_queue throttle: %ld\n", 334 group->ra_queue.throttle_delay); 335 336 if (RDC_IS_DISKQ(group)) { 337 mdb_printf("head: %d %8Tnxtio: %d %8Ttail %d %8Tlastail: %d\n", 338 QHEAD(dq), QNXTIO(dq), QTAIL(dq), LASTQTAIL(dq)); 339 mdb_printf("coalbounds: %d %8Tqwrap: %d\n", QCOALBOUNDS(dq), 340 QWRAP(dq)); 341 mdb_printf("blocks: %d %8Titems %d qfflags 0x%x \n", 342 QBLOCKS(dq), QNITEMS(dq), group->ra_queue.qfflags); 343 mdb_printf("diskq throttle: %ld %8Tflags: %x\n", 344 dq->throttle_delay, group->flags); 345 mdb_printf("disk queue nitems_hwm: %d %8Tblocks_hwm: %d\n", 346 dq->nitems_hwm, dq->blocks_hwm); 347 mdb_printf("diskqfd: 0x%p %8Tdisqrsrv: %d lastio: 0x%p\n", 348 group->diskqfd, group->diskqrsrv, dq->lastio); 349 mdb_printf("outstanding req %d iohdrs 0x%p iohdrs_last 0x%p\n", 350 dq->hdrcnt, dq->iohdrs, dq->hdr_last); 351 } 352 mdb_printf("seq: %u\n", group->seq); 353 mdb_printf("seqack: %u\n", group->seqack); 354 mdb_printf("sleepq: 0x%p\n", group->sleepq); 355 mdb_printf("asyncstall %d\n", group->asyncstall); 356 mdb_printf("asyncdis %d\n", group->asyncdis); 357 358 mdb_inc_indent(4); 359 if (group->sleepq) { 360 rdc_sleepq((uintptr_t)group->sleepq, DCMD_ADDRSPEC, 361 0, 0); 362 } 363 mdb_dec_indent(4); 364 365 return (DCMD_OK); 366 } 367 368 369 /* 370 * Display a krdc->lsrv. 371 * Requires an address. 372 */ 373 /*ARGSUSED*/ 374 static int 375 rdc_srv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 376 { 377 rdc_srv_t *lsrv; 378 char name[MAX_RDC_HOST_SIZE]; 379 380 if (!(flags & DCMD_ADDRSPEC)) 381 return (DCMD_USAGE); 382 383 384 lsrv = mdb_zalloc(sizeof (*lsrv), UM_GC); 385 386 if (mdb_vread(lsrv, sizeof (*lsrv), addr) != sizeof (*lsrv)) { 387 mdb_warn("failed to read rdc_srv at %p", addr); 388 return (DCMD_ERR); 389 } 390 391 if (mdb_readstr(name, sizeof (name), 392 (uintptr_t)lsrv->ri_hostname) == -1) { 393 mdb_warn("failed to read ri_hostname name at %p", addr); 394 return (DCMD_ERR); 395 } 396 397 mdb_printf("host: %s %16Tri_knconf 0x%p\n", name, lsrv->ri_knconf); 398 399 mdb_printf("ri_addr: 0x%p %8Tsecdata 0x%p\n", 400 addr + OFFSETOF(rdc_srv_t, ri_addr), lsrv->ri_secdata); 401 402 return (DCMD_OK); 403 } 404 405 /* 406 * Display a rdc_if_t. 407 * Requires an address. 408 */ 409 static int 410 rdc_if(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 411 { 412 rdc_if_t *ifp; 413 414 if (!(flags & DCMD_ADDRSPEC)) { 415 /* 416 * paranoid mode on: qualify walker name with module name 417 * using '`' syntax. 418 */ 419 if (mdb_walk_dcmd("rdc`rdc_if", 420 "rdc`rdc_if", argc, argv) == -1) { 421 mdb_warn("failed to walk 'rdc_if'"); 422 return (DCMD_ERR); 423 } 424 return (DCMD_OK); 425 } 426 427 ifp = mdb_zalloc(sizeof (*ifp), UM_GC); 428 429 if (mdb_vread(ifp, sizeof (*ifp), addr) != sizeof (*ifp)) { 430 mdb_warn("failed to read rdc_srv at %p", addr); 431 return (DCMD_ERR); 432 } 433 434 mdb_printf("next: 0x%p %8Tsrv 0x%p\n", ifp->next, ifp->srv); 435 mdb_printf("if_addr: 0x%p %8Tr_ifaddr 0x%p\n", 436 addr + OFFSETOF(rdc_if_t, ifaddr), 437 addr + OFFSETOF(rdc_if_t, r_ifaddr)); 438 mdb_printf("if_down: %d %8Tprimary %d %8Tsecondary %d\n", 439 ifp->if_down, ifp->isprimary, ifp->issecondary); 440 mdb_printf("version %d %8Tnoping %d\n", ifp->rpc_version, 441 ifp->no_ping); 442 mdb_printf("\n"); 443 444 return (DCMD_OK); 445 } 446 447 448 /* 449 * Display a rdc_buf_t 450 * Requires an address. 451 */ 452 /*ARGSUSED*/ 453 static int 454 rdc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 455 { 456 rdc_buf_t *buf; 457 458 if (!(flags & DCMD_ADDRSPEC)) 459 return (DCMD_USAGE); 460 461 462 buf = mdb_zalloc(sizeof (*buf), UM_GC); 463 464 if (mdb_vread(buf, sizeof (*buf), addr) != sizeof (*buf)) { 465 mdb_warn("failed to read rdc_buf at %p", addr); 466 return (DCMD_ERR); 467 } 468 469 mdb_printf("nsc_buf fd: 0x%p %8Tvec 0x%p\n", 470 buf->rdc_bufh.sb_fd, buf->rdc_bufh.sb_vec); 471 472 mdb_printf("nsc_buf pos: %d %8Tlen %d\n", 473 buf->rdc_bufh.sb_pos, buf->rdc_bufh.sb_len); 474 475 mdb_printf("nsc_buf flag: 0x%x %8Terror %d\n", 476 buf->rdc_bufh.sb_flag, buf->rdc_bufh.sb_error); 477 478 mdb_printf("anon_buf : 0x%p %8Tfd 0x%p %8Tbufp 0x%p\n", 479 buf->rdc_anon, buf->rdc_fd, buf->rdc_bufp); 480 481 mdb_printf("vsize: %d %8Tflags 0x%x\n", 482 buf->rdc_vsize, buf->rdc_flags); 483 484 return (DCMD_OK); 485 } 486 487 /*ARGSUSED*/ 488 static int 489 rdc_aio(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 490 { 491 rdc_aio_t *aio; 492 493 if (!(flags & DCMD_ADDRSPEC)) 494 return (DCMD_USAGE); 495 496 aio = mdb_zalloc(sizeof (*aio), UM_GC); 497 498 if (mdb_vread(aio, sizeof (*aio), addr) != sizeof (*aio)) { 499 mdb_warn("failed to read rdc_aio at %p", addr); 500 return (DCMD_ERR); 501 } 502 mdb_printf("rdc_aio next: %p %8T nsc_buf: %p %8T nsc_qbuf %p\n", 503 aio->next, aio->handle, aio->qhandle); 504 mdb_printf("pos: %d len: %d qpos: %d flag: %x iostatus: %d index: %d" 505 " seq: %d\n", aio->pos, aio->len, aio->qpos, aio->flag, 506 aio->iostatus, aio->index, aio->seq); 507 return (DCMD_OK); 508 } 509 510 /*ARGSUSED*/ 511 static int 512 rdc_dset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 513 { 514 rdc_net_dataset_t *dset; 515 516 if (!(flags & DCMD_ADDRSPEC)) 517 return (DCMD_USAGE); 518 519 dset = mdb_zalloc(sizeof (*dset), UM_GC); 520 521 if (mdb_vread(dset, sizeof (*dset), addr) != sizeof (*dset)) { 522 mdb_warn("failed to read dset at %p", addr); 523 return (DCMD_ERR); 524 } 525 mdb_printf("dset id: %d %8T dset inuse: %d %8T dset delpend: %d\n", 526 dset->id, dset->inuse, dset->delpend); 527 mdb_printf("dset items: %d %8T dset head %p %8T dset tail %p \n", 528 dset->nitems, dset->head, dset->tail); 529 mdb_printf("dset pos %d %8T dset len %d\n", dset->pos, dset->fbalen); 530 531 return (DCMD_OK); 532 } 533 /* 534 * Display a single rdc_k_info structure. 535 * If called with no address, performs a global walk of all rdc_k_info. 536 * -a : all (i.e. display all devices, even if disabled 537 * -v : verbose 538 */ 539 540 const mdb_bitmask_t sv_flag_bits[] = { 541 { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, 542 { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, 543 { NULL, 0, 0 } 544 }; 545 546 static int 547 rdc_kinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 548 { 549 rdc_k_info_t *krdc; 550 rdc_u_info_t *rdc_u_info, *urdc; 551 int a_opt, v_opt; 552 int dev_t_chars; 553 554 a_opt = v_opt = FALSE; 555 dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ 556 557 if (mdb_getopts(argc, argv, 558 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 559 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 560 return (DCMD_USAGE); 561 562 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 563 urdc = mdb_zalloc(sizeof (*urdc), UM_GC); 564 565 if (!(flags & DCMD_ADDRSPEC)) { 566 /* 567 * paranoid mode on: qualify walker name with module name 568 * using '`' syntax. 569 */ 570 if (mdb_walk_dcmd("rdc`rdc_kinfo", 571 "rdc`rdc_kinfo", argc, argv) == -1) { 572 mdb_warn("failed to walk 'rdc_kinfo'"); 573 return (DCMD_ERR); 574 } 575 return (DCMD_OK); 576 } 577 if (DCMD_HDRSPEC(flags)) { 578 mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", 579 dev_t_chars, "TFLAG", "STATE"); 580 } 581 582 if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { 583 mdb_warn("failed to read rdc_k_info at %p", addr); 584 return (DCMD_ERR); 585 } 586 587 if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { 588 mdb_warn("failed to read 'rdc_u_info'"); 589 return (DCMD_ERR); 590 } 591 592 urdc = &rdc_u_info[krdc->index]; 593 594 if (!a_opt && ((krdc->type_flag & RDC_CONFIGURED) == 0)) 595 return (DCMD_OK); 596 597 mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, krdc->type_flag); 598 599 600 if (krdc->type_flag & RDC_DISABLEPEND) 601 mdb_printf(" disable pending"); 602 if (krdc->type_flag & RDC_ASYNCMODE) 603 mdb_printf(" async"); 604 if (krdc->type_flag & RDC_RESUMEPEND) 605 mdb_printf(" resume pending"); 606 if (krdc->type_flag & RDC_BUSYWAIT) 607 mdb_printf(" busywait"); 608 #ifdef RDC_SMALLIO 609 if (krdc->type_flag & RDC_SMALLIO) 610 mdb_printf(" smallio"); 611 #endif 612 613 mdb_printf("\n"); 614 615 if (!v_opt) 616 return (DCMD_OK); 617 618 /* 619 * verbose - print the rest of the structure as well. 620 */ 621 622 mdb_inc_indent(4); 623 624 mdb_printf("index: %d %8Trindex: %d %8Tbusyc: %d %8Tmaxfbas: %d\n", 625 krdc->index, krdc->remote_index, krdc->busy_count, krdc->maxfbas); 626 627 mdb_printf("info_dev: 0x%p %8Tiodev: 0x%p %8T %8T vers %d\n", 628 krdc->devices, krdc->iodev, krdc->rpc_version); 629 630 mdb_printf("iokstats: 0x%p\n", krdc->io_kstats); 631 mdb_printf("group: 0x%p %8Tgroup_next: 0x%p\n", 632 krdc->group, krdc->group_next); 633 mdb_printf("group lock: 0x%p aux_state: %d\n", 634 &krdc->group->lock, krdc->aux_state); 635 636 mdb_inc_indent(4); 637 if (krdc->type_flag & RDC_ASYNCMODE) { 638 rdc_group((uintptr_t)krdc->group, DCMD_ADDRSPEC, 0, 0); 639 } 640 mdb_dec_indent(4); 641 642 mdb_printf("servinfo: 0x%p %8Tintf: 0x%p\nbitmap: 0x%p %8T" 643 "bitmap_ref: 0x%p\n", 644 krdc->lsrv, krdc->intf, krdc->dcio_bitmap, krdc->bitmap_ref); 645 646 mdb_printf("bmap_size: %d %8Tbmaprsrv: %d%8T bmap_write: %d\n", 647 krdc->bitmap_size, krdc->bmaprsrv, krdc->bitmap_write); 648 649 mdb_printf("bitmapfd: 0x%p %8Tremote_fd: 0x%p %8T\n", krdc->bitmapfd, 650 krdc->remote_fd); 651 652 mdb_printf("net_dataset: 0x%p %8Tdisk_status: %d %8T\n", 653 krdc->net_dataset, krdc->disk_status); 654 655 mdb_printf("many: 0x%p %8Tmulti: 0x%p %8T\n", krdc->many_next, 656 krdc->multi_next); 657 658 mdb_printf("rdc_uinfo: 0x%p\n\n", urdc); 659 mdb_dec_indent(4); 660 return (DCMD_OK); 661 } 662 663 664 static int 665 rdc_uinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 666 { 667 rdc_u_info_t *urdc; 668 rdc_k_info_t *rdc_k_info, *krdc, krdc1; 669 rdc_group_t grp; 670 disk_queue *dqp = NULL; 671 int a_opt, v_opt; 672 int dev_t_chars; 673 int rdcflags; 674 675 a_opt = v_opt = FALSE; 676 dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ 677 678 if (mdb_getopts(argc, argv, 679 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 680 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 681 return (DCMD_USAGE); 682 683 urdc = mdb_zalloc(sizeof (*urdc), UM_GC); 684 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 685 686 if (!(flags & DCMD_ADDRSPEC)) { 687 /* 688 * paranoid mode on: qualify walker name with module name 689 * using '`' syntax. 690 */ 691 if (mdb_walk_dcmd("rdc`rdc_uinfo", 692 "rdc`rdc_uinfo", argc, argv) == -1) { 693 mdb_warn("failed to walk 'rdc_uinfo'"); 694 return (DCMD_ERR); 695 } 696 return (DCMD_OK); 697 } 698 if (DCMD_HDRSPEC(flags)) { 699 mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", 700 dev_t_chars, "FLAG", "STATE"); 701 } 702 703 if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) { 704 mdb_warn("failed to read rdc_u_info at %p", addr); 705 return (DCMD_ERR); 706 } 707 708 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 709 mdb_warn("failed to read 'rdc_k_info'"); 710 return (DCMD_ERR); 711 } 712 713 krdc = &rdc_k_info[urdc->index]; 714 715 if (!a_opt && ((urdc->flags & RDC_ENABLED) == 0)) 716 return (DCMD_OK); 717 718 719 if (mdb_vread(&krdc1, sizeof (krdc1), 720 (uintptr_t)krdc) != sizeof (krdc1)) { 721 mdb_warn("failed to read 'rdc_k_info1'"); 722 return (DCMD_ERR); 723 } 724 725 if (krdc1.group) { 726 if (mdb_vread(&grp, sizeof (grp), 727 (uintptr_t)krdc1.group) != sizeof (grp)) { 728 mdb_warn("failed to read group info "); 729 return (DCMD_ERR); 730 } 731 dqp = &grp.diskq; 732 } 733 734 rdcflags = (urdc->flags | urdc->sync_flags | urdc->bmap_flags); 735 mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, rdcflags); 736 737 738 if (rdcflags & RDC_PRIMARY) 739 mdb_printf(" primary"); 740 if (rdcflags & RDC_SLAVE) 741 mdb_printf(" slave"); 742 if (rdcflags & RDC_SYNCING) 743 mdb_printf(" syncing"); 744 if (rdcflags & RDC_SYNC_NEEDED) 745 mdb_printf(" sync_need"); 746 if (rdcflags & RDC_RSYNC_NEEDED) 747 mdb_printf(" rsync_need"); 748 if (rdcflags & RDC_LOGGING) 749 mdb_printf(" logging"); 750 if (rdcflags & RDC_QUEUING) 751 mdb_printf(" queuing"); 752 if (rdcflags & RDC_DISKQ_FAILED) 753 mdb_printf(" diskq failed"); 754 if (rdcflags & RDC_VOL_FAILED) 755 mdb_printf(" vol failed"); 756 if (rdcflags & RDC_BMP_FAILED) 757 mdb_printf(" bmp failed"); 758 if (rdcflags & RDC_ASYNC) 759 mdb_printf(" async"); 760 if (rdcflags & RDC_CLR_AFTERSYNC) 761 mdb_printf(" clr_bitmap_aftersync"); 762 if (dqp) { 763 if (IS_QSTATE(dqp, RDC_QNOBLOCK)) 764 mdb_printf(" noblock"); 765 } 766 #ifdef RDC_SMALLIO 767 if (rdcflags & RDC_SMALLIO) 768 mdb_printf(" smallio"); 769 #endif 770 771 mdb_printf("\n"); 772 773 if (!v_opt) 774 return (DCMD_OK); 775 776 /* 777 * verbose - print the rest of the structure as well. 778 */ 779 780 mdb_inc_indent(4); 781 mdb_printf("\n"); 782 783 mdb_printf("primary: %s %8Tfile: %s \nbitmap: %s ", 784 urdc->primary.intf, urdc->primary.file, urdc->primary.bitmap); 785 mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, primary)); 786 mdb_printf("secondary: %s %8Tfile: %s \nbitmap: %s ", 787 urdc->secondary.intf, urdc->secondary.file, urdc->secondary.bitmap); 788 mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, secondary)); 789 790 mdb_printf("sflags: %d %8Tbflags: %d%8T mflags: %d\n", 791 urdc->sync_flags, urdc->bmap_flags, urdc->mflags); 792 mdb_printf("index: %d %8Tsync_pos: %d%8T vsize: %d\n", 793 urdc->index, urdc->sync_pos, urdc->volume_size); 794 mdb_printf("setid: %d %8Tbits set: %d %8Tautosync: %d\n", 795 urdc->setid, urdc->bits_set, urdc->autosync); 796 mdb_printf("maxqfbas: %d %8Tmaxqitems: %d\n", 797 urdc->maxqfbas, urdc->maxqitems); 798 mdb_printf("netconfig: %p\n", urdc->netconfig); 799 mdb_printf("group: %s %8TdirectIO: %s\n", 800 urdc->group_name, urdc->direct_file); 801 mdb_printf("diskqueue: %s ", urdc->disk_queue); 802 if (dqp) { 803 mdb_printf("diskqsize: %d\n", QSIZE(dqp)); 804 } else { 805 mdb_printf("\n"); 806 } 807 mdb_printf("rdc_k_info: 0x%p\n", krdc); 808 mdb_printf("\n"); 809 mdb_dec_indent(4); 810 811 mdb_printf("\n"); 812 return (DCMD_OK); 813 } 814 815 /*ARGSUSED*/ 816 static int 817 rdc_infodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 818 { 819 rdc_info_dev_t *infodev; 820 _rdc_info_dev_t *infp; 821 822 if (!(flags & DCMD_ADDRSPEC)) 823 return (DCMD_USAGE); 824 825 infodev = mdb_zalloc(sizeof (*infodev), UM_GC); 826 infp = mdb_zalloc(sizeof (*infp), UM_GC); 827 828 if (mdb_vread(infodev, sizeof (*infodev), addr) != sizeof (*infodev)) { 829 mdb_warn("failed to read rdc_infodev at 0x%p\n", addr); 830 return (DCMD_ERR); 831 } 832 833 infp = &infodev->id_cache_dev; 834 mdb_inc_indent(4); 835 836 mdb_printf("id_next: 0x%p\n", infodev->id_next); 837 mdb_printf("id_cache_dev:\n"); 838 839 mdb_inc_indent(4); 840 mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n", 841 infp->bi_fd, infp->bi_iodev, infp->bi_krdc); 842 mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n" 843 "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv, 844 infp->bi_failed, infp->bi_ofailed, infp->bi_flag); 845 846 infp = &infodev->id_raw_dev; 847 848 mdb_dec_indent(4); 849 mdb_printf("id_cache_dev:\n"); 850 mdb_inc_indent(4); 851 852 mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n", 853 infp->bi_fd, infp->bi_iodev, infp->bi_krdc); 854 mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n" 855 "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv, 856 infp->bi_failed, infp->bi_ofailed, infp->bi_flag); 857 858 mdb_dec_indent(4); 859 860 mdb_printf("id_sets: %d %8Tid_release: %d %8Tid_flag %d", 861 infodev->id_sets, infodev->id_release, infodev->id_flag); 862 863 if (infodev->id_flag & RDC_ID_CLOSING) { 864 mdb_printf("closing"); 865 } 866 mdb_printf("\n"); 867 868 mdb_dec_indent(4); 869 return (DCMD_OK); 870 } 871 872 /* 873 * Display general sv module information. 874 */ 875 876 #define rdc_get_print(kvar, str, fmt, val) \ 877 if (mdb_readvar(&(val), #kvar) == -1) { \ 878 mdb_dec_indent(4); \ 879 mdb_warn("unable to read '" #kvar "'"); \ 880 return (DCMD_ERR); \ 881 } \ 882 mdb_printf("%-20s" fmt "\n", str ":", val) 883 884 /*ARGSUSED*/ 885 static int 886 rdc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 887 { 888 int maj, min, mic, baseline, i; 889 890 if (argc != 0) 891 return (DCMD_USAGE); 892 893 if (mdb_readvar(&maj, "sndr_major_rev") == -1) { 894 mdb_warn("unable to read 'sndr_major_rev'"); 895 return (DCMD_ERR); 896 } 897 898 if (mdb_readvar(&min, "sndr_minor_rev") == -1) { 899 mdb_warn("unable to read 'sndr_minor_rev'"); 900 return (DCMD_ERR); 901 } 902 903 if (mdb_readvar(&mic, "sndr_micro_rev") == -1) { 904 mdb_warn("unable to read 'sndr_micro_rev'"); 905 return (DCMD_ERR); 906 } 907 908 if (mdb_readvar(&baseline, "sndr_baseline_rev") == -1) { 909 mdb_warn("unable to read 'sndr_baseline_rev'"); 910 return (DCMD_ERR); 911 } 912 913 mdb_printf("Remote Mirror module version: kernel %d.%d.%d.%d; " 914 "mdb %d.%d.%d.%d\n", maj, min, mic, baseline, 915 ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); 916 mdb_inc_indent(4); 917 918 rdc_get_print(rdc_debug, "debug", "%d", i); 919 rdc_get_print(rdc_bitmap_mode, "bitmap mode", "%d", i); 920 rdc_get_print(rdc_max_sets, "max sndr devices", "%d", i); 921 rdc_get_print(rdc_rpc_tmout, "client RPC timeout", "%d", i); 922 rdc_get_print(rdc_health_thres, "health threshold", "%d", i); 923 rdc_get_print(MAX_RDC_FBAS, "max trans fba", "%d", i); 924 925 mdb_dec_indent(4); 926 return (DCMD_OK); 927 } 928 929 static int 930 rdc_k2u(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 931 { 932 rdc_k_info_t *krdc; 933 rdc_u_info_t *rdc_u_info, *urdc; 934 int rc; 935 936 if (!(flags & DCMD_ADDRSPEC)) 937 return (DCMD_USAGE); 938 939 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 940 urdc = mdb_zalloc(sizeof (*urdc), UM_GC); 941 942 if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { 943 mdb_warn("failed to read krdc at %p", addr); 944 return (DCMD_ERR); 945 } 946 947 if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { 948 mdb_warn("failed to read 'rdc_u_info'"); 949 return (DCMD_ERR); 950 } 951 952 urdc = &rdc_u_info[krdc->index]; 953 954 rc = rdc_uinfo((uintptr_t)urdc, DCMD_ADDRSPEC, argc, argv); 955 return (rc); 956 } 957 958 static int 959 rdc_u2k(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 960 { 961 rdc_u_info_t *urdc; 962 rdc_k_info_t *rdc_k_info, *krdc; 963 int rc; 964 965 if (!(flags & DCMD_ADDRSPEC)) 966 return (DCMD_USAGE); 967 968 urdc = mdb_zalloc(sizeof (*urdc), UM_GC); 969 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 970 971 if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) { 972 mdb_warn("failed to read urdc at %p\n", addr); 973 return (DCMD_ERR); 974 } 975 976 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 977 mdb_warn("failed to read 'rdc_k_info'"); 978 return (DCMD_ERR); 979 } 980 981 krdc = &rdc_k_info[urdc->index]; 982 983 rc = rdc_kinfo((uintptr_t)krdc, DCMD_ADDRSPEC, argc, argv); 984 return (rc); 985 } 986 987 #ifdef DEBUG 988 /* 989 * This routine is used to set the seq field in the rdc_kinfo->group 990 * structure. Used to test that the queue code handles the integer 991 * overflow correctly. 992 * Takes two arguments index and value. 993 * The index is the index into the kinfo structure array and 994 * the value is the new value to set into the seq field. 995 */ 996 /*ARGSUSED*/ 997 static int 998 rdc_setseq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 999 { 1000 rdc_k_info_t *rdc_k_info; 1001 rdc_group_t *group; 1002 int index; 1003 uint_t val; 1004 uintptr_t pokeaddr; 1005 1006 if (argc != 2) { 1007 mdb_warn("must have two arguments, index and value\n"); 1008 return (DCMD_ERR); 1009 } 1010 1011 index = (int)mdb_strtoull(argv[0].a_un.a_str); 1012 val = (uint_t)mdb_strtoull(argv[1].a_un.a_str); 1013 1014 /* 1015 * Find out where in memory the seq field. 1016 * The structure offset first. 1017 */ 1018 1019 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 1020 mdb_warn("failed to read 'rdc_k_info'"); 1021 return (DCMD_ERR); 1022 } 1023 pokeaddr = (uintptr_t)&rdc_k_info[index].group; 1024 if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) != 1025 sizeof (rdc_group_t *)) { 1026 mdb_warn("failed to fetch the group structure for set %d\n", 1027 index); 1028 return (DCMD_ERR); 1029 } 1030 pokeaddr = (uintptr_t)(&group->seq); 1031 if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) { 1032 mdb_warn("failed to write seq at %p\n", pokeaddr); 1033 return (DCMD_ERR); 1034 } 1035 1036 return (DCMD_OK); 1037 } 1038 1039 1040 /* 1041 * This routine is used to set the seqack field in the rdc_kinfo->group 1042 * structure. Used to test that the queue code handles the integer 1043 * overflow correctly. 1044 * Takes two arguments index and value. 1045 * The index is the index into the kinfo structure array and 1046 * the value is the new value to set into the seqack field. 1047 */ 1048 /*ARGSUSED*/ 1049 static int 1050 rdc_setseqack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1051 { 1052 rdc_k_info_t *rdc_k_info; 1053 rdc_group_t *group; 1054 int index; 1055 uint_t val; 1056 uintptr_t pokeaddr; 1057 1058 if (argc != 2) { 1059 mdb_warn("must have two arguments, index and value\n"); 1060 return (DCMD_ERR); 1061 } 1062 1063 index = (int)mdb_strtoull(argv[0].a_un.a_str); 1064 val = (uint_t)mdb_strtoull(argv[1].a_un.a_str); 1065 1066 /* 1067 * Find out where in memory the seqack field. 1068 * The structure offset first. 1069 */ 1070 1071 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 1072 mdb_warn("failed to read 'rdc_k_info'"); 1073 return (DCMD_ERR); 1074 } 1075 pokeaddr = (uintptr_t)&rdc_k_info[index].group; 1076 if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) != 1077 sizeof (rdc_group_t *)) { 1078 mdb_warn("failed to fetch the group structure for set %d\n", 1079 index); 1080 return (DCMD_ERR); 1081 } 1082 pokeaddr = (uintptr_t)(&group->seqack); 1083 if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) { 1084 mdb_warn("failed to write seqack at %p\n", pokeaddr); 1085 return (DCMD_ERR); 1086 } 1087 1088 return (DCMD_OK); 1089 } 1090 1091 /* 1092 * random define printing stuff, just does the define, and print the result 1093 */ 1094 /*ARGSUSED*/ 1095 static int 1096 fba_to_log_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1097 { 1098 int num; 1099 if (argc < 1) { 1100 mdb_warn("must have an argument\n"); 1101 return (DCMD_ERR); 1102 } 1103 num = (int)mdb_strtoull(argv[0].a_un.a_str); 1104 num = FBA_TO_LOG_NUM(num); 1105 mdb_printf("LOG NUM: %d (0x%x)", num, num); 1106 1107 return (DCMD_OK); 1108 } 1109 1110 /*ARGSUSED*/ 1111 static int 1112 log_to_fba_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1113 { 1114 int num; 1115 if (argc < 1) { 1116 mdb_warn("must have an argument\n"); 1117 return (DCMD_ERR); 1118 } 1119 num = (int)mdb_strtoull(argv[0].a_un.a_str); 1120 num = LOG_TO_FBA_NUM(num); 1121 mdb_printf("LOG NUM: %d (0x%x)", num, num); 1122 1123 return (DCMD_OK); 1124 } 1125 1126 static int 1127 bmap_bit_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1128 { 1129 int st; 1130 int i, num; 1131 rdc_k_info_t *krdc; 1132 unsigned char *bmap; 1133 unsigned char *bmaddr; 1134 int bmsize; 1135 1136 if (!(flags & DCMD_ADDRSPEC)) 1137 return (DCMD_USAGE); 1138 1139 if (argc < 1) { 1140 mdb_warn("must have an argument\n"); 1141 return (DCMD_ERR); 1142 } 1143 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 1144 1145 if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { 1146 mdb_warn("failed to read rdc_k_info at %p", addr); 1147 return (DCMD_ERR); 1148 } 1149 1150 bmaddr = krdc->dcio_bitmap; 1151 bmsize = krdc->bitmap_size; 1152 bmap = mdb_zalloc(bmsize, UM_GC); 1153 if (mdb_vread(bmap, bmsize, (uintptr_t)bmaddr) != bmsize) { 1154 mdb_warn("failed to read bitmap"); 1155 return (DCMD_ERR); 1156 } 1157 1158 num = (int)mdb_strtoull(argv[0].a_un.a_str); 1159 st = FBA_TO_LOG_NUM(num); 1160 i = BMAP_BIT_ISSET(bmap, st); 1161 mdb_printf(" BIT (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT", 1162 bmap[IND_BYTE(st)] & 0xff); 1163 1164 return (DCMD_OK); 1165 } 1166 1167 static int 1168 bmap_bitref_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1169 { 1170 int num, st, i; 1171 rdc_k_info_t *krdc; 1172 unsigned char *brefbyte; 1173 unsigned int *brefint; 1174 void *bradder; 1175 int brsize; 1176 size_t refcntsize = sizeof (unsigned char); 1177 struct bm_ref_ops *refops; 1178 1179 if (!(flags & DCMD_ADDRSPEC)) 1180 return (DCMD_USAGE); 1181 1182 if (argc < 1) { 1183 mdb_warn("must have an argument\n"); 1184 return (DCMD_ERR); 1185 } 1186 1187 krdc = mdb_zalloc(sizeof (*krdc), UM_GC); 1188 1189 if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { 1190 mdb_warn("failed to read rdc_k_info at %p", addr); 1191 return (DCMD_ERR); 1192 } 1193 1194 bradder = krdc->bitmap_ref; 1195 refops = mdb_zalloc(sizeof (*refops), UM_GC); 1196 if (mdb_vread(refops, sizeof (*refops), (uintptr_t)krdc->bm_refs) != 1197 sizeof (*refops)) { 1198 mdb_warn("failed to read bm_refops at %p", krdc->bm_refs); 1199 return (DCMD_ERR); 1200 } 1201 refcntsize = refops->bmap_ref_size; 1202 brsize = krdc->bitmap_size * BITS_IN_BYTE * refcntsize; 1203 if (refcntsize == sizeof (unsigned char)) { 1204 brefbyte = mdb_zalloc(brsize, UM_GC); 1205 if (mdb_vread(brefbyte, brsize, (uintptr_t)bradder) != brsize) { 1206 mdb_warn("failed to read bitmap"); 1207 return (DCMD_ERR); 1208 } 1209 } else { 1210 brefint = mdb_zalloc(brsize, UM_GC); 1211 if (mdb_vread(brefint, brsize, (uintptr_t)bradder) != brsize) { 1212 mdb_warn("failed to read bitmap"); 1213 return (DCMD_ERR); 1214 } 1215 } 1216 1217 num = (int)mdb_strtoull(argv[0].a_un.a_str); 1218 st = FBA_TO_LOG_NUM(num); 1219 if (refcntsize == sizeof (unsigned char)) 1220 i = brefbyte[st]; 1221 else 1222 i = brefint[st]; 1223 1224 mdb_printf("BITREF (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT", 1225 i); 1226 1227 return (DCMD_OK); 1228 } 1229 1230 /*ARGSUSED*/ 1231 static int 1232 ind_byte(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1233 { 1234 int num; 1235 1236 if (argc < 1) { 1237 mdb_warn("must have an argument\n"); 1238 return (DCMD_ERR); 1239 } 1240 num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str)); 1241 mdb_printf("IND_BYTE: %d", IND_BYTE(num)); 1242 1243 return (DCMD_OK); 1244 } 1245 1246 /*ARGSUSED*/ 1247 static int 1248 ind_bit(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1249 { 1250 int num; 1251 1252 if (argc < 1) { 1253 mdb_warn("must have an argument\n"); 1254 return (DCMD_ERR); 1255 } 1256 num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str)); 1257 mdb_printf("IND_BIT: %d 0x%x", IND_BIT(num), IND_BIT(num)); 1258 1259 return (DCMD_OK); 1260 } 1261 1262 static char * 1263 print_bit(uint_t bitmask) 1264 { 1265 int bitval = 1; 1266 int i; 1267 1268 bitstr[32] = '\0'; 1269 1270 for (i = 31; i >= 0; i--) { 1271 if (bitmask & bitval) { 1272 bitstr[i] = '1'; 1273 } else { 1274 bitstr[i] = '0'; 1275 } 1276 bitval *= 2; 1277 } 1278 return (bitstr); 1279 } 1280 1281 /*ARGSUSED*/ 1282 static int 1283 rdc_bitmask(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1284 { 1285 uint_t bitmask = 0; 1286 int first, st, en, pos, len; 1287 1288 if (argc < 2) { 1289 mdb_warn("must have 2 args (pos, len)\n"); 1290 return (DCMD_ERR); 1291 } 1292 pos = (int)mdb_strtoull(argv[0].a_un.a_str); 1293 len = (int)mdb_strtoull(argv[1].a_un.a_str); 1294 1295 if (len <= 0) { 1296 mdb_printf("non positive len specified"); 1297 return (DCMD_ERR); 1298 } 1299 1300 if ((len - pos) > 2048) { 1301 mdb_printf("len out of range, 32 bit bitmask"); 1302 return (DCMD_ERR); 1303 } 1304 1305 first = st = FBA_TO_LOG_NUM(pos); 1306 en = FBA_TO_LOG_NUM(pos + len - 1); 1307 while (st <= en) { 1308 BMAP_BIT_SET((uchar_t *)&bitmask, st - first); 1309 st++; 1310 } 1311 1312 mdb_printf("bitmask for POS: %d LEN: %d : 0x%08x (%s)", pos, len, 1313 bitmask & 0xffffffff, print_bit(bitmask)); 1314 return (DCMD_OK); 1315 1316 } 1317 1318 /* 1319 * Dump the bitmap of the krdc structure indicated by the index 1320 * argument. Used by the ZatoIchi tests. 1321 */ 1322 /*ARGSUSED*/ 1323 static int 1324 rdc_bmapdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1325 { 1326 rdc_k_info_t *rdc_k_info; 1327 int index; 1328 uintptr_t bmapaddr; 1329 uintptr_t bmapdata; 1330 unsigned char *data; 1331 int bmapsize; 1332 int i; 1333 int st = 0; 1334 int en = 0; 1335 1336 if (argc < 1) { 1337 mdb_warn("must have index argument\n"); 1338 return (DCMD_ERR); 1339 } 1340 1341 i = argc; 1342 if (i == 3) { 1343 en = (int)mdb_strtoull(argv[2].a_un.a_str); 1344 en = FBA_TO_LOG_NUM(en); 1345 i--; 1346 } 1347 if (i == 2) { 1348 st = (int)mdb_strtoull(argv[1].a_un.a_str); 1349 st = FBA_TO_LOG_NUM(st); 1350 } 1351 1352 index = (int)mdb_strtoull(argv[0].a_un.a_str); 1353 /* 1354 * Find out where in memory the rdc_k_kinfo array starts 1355 */ 1356 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 1357 mdb_warn("failed to read 'rdc_k_info'"); 1358 return (DCMD_ERR); 1359 } 1360 bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size); 1361 if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr) 1362 != sizeof (bmapsize)) { 1363 mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); 1364 return (DCMD_ERR); 1365 } 1366 1367 bmapaddr = (uintptr_t)(&rdc_k_info[index].dcio_bitmap); 1368 if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr) 1369 != sizeof (bmapdata)) { 1370 mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); 1371 return (DCMD_ERR); 1372 } 1373 data = mdb_zalloc(bmapsize, UM_SLEEP); 1374 1375 if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) { 1376 mdb_warn("failed to read the bitmap data\n"); 1377 mdb_free(data, bmapsize); 1378 return (DCMD_ERR); 1379 } 1380 mdb_printf("bitmap data address 0x%p bitmap size %d\n" 1381 "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]); 1382 1383 if ((st < 0) || ((st/8) > bmapsize) || (en < 0)) { 1384 mdb_warn("offset is out of range st %d bms %d en %d", 1385 st, bmapsize, en); 1386 return (DCMD_ERR); 1387 } 1388 if (((en/8) > bmapsize) || (en == 0)) 1389 en = bmapsize * 8; 1390 1391 mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en); 1392 st /= 8; 1393 en /= 8; 1394 for (i = st; i < en; i++) { 1395 mdb_printf("%02x ", data[i] & 0xff); 1396 if ((i % 16) == 15) { 1397 int s = LOG_TO_FBA_NUM((i-15)*8); 1398 int e = LOG_TO_FBA_NUM(((i+1)*8)) - 1; 1399 mdb_printf(" fbas: %x - %x\n", s, e); 1400 } 1401 } 1402 mdb_printf("\n"); 1403 mdb_free(data, bmapsize); 1404 return (DCMD_OK); 1405 } 1406 1407 /* 1408 * dump the bitmap reference count 1409 */ 1410 /*ARGSUSED*/ 1411 static int 1412 rdc_brefdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1413 { 1414 rdc_k_info_t *rdc_k_info; 1415 int index; 1416 uintptr_t bmapaddr; 1417 uintptr_t bmapdata; 1418 unsigned char *data; 1419 int bmapsize; 1420 int i; 1421 int st = 0; 1422 int en = 0; 1423 1424 if (argc < 1) { 1425 mdb_warn("must have index argument\n"); 1426 return (DCMD_ERR); 1427 } 1428 index = (int)mdb_strtoull(argv[0].a_un.a_str); 1429 1430 i = argc; 1431 if (i == 3) { 1432 en = (int)mdb_strtoull(argv[2].a_un.a_str); 1433 en = FBA_TO_LOG_NUM(en); 1434 i--; 1435 1436 } 1437 if (i == 2) { 1438 st = (int)mdb_strtoull(argv[1].a_un.a_str); 1439 st = FBA_TO_LOG_NUM(st); 1440 } 1441 1442 /* 1443 * Find out where in memory the rdc_k_kinfo array starts 1444 */ 1445 if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { 1446 mdb_warn("failed to read 'rdc_k_info'"); 1447 return (DCMD_ERR); 1448 } 1449 bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size); 1450 1451 if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr) 1452 != sizeof (bmapsize)) { 1453 mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); 1454 return (DCMD_ERR); 1455 } 1456 1457 bmapsize *= 8; 1458 bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_ref); 1459 1460 if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr) 1461 != sizeof (bmapdata)) { 1462 mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); 1463 return (DCMD_ERR); 1464 } 1465 data = mdb_zalloc(bmapsize, UM_SLEEP); 1466 1467 if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) { 1468 mdb_warn("failed to read the bitmap data\n"); 1469 mdb_free(data, bmapsize); 1470 return (DCMD_ERR); 1471 } 1472 mdb_printf("bitmap data address 0x%p bitmap size %d\n" 1473 "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]); 1474 1475 if ((st < 0) || (st > bmapsize) || (en < 0)) { 1476 mdb_warn("offset is out of range"); 1477 } 1478 if ((en > bmapsize) || (en == 0)) 1479 en = bmapsize; 1480 1481 mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en); 1482 1483 for (i = st; i < en; i++) { 1484 mdb_printf("%02x ", data[i] & 0xff); 1485 if ((i % 16) == 15) { 1486 int s = LOG_TO_FBA_NUM(i-15); 1487 int e = LOG_TO_FBA_NUM(i+1) - 1; 1488 mdb_printf(" fbas: 0x%x - 0x%x \n", s, e); 1489 } 1490 } 1491 mdb_printf("\n"); 1492 mdb_free(data, bmapsize); 1493 return (DCMD_OK); 1494 } 1495 1496 static int 1497 rdc_bmapnref(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1498 { 1499 mdb_printf("\nRDC bitmap info\n"); 1500 rdc_bmapdump(addr, flags, argc, argv); 1501 mdb_printf("RDC bitmap reference count info\n"); 1502 rdc_brefdump(addr, flags, argc, argv); 1503 return (DCMD_OK); 1504 } 1505 1506 #endif 1507 /* 1508 * MDB module linkage information: 1509 */ 1510 1511 static const mdb_dcmd_t dcmds[] = { 1512 { "rdc", NULL, "display sndr module info", rdc }, 1513 { "rdc_buf", "?[-v]", "rdc_buf structure", rdc_buf }, 1514 { "rdc_kinfo", "?[-av]", "rdc_k_info structure", rdc_kinfo }, 1515 { "rdc_uinfo", "?[-av]", "rdc_u_info structure", rdc_uinfo }, 1516 { "rdc_group", "?", "rdc group structure", rdc_group }, 1517 { "rdc_srv", "?", "rdc_srv structure", rdc_srv }, 1518 { "rdc_if", "?", "rdc_if structure", rdc_if }, 1519 { "rdc_infodev", "?", "rdc_info_dev structure", rdc_infodev }, 1520 { "rdc_k2u", "?", "rdc_kinfo to rdc_uinfo", rdc_k2u }, 1521 { "rdc_u2k", "?", "rdc_uinfo to rdc_kinfo", rdc_u2k }, 1522 { "rdc_aio", "?", "rdc_aio structure", rdc_aio}, 1523 { "rdc_iohdr", "?", "rdc_iohdr structure", rdc_iohdr}, 1524 #ifdef DEBUG 1525 { "rdc_setseq", "?", "Write seq field in group", rdc_setseq }, 1526 { "rdc_setseqack", "?", "Write seqack field in group", rdc_setseqack }, 1527 { "rdc_dset", "?", "Dump dset info", rdc_dset }, 1528 { "rdc_bmapdump", "?", "Dump bitmap", rdc_bmapdump }, 1529 { "rdc_brefdump", "?", "Dump bitmap reference count", rdc_brefdump }, 1530 { "rdc_bmapnref", "?", "Dump bitmap and ref count", rdc_bmapnref }, 1531 { "rdc_fba2log", "?", "fba to log num", fba_to_log_num }, 1532 { "rdc_log2fba", "?", "log to fba num", log_to_fba_num }, 1533 { "rdc_bitisset", "?", "check bit set", bmap_bit_isset }, 1534 { "rdc_brefisset", "?", "check bit ref set", bmap_bitref_isset }, 1535 { "rdc_indbyte", "?", "print indbyte", ind_byte }, 1536 { "rdc_indbit", "?", "print indbit", ind_bit }, 1537 { "rdc_bitmask", "?", "print bitmask for pos->len", rdc_bitmask }, 1538 #endif 1539 { NULL } 1540 }; 1541 1542 1543 static const mdb_walker_t walkers[] = { 1544 { "rdc_kinfo", "walk the rdc_k_info array", 1545 rdc_k_info_winit, rdc_k_info_wstep, rdc_k_info_wfini }, 1546 { "rdc_uinfo", "walk the rdc_u_info array", 1547 rdc_u_info_winit, rdc_u_info_wstep, rdc_u_info_wfini }, 1548 { "rdc_if", "walk rdc_if chain", 1549 rdc_if_winit, rdc_if_wstep, rdc_if_wfini }, 1550 { NULL } 1551 }; 1552 1553 1554 static const mdb_modinfo_t modinfo = { 1555 MDB_API_VERSION, dcmds, walkers 1556 }; 1557 1558 1559 const mdb_modinfo_t * 1560 _mdb_init(void) 1561 { 1562 return (&modinfo); 1563 } 1564