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 (c) 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <sys/dditypes.h> 26 #include <sys/mdb_modapi.h> 27 #include <sys/modctl.h> 28 #include <sys/sunddi.h> 29 30 #include <lpif.h> 31 #include <stmf.h> 32 #include <stmf_ioctl.h> 33 #include <portif.h> 34 #include <stmf_sbd.h> 35 #include <sbd_impl.h> 36 #include <scsi/generic/persist.h> 37 38 #define STMF_SBD_STR_MAX 2048 39 #define STMF_SBD_VERBOSE 0x00000001 40 41 #define ARRAY_SIZE(a) (sizeof (a) / sizeof (*a)) 42 43 /* structure to pass arguments to mdb_walker callback function */ 44 typedef struct stmf_sbd_cb_s { 45 uint32_t flag; 46 } stmf_sbd_cb_t; 47 48 49 static const char *stmf_protocol_str[] = { 50 "FIBRE_CHANNEL", /* PROTOCOL_FIBRE_CHANNEL 0 */ 51 "PARALLEL_SCSI", /* PROTOCOL_PARALLEL_SCSI 1 */ 52 "SSA", /* PROTOCOL_SSA 2 */ 53 "IEEE_1394", /* PROTOCOL_IEEE_1394 3 */ 54 "SRP", /* PROTOCOL_SRP 4 */ 55 "iSCSI", /* PROTOCOL_iSCSI 5 */ 56 "SAS", /* PROTOCOL_SAS 6 */ 57 "ADT", /* PROTOCOL_ADT 7 */ 58 "ATAPI" /* PROTOCOL_ATAPI 8 */ 59 }; 60 61 62 /* 63 * Support functions. 64 */ 65 66 static uint64_t 67 nhconvert_8bytes(const void *src) { 68 uint64_t dest; 69 mdb_nhconvert(&dest, src, 8); 70 return (dest); 71 } 72 73 /* 74 * Variable 'bits' is a collection of flags for which a corresponding 75 * description string is available at flag_ary. 76 * So flag_ary should be an ary of strings with total_bits strings. 77 */ 78 static void 79 stmf_sbd_print_bit_flags(const char *flag_ary[], 80 int total_bits, uint32_t bits) { 81 uint32_t curbit = 0x01; 82 int i, delim = 0; 83 84 for (i = 0; i < total_bits; i++) { 85 if (bits & curbit) { 86 mdb_printf("%s%s", (delim) ? " | " : "", flag_ary[i]); 87 delim = 1; 88 } 89 curbit <<= 1; 90 } 91 mdb_printf("\n"); 92 } 93 94 95 static void 96 stmf_sbd_print_pgr_info(sbd_pgr_t *pgr) 97 { 98 static const char *pgr_flag_str[] = { 99 "SBD_PGR_APTPL", /* 0x01 */ 100 "SBD_PGR_RSVD_ONE", /* 0x02 */ 101 "SBD_PGR_RSVD_ALL_REGISTRANTS", /* 0x04 */ 102 "SBD_PGR_ALL_KEYS_HAS_IT" /* 0x08 */ 103 }; 104 105 static const char *pgr_type_desc[] = { 106 "ILLEGAL", /* 0x0 */ 107 "Write Exclusive", /* 0x1 */ 108 "ILLEGAL", /* 0x2 */ 109 "Exclusive Access", /* 0x3 */ 110 "ILLEGAL", /* 0x4 */ 111 "Write Exclusive, Registrants Only", /* 0x5 */ 112 "Exclusive Access, Registrants Only", /* 0x6 */ 113 "Write Exclusive, All Registrants", /* 0x7 */ 114 "Exclusive Access, All Registrants" /* 0x8 */ 115 }; 116 117 mdb_printf("PGR flags: "); 118 stmf_sbd_print_bit_flags(pgr_flag_str, ARRAY_SIZE(pgr_flag_str), 119 pgr->pgr_flags); 120 if (pgr->pgr_rsvholder || pgr->pgr_flags & 121 SBD_PGR_RSVD_ALL_REGISTRANTS) { 122 mdb_printf("Reservation Details \n"); 123 mdb_printf("\tReservation holder: "); 124 if (pgr->pgr_rsvholder) 125 mdb_printf("%p\n", pgr->pgr_rsvholder); 126 else 127 mdb_printf("All Registrants\n"); 128 129 mdb_printf("\t type : %d => %s\n", 130 pgr->pgr_rsv_type, 131 (pgr->pgr_rsv_type < ARRAY_SIZE(pgr_type_desc)) ? 132 pgr_type_desc[pgr->pgr_rsv_type] : "ILLEGAL"); 133 mdb_printf("\t scope : %d\n", pgr->pgr_rsv_scope); 134 } else { 135 mdb_printf("No reservations.\n"); 136 } 137 } 138 139 void 140 print_scsi_devid_desc(uintptr_t addr, uint16_t len, char *spacer) 141 { 142 scsi_devid_desc_t *id; 143 144 if (len < sizeof (*id)) { 145 mdb_warn("%sError: Devid Size = %d < sizeof(scsi_devid_desc_t)" 146 "\n", spacer, len); 147 return; 148 } 149 150 id = mdb_zalloc(len, UM_SLEEP); 151 if (mdb_vread(id, len, addr) == -1) { 152 mdb_warn("failed to read scsi_devid_desc at %p\n", addr); 153 mdb_free(id, len); 154 return; 155 } 156 157 mdb_printf("%sTotal length:\t%d\n", spacer, len); 158 mdb_printf("%sProtocol:\t%d => %-16s\n", spacer, id->protocol_id, 159 (id->protocol_id < ARRAY_SIZE(stmf_protocol_str)) ? 160 stmf_protocol_str[id->protocol_id] : ""); 161 mdb_printf("%sCode Set:\t%d\n", spacer, id->code_set); 162 mdb_printf("%sIdent Length:\t%d\n", spacer, id->ident_length); 163 164 if (len < sizeof (*id) + id->ident_length - 1) { 165 mdb_printf("%s(Can not recognize ident data)\n", spacer); 166 } else { 167 id->ident[id->ident_length] = '\0'; 168 mdb_printf("%sIdent:\t\t%s\n", spacer, id->ident); 169 } 170 mdb_free(id, len); 171 mdb_printf("\n"); 172 } 173 174 /* 175 * Decipher and print transport id which is pointed by addr variable. 176 */ 177 static int 178 print_transport_id(uintptr_t addr, uint16_t tpd_len, char *spacer) 179 { 180 scsi_transport_id_t *tpd; 181 182 if (tpd_len < sizeof (*tpd)) { 183 mdb_warn("%sError: Transport ID Size = %d < " 184 "sizeof (scsi_transport_id_t)\n", spacer, tpd_len); 185 return (DCMD_ERR); 186 } 187 188 tpd = mdb_zalloc(tpd_len, UM_SLEEP); 189 if (mdb_vread(tpd, tpd_len, addr) == -1) { 190 mdb_warn("failed to read scsi_transport_id at %p\n", addr); 191 mdb_free(tpd, tpd_len); 192 return (DCMD_ERR); 193 } 194 195 mdb_printf("%sTotal length:\t%d\n", spacer, tpd_len); 196 mdb_printf("%sProtocol:\t%d => %16s\n", spacer, tpd->protocol_id, 197 (tpd->protocol_id < ARRAY_SIZE(stmf_protocol_str)) ? 198 stmf_protocol_str[tpd->protocol_id] : ""); 199 mdb_printf("%sFormat Code:\t0x%x\n", spacer, tpd->format_code); 200 201 switch (tpd->protocol_id) { 202 case PROTOCOL_FIBRE_CHANNEL: 203 { 204 uint8_t *p = ((scsi_fc_transport_id_t *)tpd)->port_name; 205 mdb_printf("%sFC Port Name:\t%016llX\n", spacer, 206 nhconvert_8bytes(p)); 207 } 208 break; 209 case PROTOCOL_PARALLEL_SCSI: 210 case PROTOCOL_SSA: 211 case PROTOCOL_IEEE_1394: 212 break; 213 case PROTOCOL_SRP: 214 { 215 uint8_t *p = ((scsi_srp_transport_id_t *)tpd)->srp_name; 216 /* Print 8 byte initiator extention and guid in order */ 217 mdb_printf("%sSRP Name:\t%016llX:%016llX\n", spacer, 218 nhconvert_8bytes(&p[8]), nhconvert_8bytes(&p[0])); 219 } 220 break; 221 case PROTOCOL_iSCSI: 222 mdb_printf("%sISCSI Name:\t%s\n", spacer, 223 ((iscsi_transport_id_t *)tpd)->iscsi_name); 224 break; 225 case PROTOCOL_SAS: 226 case PROTOCOL_ADT: 227 case PROTOCOL_ATAPI: 228 default: 229 break; 230 } 231 232 mdb_free(tpd, tpd_len); 233 return (DCMD_OK); 234 } 235 236 void 237 stmf_sbd_pgr_key_dcmd_help(void) 238 { 239 mdb_printf( 240 "Prints info about pgr keys and reservations on the given lun.\n\n" 241 "Usage: <addr>::stmf_sbd_pgr_key [-akv]\n" 242 " where <addr> represent the address of\n" 243 " sbd_lu_t by default\n" 244 " or\n" 245 " sbd_pgr_key_t if '-a' option is specified.\n" 246 "Options:\n" 247 " -a if specified, <addr> represents address of sbd_pgr_key_t\n" 248 " -k if specified, only prints key information\n" 249 " -v verbose output\n"); 250 } 251 252 253 /* 254 * MDB WALKERS implementations 255 */ 256 257 static int 258 stmf_sbd_lu_walk_init(mdb_walk_state_t *wsp) 259 { 260 if (wsp->walk_addr == NULL) { 261 if (mdb_readvar(&wsp->walk_addr, "sbd_lu_list") == -1) { 262 mdb_warn("failed to read sbd_lu_list\n"); 263 return (WALK_ERR); 264 } 265 } 266 return (WALK_NEXT); 267 } 268 269 static int 270 stmf_sbd_lu_walk_step(mdb_walk_state_t *wsp) 271 { 272 uintptr_t addr = wsp->walk_addr; 273 sbd_lu_t slu; 274 275 if (wsp->walk_addr == NULL) 276 return (WALK_DONE); 277 278 if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { 279 mdb_warn("failed to read sbd_lu_t at %p\n", addr); 280 return (WALK_ERR); 281 } 282 wsp->walk_addr = (uintptr_t)slu.sl_next; 283 return (wsp->walk_callback(addr, &slu, wsp->walk_cbdata)); 284 } 285 286 char * 287 stmf_sbd_getstr(uintptr_t addr, char *str) { 288 if ((addr == 0) || (mdb_readstr(str, STMF_SBD_STR_MAX, addr) == -1)) 289 str = NULL; 290 return (str); 291 } 292 293 static int 294 stmf_sbd_lu_cb(uintptr_t addr, const sbd_lu_t *slu, stmf_sbd_cb_t *cb_st) 295 { 296 if (cb_st->flag & STMF_SBD_VERBOSE) { 297 char str[STMF_SBD_STR_MAX]; 298 299 mdb_printf("\nsbd_lu - %p\n", addr); 300 301 /* sl_device_id contains 4 bytes hdr + 16 bytes(GUID) */ 302 mdb_printf("\tsl_deviceid: %-?p GUID => %016llX%016llX\n", 303 slu->sl_device_id, nhconvert_8bytes(&slu->sl_device_id[4]), 304 nhconvert_8bytes(&slu->sl_device_id[12])); 305 mdb_printf("\tsl_name: %-?p %s\n", slu->sl_name, 306 stmf_sbd_getstr((uintptr_t)slu->sl_name, str)); 307 mdb_printf("\tsl_alias: %-?p %s\n", slu->sl_alias, 308 stmf_sbd_getstr((uintptr_t)slu->sl_alias, str)); 309 mdb_printf("\tsl_meta_filename: %-?p %s\n", 310 slu->sl_meta_filename, 311 stmf_sbd_getstr((uintptr_t)slu->sl_meta_filename, str)); 312 mdb_printf("\tsl_data_filename: %-?p %s\n", 313 slu->sl_data_filename, 314 stmf_sbd_getstr((uintptr_t)slu->sl_data_filename, str)); 315 mdb_printf("\tsl_mgmt_url: %-?p %s\n", slu->sl_mgmt_url, 316 stmf_sbd_getstr((uintptr_t)slu->sl_mgmt_url, str)); 317 mdb_printf("\tsl_zfs_meta: %-?p\n", slu->sl_zfs_meta); 318 mdb_printf("\tsl_it_list: %-?p\n", slu->sl_it_list); 319 mdb_printf("\tsl_pgr: %-?p\n", slu->sl_pgr); 320 } else { 321 mdb_printf("%p\n", addr); 322 } 323 return (WALK_NEXT); 324 } 325 326 static int 327 stmf_sbd_pgr_key_walk_init(mdb_walk_state_t *wsp) 328 { 329 if (wsp->walk_addr == NULL) { 330 mdb_warn("<pgr_key_list addr>::walk stmf_sbd_pgr_key\n"); 331 return (WALK_ERR); 332 } 333 return (WALK_NEXT); 334 } 335 336 static int 337 stmf_sbd_pgr_key_walk_step(mdb_walk_state_t *wsp) 338 { 339 uintptr_t addr = wsp->walk_addr; 340 sbd_pgr_key_t key; 341 342 if (wsp->walk_addr == NULL) 343 return (WALK_DONE); 344 345 if (mdb_vread(&key, sizeof (sbd_pgr_key_t), addr) == -1) { 346 mdb_warn("failed to read sbd_pgr_key_t at %p\n", addr); 347 return (WALK_ERR); 348 } 349 wsp->walk_addr = (uintptr_t)key.pgr_key_next; 350 return (wsp->walk_callback(addr, &key, wsp->walk_cbdata)); 351 } 352 353 static int 354 stmf_sbd_pgr_key_cb(uintptr_t addr, const sbd_pgr_key_t *key, 355 stmf_sbd_cb_t *cb_st) 356 { 357 static const char *key_flag_str [] = { 358 "SBD_PGR_KEY_ALL_TG_PT", /* 0x01 */ 359 "SBD_PGR_KEY_TPT_ID_FLAG" /* 0x02 */ 360 }; 361 362 if (cb_st->flag & STMF_SBD_VERBOSE) { 363 mdb_printf("sbd_pgr_key - %p\n", addr); 364 mdb_printf("\tRegistered key: 0x%016llx\n", key->pgr_key); 365 mdb_printf("\tKey Flags: "); 366 stmf_sbd_print_bit_flags(key_flag_str, ARRAY_SIZE(key_flag_str), 367 key->pgr_key_flags); 368 mdb_printf("\tpgr_key_it: %?-p\n", key->pgr_key_it); 369 mdb_printf("\tLocal Device ID: %?-p\n", 370 key->pgr_key_lpt_id); 371 print_scsi_devid_desc((uintptr_t)key->pgr_key_lpt_id, 372 key->pgr_key_lpt_len, " "); 373 mdb_printf("\tRemote Transport ID: %?-p\n", 374 key->pgr_key_rpt_id); 375 print_transport_id((uintptr_t)key->pgr_key_rpt_id, 376 key->pgr_key_rpt_len, " "); 377 } else { 378 mdb_printf("%p\n", addr); 379 } 380 return (WALK_NEXT); 381 } 382 383 static int 384 stmf_sbd_it_walk_init(mdb_walk_state_t *wsp) 385 { 386 if (wsp->walk_addr == NULL) { 387 mdb_warn("<sbd_it_list addr>::walk stmf_sbd_pgr_key\n"); 388 return (WALK_ERR); 389 } 390 return (WALK_NEXT); 391 } 392 393 static int 394 stmf_sbd_it_walk_step(mdb_walk_state_t *wsp) 395 { 396 uintptr_t addr = wsp->walk_addr; 397 sbd_it_data_t it; 398 399 if (wsp->walk_addr == NULL) 400 return (WALK_DONE); 401 402 if (mdb_vread(&it, sizeof (sbd_it_data_t), addr) == -1) { 403 mdb_warn("failed to read sbd_it_data_t at %p\n", addr); 404 return (WALK_ERR); 405 } 406 wsp->walk_addr = (uintptr_t)it.sbd_it_next; 407 return (wsp->walk_callback(addr, &it, wsp->walk_cbdata)); 408 } 409 410 static int 411 stmf_sbd_it_cb(uintptr_t addr, const sbd_it_data_t *it, stmf_sbd_cb_t *cb_st) 412 { 413 static const char *it_flag_str [] = { 414 "SBD_IT_HAS_SCSI2_RESERVATION", /* 0x0001 */ 415 "SBD_IT_PGR_REGISTERED", /* 0x0002 */ 416 "SBD_IT_PGR_EXCLUSIVE_RSV_HOLDER", /* 0x0004 */ 417 "SBD_IT_PGR_CHECK_FLAG" /* 0x0008 */ 418 }; 419 420 if (cb_st->flag & STMF_SBD_VERBOSE) { 421 mdb_printf("SBD IT DATA - %p\n", addr); 422 mdb_printf("\tSession ID: 0x%0-lx\n", it->sbd_it_session_id); 423 mdb_printf("\tIT Flags: "); 424 stmf_sbd_print_bit_flags(it_flag_str, ARRAY_SIZE(it_flag_str), 425 it->sbd_it_flags); 426 mdb_printf("\tPGR Key: %-p\n", it->pgr_key_ptr); 427 } else { 428 mdb_printf("%p\n", addr); 429 } 430 return (WALK_NEXT); 431 } 432 433 /* 434 * MDB DCMDS implementations. 435 */ 436 437 int 438 stmf_sbd_lu(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 439 { 440 uint_t verbose = FALSE; 441 sbd_lu_t slu; 442 stmf_sbd_cb_t cb_st = {0}; 443 444 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) 445 != argc) 446 return (DCMD_USAGE); 447 if (verbose) 448 cb_st.flag |= STMF_SBD_VERBOSE; 449 450 if (flags & DCMD_ADDRSPEC) { 451 cb_st.flag |= STMF_SBD_VERBOSE; 452 if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { 453 mdb_warn("failed to read sbd_lu_t at %p\n", addr); 454 return (DCMD_ERR); 455 } 456 if (stmf_sbd_lu_cb(addr, &slu, &cb_st) == WALK_ERR) 457 return (DCMD_ERR); 458 } else { 459 if (mdb_walk("stmf_sbd_lu", (mdb_walk_cb_t)stmf_sbd_lu_cb, 460 &cb_st) == -1) { 461 mdb_warn("failed to walk sbd_lu_list\n"); 462 return (DCMD_ERR); 463 } 464 } 465 return (DCMD_OK); 466 } 467 468 static int 469 stmf_sbd_pgr_key(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 470 { 471 uint_t verbose = FALSE, keyonly = FALSE, pgrkeyaddr = FALSE; 472 sbd_lu_t slu; 473 sbd_pgr_t pgr; 474 sbd_pgr_key_t key; 475 stmf_sbd_cb_t cb_st = {0}; 476 477 if (!(flags & DCMD_ADDRSPEC)) 478 return (DCMD_USAGE); 479 480 if (mdb_getopts(argc, argv, 481 'a', MDB_OPT_SETBITS, TRUE, &pgrkeyaddr, 482 'k', MDB_OPT_SETBITS, TRUE, &keyonly, 483 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) 484 return (DCMD_USAGE); 485 486 if (pgrkeyaddr || verbose) 487 cb_st.flag |= STMF_SBD_VERBOSE; 488 489 /* If address of pgr_key is given, just print that key and return */ 490 if (pgrkeyaddr) { 491 if (mdb_vread(&key, sizeof (sbd_pgr_key_t), addr) == -1) { 492 mdb_warn("failed to read sbd_pgr_key at %p\n", addr); 493 return (DCMD_ERR); 494 } 495 if (stmf_sbd_pgr_key_cb(addr, &key, &cb_st) == WALK_ERR) { 496 return (DCMD_ERR); 497 } 498 return (DCMD_OK); 499 } else { 500 if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { 501 mdb_warn("failed to read sbd_lu at %p\n", addr); 502 return (DCMD_ERR); 503 } 504 } 505 506 if (verbose) { 507 mdb_printf("\nLU:- %p\n", addr); 508 } 509 /* Just a sanity check, not necessarily needed */ 510 if (slu.sl_pgr == NULL) { 511 if (verbose) 512 mdb_warn("pgr structure not found for lun %p\n", addr); 513 return (DCMD_OK); 514 } 515 516 if (mdb_vread(&pgr, sizeof (sbd_pgr_t), (uintptr_t)slu.sl_pgr) == -1) { 517 mdb_warn("failed to read sbd_lu at %p\n", slu.sl_pgr); 518 return (DCMD_ERR); 519 } 520 521 if (!keyonly) 522 stmf_sbd_print_pgr_info(&pgr); 523 524 if (pgr.pgr_keylist == NULL) { 525 if (verbose) 526 mdb_printf("No registered pgr keys found\n"); 527 return (DCMD_OK); 528 } else { 529 if (!keyonly) 530 mdb_printf("\nKeys\n"); 531 } 532 533 if (mdb_pwalk("stmf_sbd_pgr_key", (mdb_walk_cb_t)stmf_sbd_pgr_key_cb, 534 &cb_st, (uintptr_t)pgr.pgr_keylist) == -1) { 535 mdb_warn("failed to walk pgr_keylist\n"); 536 return (DCMD_ERR); 537 } 538 return (DCMD_OK); 539 } 540 541 /*ARGSUSED*/ 542 static int 543 stmf_remote_port(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 544 { 545 stmf_remote_port_t rpt; 546 int ret = DCMD_OK; 547 548 if (!(flags & DCMD_ADDRSPEC)) 549 return (DCMD_USAGE); 550 551 if (mdb_vread(&rpt, sizeof (stmf_remote_port_t), addr) == -1) { 552 mdb_warn("failed to read stmf_remote_port_t at %p\n", addr); 553 return (DCMD_ERR); 554 } 555 556 ret = print_transport_id((uintptr_t)rpt.rport_tptid, 557 rpt.rport_tptid_sz, " "); 558 return (ret); 559 } 560 561 static int 562 stmf_sbd_it(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 563 { 564 uint_t verbose = FALSE; 565 sbd_lu_t slu; 566 stmf_sbd_cb_t cb_st = {0}; 567 568 if (!(flags & DCMD_ADDRSPEC)) 569 return (DCMD_USAGE); 570 571 if (mdb_getopts(argc, argv, 572 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) 573 return (DCMD_USAGE); 574 575 if (verbose) { 576 cb_st.flag |= STMF_SBD_VERBOSE; 577 mdb_printf("\nLU:- %p\n", addr); 578 } 579 580 /* If address of pgr_key is given, just print that key and return */ 581 if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { 582 mdb_warn("failed to read sbd_lu at %p\n", addr); 583 return (DCMD_ERR); 584 } 585 586 /* Just a sanity check, not necessarily needed */ 587 if (slu.sl_it_list == NULL) { 588 if (verbose) 589 mdb_printf("sbd_it_list is empty\n", addr); 590 return (DCMD_OK); 591 } 592 593 if (mdb_pwalk("stmf_sbd_it", (mdb_walk_cb_t)stmf_sbd_it_cb, &cb_st, 594 (uintptr_t)slu.sl_it_list) == -1) { 595 mdb_warn("failed to walk sbd_lu_it_list\n"); 596 return (DCMD_ERR); 597 } 598 return (DCMD_OK); 599 } 600 601 /* 602 * MDB dmcds and walkers definitions 603 */ 604 605 static const mdb_dcmd_t dcmds[] = { 606 { "stmf_sbd_lu", "?[-v]", "Print the list of sbd_lu_t", 607 stmf_sbd_lu, NULL }, 608 { "stmf_sbd_it", ":[-v]", "Print the list of sbd_it_data for given lu", 609 stmf_sbd_it, NULL }, 610 { "stmf_sbd_pgr_key", ":[-kov]", "Print the list of pgr keys", 611 stmf_sbd_pgr_key, stmf_sbd_pgr_key_dcmd_help }, 612 { "stmf_remote_port", ":", "decipher info in a stmf_remote_port", 613 stmf_remote_port, NULL }, 614 { NULL } 615 }; 616 617 static const mdb_walker_t walkers[] = { 618 { "stmf_sbd_lu", "walk list of stmf_sbd_lu structures", 619 stmf_sbd_lu_walk_init, stmf_sbd_lu_walk_step, NULL }, 620 { "stmf_sbd_pgr_key", "walk the pgr keys of the given pgr key list", 621 stmf_sbd_pgr_key_walk_init, stmf_sbd_pgr_key_walk_step, NULL }, 622 { "stmf_sbd_it", "walk the sbd_it_data for the given it list", 623 stmf_sbd_it_walk_init, stmf_sbd_it_walk_step, NULL }, 624 { NULL } 625 }; 626 627 static const mdb_modinfo_t modinfo = { 628 MDB_API_VERSION, dcmds, walkers 629 }; 630 631 const mdb_modinfo_t * 632 _mdb_init(void) 633 { 634 return (&modinfo); 635 } 636