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 /* 27 * mpathadm.c : MP API CLI program 28 * 29 */ 30 31 #include <libintl.h> 32 33 #include <mpapi.h> 34 #include "cmdparse.h" 35 #include "mpathadm_text.h" 36 #include "mpathadm.h" 37 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 #include <unistd.h> 41 #include <stdlib.h> 42 #include <devid.h> 43 #include <fcntl.h> 44 45 /* helper functions */ 46 static char *getExecBasename(char *); 47 48 /* object functions per subcommand */ 49 static int listFunc(int, char **, int, cmdOptions_t *, void *); 50 static int showFunc(int, char **, int, cmdOptions_t *, void *); 51 static int modifyFunc(int, char **, int, cmdOptions_t *, void *); 52 static int enableFunc(int, char **, int, cmdOptions_t *, void *); 53 static int disableFunc(int, char **, int, cmdOptions_t *, void *); 54 static int failoverFunc(int, char **, int, cmdOptions_t *, void *); 55 static int overrideFunc(int, char **, int, cmdOptions_t *, void *); 56 57 #define VERSION_STRING_MAX_LEN 10 58 59 #define OPTIONSTRING_NAME "name" 60 #define OPTIONSTRING_TPNAME "target-port name" 61 #define OPTIONSTRING_ONOFF "on/off" 62 #define OPTIONSTRING_LBTYPE "loadbalance type" 63 #define OPTIONSTRING_IPORT "initiator-port name" 64 #define OPTIONSTRING_LUNIT "logical-unit name" 65 #define OPTIONSTRING_CANCEL "cancel" 66 #define OPTIONSTRING_VALUE "value" 67 68 /* 69 * Version number: (copied from iscsiadm) 70 * MAJOR - This should only change when there is an incompatible change made 71 * to the interfaces or the output. 72 * 73 * MINOR - This should change whenever there is a new command or new feature 74 * with no incompatible change. 75 */ 76 #define VERSION_STRING_MAJOR "1" 77 #define VERSION_STRING_MINOR "0" 78 79 80 /* globals */ 81 static char *cmdName; 82 83 84 /* 85 * **************************************************************************** 86 * 87 * getExecBasename - copied from iscsiadm code 88 * 89 * input: 90 * execFullName - exec name of program (argv[0]) 91 * 92 * Returns: 93 * command name portion of execFullName 94 * 95 * **************************************************************************** 96 */ 97 static char * 98 getExecBasename(char *execFullname) 99 { 100 char *lastSlash, *execBasename; 101 102 /* guard against '/' at end of command invocation */ 103 for (;;) { 104 lastSlash = strrchr(execFullname, '/'); 105 if (lastSlash == NULL) { 106 execBasename = execFullname; 107 break; 108 } else { 109 execBasename = lastSlash + 1; 110 if (*execBasename == '\0') { 111 *lastSlash = '\0'; 112 continue; 113 } 114 break; 115 } 116 } 117 return (execBasename); 118 } 119 120 121 /* 122 * Add new options here 123 */ 124 125 /* tables set up based on cmdparse instructions */ 126 optionTbl_t longOptions[] = { 127 {"inqname", required_arg, 'n', OPTIONSTRING_NAME}, 128 {"target-port", required_arg, 't', OPTIONSTRING_TPNAME}, 129 {"autofailback", required_arg, 'a', OPTIONSTRING_ONOFF}, 130 {"autoprobe", required_arg, 'p', OPTIONSTRING_ONOFF}, 131 {"loadbalance", required_arg, 'b', OPTIONSTRING_LBTYPE}, 132 {"initiator-port", required_arg, 'i', OPTIONSTRING_IPORT}, 133 {"logical-unit", required_arg, 'l', OPTIONSTRING_LUNIT}, 134 {"cancel", no_arg, 'c', OPTIONSTRING_CANCEL}, 135 {"vendor-id", required_arg, 'd', OPTIONSTRING_VALUE}, 136 {NULL, 0, 0, 0} 137 }; 138 139 140 /* 141 * Add new subcommands here 142 */ 143 subcommand_t subcommands[] = { 144 {"list", LIST, listFunc}, 145 {"show", SHOW, showFunc}, 146 {"modify", MODIFY, modifyFunc}, 147 {"enable", ENABLE, enableFunc}, 148 {"disable", DISABLE, disableFunc}, 149 {"failover", FAILOVER, failoverFunc}, 150 {"override", OVERRIDE, overrideFunc}, 151 {NULL, 0, NULL} 152 }; 153 154 /* 155 * Add objects here 156 */ 157 object_t objects[] = { 158 {"mpath-support", MPATH_SUPPORT}, 159 {"logical-unit", LOGICAL_UNIT}, 160 {"LU", LOGICAL_UNIT}, 161 {"initiator-port", INITIATOR_PORT}, 162 {"path", PATH}, 163 {NULL, 0} 164 }; 165 166 /* 167 * Rules for subcommands and objects 168 * 169 * command 170 * 171 * reqOpCmd -> subcommands that must have an operand 172 * optOpCmd -> subcommands that may have an operand 173 * noOpCmd -> subcommands that will have no operand 174 * invCmd -> subcommands that are invalid 175 * multOpCmd -> subcommands that can accept multiple operands 176 * operandDefinition -> Usage definition for the operand of this object 177 */ 178 objectRules_t objectRules[] = { 179 {MPATH_SUPPORT, SHOW|MODIFY|ADD, LIST|REMOVE, 0, 180 ENABLE|DISABLE|FAILOVER|OVERRIDE, LIST|SHOW|MODIFY, 181 "mpath-support name"}, 182 {INITIATOR_PORT, SHOW, LIST, 0, 183 MODIFY|ENABLE|DISABLE|FAILOVER|OVERRIDE|ADD|REMOVE, LIST|SHOW, 184 "initiator-port name"}, 185 {LOGICAL_UNIT, SHOW|MODIFY|FAILOVER, LIST, 0, 186 ENABLE|DISABLE|OVERRIDE|ADD|REMOVE, LIST|SHOW|MODIFY, 187 "logical-unit name"}, 188 {PATH, 0, 0, ENABLE|DISABLE|OVERRIDE, 189 SHOW|LIST|MODIFY|FAILOVER|ADD|REMOVE, 0, 190 "initiator-port name"}, 191 {0, 0, 0, 0, 0, NULL} 192 }; 193 194 /* 195 * list of objects, subcommands, valid short options, required flag and 196 * exclusive option string 197 * 198 * If it's not here, there are no options for that object. 199 */ 200 optionRules_t optionRules[] = { 201 {LOGICAL_UNIT, LIST, "nt", B_FALSE, NULL}, 202 {LOGICAL_UNIT, MODIFY, "apb", B_TRUE, NULL}, 203 {MPATH_SUPPORT, MODIFY, "apb", B_TRUE, NULL}, 204 {MPATH_SUPPORT, ADD, "d", B_TRUE, NULL}, 205 {MPATH_SUPPORT, REMOVE, "d", B_TRUE, NULL}, 206 {PATH, ENABLE, "itl", B_TRUE, NULL}, 207 {PATH, DISABLE, "itl", B_TRUE, NULL}, 208 {PATH, OVERRIDE, "itlc", B_TRUE, NULL}, 209 {0, 0, 0, 0, 0} 210 }; 211 212 213 /* 214 * **************************************************************************** 215 * 216 * listMpathSupport - mpathadm list mpath-support 217 * 218 * operandLen - number of operands user passed into the cli 219 * operand - pointer to operand list from user 220 * 221 * **************************************************************************** 222 */ 223 int 224 listMpathSupport(int operandLen, char *operand[]) 225 { 226 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 227 MP_PLUGIN_PROPERTIES pluginProps; 228 MP_OID_LIST *pPluginOidList; 229 boolean_t shown = B_FALSE; 230 /* number of plugins listed */ 231 int i, 232 op; 233 234 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 235 != MP_STATUS_SUCCESS) { 236 (void) fprintf(stderr, "%s: %s\n", cmdName, 237 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 238 return (mpstatus); 239 } 240 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 241 (void) fprintf(stderr, "%s: %s\n", cmdName, 242 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 243 return (ERROR_CLI_FAILED); 244 } 245 246 247 /* loop through operands first */ 248 for (op = 0; (op < operandLen) | 249 ((0 == operandLen) && (B_FALSE == shown)); op++) { 250 shown = B_TRUE; 251 for (i = 0; i < pPluginOidList->oidCount; i++) { 252 253 (void) memset(&pluginProps, 0, 254 sizeof (MP_PLUGIN_PROPERTIES)); 255 mpstatus = 256 MP_GetPluginProperties(pPluginOidList->oids[i], 257 &pluginProps); 258 if (mpstatus != MP_STATUS_SUCCESS) { 259 (void) fprintf(stderr, "%s: %s\n", 260 cmdName, getTextString(ERR_NO_PROPERTIES)); 261 } else { 262 if (0 == operandLen) { 263 /* if no operands, list them all */ 264 (void) printf("%s %s\n", 265 getTextString( 266 TEXT_LB_MPATH_SUPPORT), 267 pluginProps.fileName); 268 } else { 269 /* if there is an operand... */ 270 /* ... compare and display if match */ 271 if (0 == 272 strcmp(operand[op], 273 pluginProps.fileName)) { 274 (void) printf("%s %s\n", 275 getTextString( 276 TEXT_LB_MPATH_SUPPORT), 277 pluginProps.fileName); 278 } else { 279 /* LINTED E_SEC_PRINTF_VAR_FMT */ 280 (void) fprintf(stderr, 281 getTextString( 282 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME), 283 operand[op]); 284 (void) printf("\n"); 285 } 286 } 287 } 288 } 289 } 290 291 return (mpstatus); 292 } 293 294 295 /* 296 * **************************************************************************** 297 * 298 * showMpathSupport - mpathadm show mpath-support <mpath-support name>, ... 299 * 300 * operandLen - number of operands user passed into the cli 301 * operand - pointer to operand list from user 302 * 303 * **************************************************************************** 304 */ 305 int 306 showMpathSupport(int operandLen, char *operand[]) 307 { 308 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 309 MP_PLUGIN_PROPERTIES pluginProps; 310 MP_OID_LIST *pPluginOidList; 311 MP_OID_LIST *deviceOidListArray; 312 MP_DEVICE_PRODUCT_PROPERTIES devProps; 313 boolean_t bListIt = B_FALSE; 314 int op, 315 i, 316 j; 317 MP_LOAD_BALANCE_TYPE lb; 318 319 320 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) != 321 MP_STATUS_SUCCESS) { 322 (void) fprintf(stderr, "%s: %s\n", 323 cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 324 return (mpstatus); 325 } 326 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 327 (void) fprintf(stderr, "%s: %s\n", 328 cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 329 return (ERROR_CLI_FAILED); 330 } 331 332 for (op = 0; op < operandLen; op++) { 333 bListIt = B_FALSE; 334 335 for (i = 0; i < pPluginOidList->oidCount; i++) { 336 337 (void) memset(&pluginProps, 0, 338 sizeof (MP_PLUGIN_PROPERTIES)); 339 mpstatus = 340 MP_GetPluginProperties(pPluginOidList->oids[i], 341 &pluginProps); 342 if (MP_STATUS_SUCCESS != mpstatus) { 343 (void) fprintf(stderr, "%s: %s\n", 344 cmdName, getTextString(ERR_NO_PROPERTIES)); 345 return (mpstatus); 346 } 347 348 if (0 == operandLen) { 349 /* if no operand, list it */ 350 bListIt = B_TRUE; 351 } else { 352 /* ... compare and display if match */ 353 if (0 == 354 strcmp(operand[op], 355 pluginProps.fileName)) { 356 bListIt = B_TRUE; 357 } 358 } 359 360 if (B_TRUE != bListIt) { 361 break; 362 } 363 364 (void) printf("%s %s\n", 365 getTextString(TEXT_LB_MPATH_SUPPORT), 366 pluginProps.fileName); 367 368 /* display the info for this plugin */ 369 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR)); 370 displayWideArray(pluginProps.vendor, 371 sizeof (pluginProps.vendor)); 372 (void) printf("\n\t%s ", 373 getTextString(TEXT_LB_DRIVER_NAME)); 374 displayArray(pluginProps.driverName, 375 sizeof (pluginProps.driverName)); 376 (void) printf("\n\t%s ", 377 getTextString(TEXT_LB_DEFAULT_LB)); 378 /* don't ignore load balance type none. */ 379 if (pluginProps.defaultloadBalanceType == 0) { 380 (void) printf("%s", 381 getTextString(TEXT_LBTYPE_NONE)); 382 } else { 383 displayLoadBalanceString( 384 pluginProps.defaultloadBalanceType); 385 } 386 (void) printf("\n"); 387 388 389 (void) printf("\t%s \n", 390 getTextString(TEXT_LB_SUPPORTED_LB)); 391 /* check each bit, display string if found set */ 392 if (pluginProps.supportedLoadBalanceTypes == 0) { 393 (void) printf("\t\t%s\n", 394 getTextString(TEXT_LBTYPE_NONE)); 395 } else { 396 lb = 1; 397 do { 398 if (0 != (lb & 399 pluginProps.supportedLoadBalanceTypes)) { 400 (void) printf("\t\t"); 401 displayLoadBalanceString(lb & 402 pluginProps.supportedLoadBalanceTypes); 403 (void) printf("\n"); 404 } 405 lb = lb<<1; 406 } while (lb < 0x80000000); 407 } 408 409 (void) printf("\t%s %s\n", 410 getTextString(TEXT_LB_ALLOWS_ACT_TPG), 411 (MP_TRUE == pluginProps.canSetTPGAccess)? 412 getTextString(TEXT_YES):getTextString(TEXT_NO)); 413 (void) printf("\t%s %s\n", 414 getTextString(TEXT_LB_ALLOWS_PATH_OV), 415 (MP_TRUE == pluginProps.canOverridePaths)? 416 getTextString(TEXT_YES):getTextString(TEXT_NO)); 417 (void) printf("\t%s %d\n", 418 getTextString(TEXT_LB_SUPP_AUTO_FB), 419 pluginProps.autoFailbackSupport); 420 if ((MP_AUTOFAILBACK_SUPPORT_PLUGIN == 421 pluginProps.autoFailbackSupport) | 422 (MP_AUTOFAILBACK_SUPPORT_PLUGINANDMPLU 423 == pluginProps.autoFailbackSupport)) { 424 (void) printf("\t%s %s\n", 425 getTextString(TEXT_LB_AUTO_FB), 426 pluginProps.pluginAutoFailbackEnabled?\ 427 getTextString(TEXT_ON): 428 getTextString(TEXT_OFF)); 429 (void) printf("\t%s %d/%d\n", 430 getTextString(TEXT_LB_FB_POLLING_RATE), 431 pluginProps.currentFailbackPollingRate, 432 pluginProps.failbackPollingRateMax); 433 } else { 434 (void) printf("\t%s %s\n", 435 getTextString(TEXT_LB_AUTO_FB), 436 getTextString(TEXT_NA)); 437 (void) printf("\t%s %s/%s\n", 438 getTextString(TEXT_LB_FB_POLLING_RATE), 439 getTextString(TEXT_NA), 440 getTextString(TEXT_NA)); 441 } 442 (void) printf("\t%s %d\n", 443 getTextString(TEXT_LB_SUPP_AUTO_P), 444 pluginProps.autoProbingSupport); 445 if ((MP_AUTOPROBING_SUPPORT_PLUGIN == 446 pluginProps.autoProbingSupport) | 447 (MP_AUTOPROBING_SUPPORT_PLUGIN == 448 pluginProps.autoProbingSupport)) { 449 (void) printf("\t%s %s\n", 450 getTextString(TEXT_LB_AUTO_PROB), 451 (MP_TRUE == 452 pluginProps.pluginAutoProbingEnabled)?\ 453 getTextString(TEXT_YES): 454 getTextString(TEXT_NO)); 455 (void) printf("\t%s %d/%d\n", 456 getTextString(TEXT_LB_PR_POLLING_RATE), 457 pluginProps.currentProbingPollingRate, 458 pluginProps.probingPollingRateMax); 459 } else { 460 (void) printf("\t%s %s\n", 461 getTextString(TEXT_LB_AUTO_PROB), 462 getTextString(TEXT_NA)); 463 (void) printf("\t%s %s/%s\n", 464 getTextString(TEXT_LB_PR_POLLING_RATE), 465 getTextString(TEXT_NA), 466 getTextString(TEXT_NA)); 467 } 468 469 470 (void) printf("\t%s\n", 471 getTextString(TEXT_LB_SUPP_DEVICES)); 472 473 474 if (MP_TRUE != 475 pluginProps.onlySupportsSpecifiedProducts) { 476 /* LINTED E_SEC_PRINTF_VAR_FMT */ 477 (void) printf(getTextString(TEXT_ANY_DEVICE)); 478 } else { 479 /* if only supports specific products, */ 480 /* get device product properties supported */ 481 482 mpstatus = MP_GetDeviceProductOidList(\ 483 pPluginOidList->oids[i], 484 &deviceOidListArray); 485 if (mpstatus != MP_STATUS_SUCCESS) { 486 (void) fprintf(stderr, "%s: %s\n", 487 cmdName, getTextString( 488 ERR_NO_SUPP_DEVICE_INFO)); 489 /* can't get any more info, */ 490 /* so we're done with this one */ 491 break; 492 } 493 494 for (j = 0; j < deviceOidListArray->oidCount; 495 j++) { 496 (void) memset(&devProps, 0, 497 sizeof (MP_DEVICE_PRODUCT_PROPERTIES)); 498 499 if ((mpstatus = 500 MP_GetDeviceProductProperties(\ 501 deviceOidListArray->oids[j], 502 &devProps)) == MP_STATUS_SUCCESS) { 503 504 (void) printf("\t\t%s ", 505 getTextString( 506 TEXT_LB_VENDOR)); 507 displayArray(devProps.vendor, 508 sizeof (devProps.vendor)); 509 (void) printf("\n\t\t%s ", 510 getTextString( 511 TEXT_LB_PRODUCT)); 512 displayArray(devProps.product, 513 sizeof (devProps.product)); 514 (void) printf("\n\t\t%s ", 515 getTextString( 516 TEXT_LB_REVISION)); 517 displayArray(devProps.revision, 518 sizeof (devProps.revision)); 519 520 (void) printf("\n\t\t%s\n", 521 getTextString( 522 TEXT_LB_SUPPORTED_LB)); 523 if (devProps.supportedLoadBalanceTypes == 0) { 524 (void) printf("\t\t\t%s\n", 525 getTextString(TEXT_LBTYPE_NONE)); 526 } else { 527 lb = 1; 528 do { 529 if (0 != (lb & 530 devProps.supportedLoadBalanceTypes)) { 531 (void) printf("\t\t\t"); 532 displayLoadBalanceString(lb & 533 devProps.supportedLoadBalanceTypes); 534 (void) printf("\n"); 535 } 536 lb = lb<<1; 537 } while (lb < 0x80000000); 538 } 539 540 541 (void) printf("\n"); 542 543 } else { 544 (void) fprintf(stderr, 545 "%s: %s\n", cmdName, 546 getTextString( 547 ERR_NO_SUPP_DEVICE_INFO)); 548 } 549 } /* for j */ 550 } /* if only supports specified devices */ 551 552 } /* for each plugin */ 553 554 if (B_FALSE == bListIt) { 555 /* LINTED E_SEC_PRINTF_VAR_FMT */ 556 (void) fprintf(stderr, getTextString( 557 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME), 558 operand[op]); 559 (void) printf("\n"); 560 561 } 562 563 } /* for each operand */ 564 565 566 return (mpstatus); 567 } 568 569 570 /* 571 * **************************************************************************** 572 * 573 * modifyMpathSupport - 574 * mpathadm modify mpath-support [options] <mpath-support name>, ... 575 * 576 * operandLen - number of operands user passed into the cli 577 * operand - pointer to operand list from user 578 * options - pointer to option list from user 579 * 580 * **************************************************************************** 581 */ 582 int 583 modifyMpathSupport(int operandLen, char *operand[], cmdOptions_t *options) 584 { 585 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 586 MP_PLUGIN_PROPERTIES pluginProps; 587 MP_OID_LIST *pPluginOidList; 588 boolean_t bFoundIt = B_FALSE; 589 MP_OID pluginOid; 590 cmdOptions_t *optionList = options; 591 char *cmdStr = 592 getTextString( 593 TEXT_UNKNOWN); 594 int op, 595 i, 596 lbValue; 597 598 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 599 != MP_STATUS_SUCCESS) { 600 (void) fprintf(stderr, "%s: %s\n", cmdName, 601 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 602 return (mpstatus); 603 } 604 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 605 (void) fprintf(stderr, "%s: %s\n", cmdName, 606 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 607 return (ERROR_CLI_FAILED); 608 } 609 610 for (op = 0; op < operandLen; op++) { 611 bFoundIt = B_FALSE; 612 for (i = 0; 613 (i < pPluginOidList->oidCount) && (B_TRUE != bFoundIt); 614 i++) { 615 616 (void) memset(&pluginProps, 0, 617 sizeof (MP_PLUGIN_PROPERTIES)); 618 if ((mpstatus = 619 MP_GetPluginProperties(pPluginOidList->oids[i], 620 &pluginProps)) == MP_STATUS_SUCCESS) { 621 622 if (0 == strcmp(operand[op], 623 pluginProps.fileName)) { 624 bFoundIt = B_TRUE; 625 pluginOid = pPluginOidList->oids[i]; 626 } 627 } else { 628 (void) fprintf(stderr, "%s: %s\n", 629 cmdName, getTextString(ERR_NO_PROPERTIES)); 630 } 631 632 if (B_FALSE == bFoundIt) { 633 break; 634 } 635 636 /* begin back-up indentation */ 637 /* we found the plugin oid */ 638 /* now change the options requested */ 639 switch (optionList->optval) { 640 case 'a': 641 /* modify autofailback */ 642 cmdStr = getTextString(TEXT_AUTO_FAILBACK); 643 if (0 == strcasecmp(optionList->optarg, 644 getTextString(TEXT_ON))) { 645 mpstatus = 646 MP_EnableAutoFailback(pluginOid); 647 } else if (0 == 648 strcasecmp(optionList->optarg, 649 getTextString(TEXT_OFF))) { 650 mpstatus = 651 MP_DisableAutoFailback(pluginOid); 652 } else { 653 /* LINTED E_SEC_PRINTF_VAR_FMT */ 654 (void) fprintf(stderr, getTextString( 655 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 656 cmdStr, 657 getTextString(TEXT_ILLEGAL_ARGUMENT)); 658 (void) printf("\n"); 659 return (ERROR_CLI_FAILED); 660 } 661 break; 662 case 'p': 663 /* modify autoprobing */ 664 cmdStr = getTextString(TEXT_AUTO_PROBING); 665 if (0 == strcasecmp(optionList->optarg, 666 getTextString(TEXT_ON))) { 667 mpstatus = 668 MP_EnableAutoProbing(pluginOid); 669 } else if (0 == 670 strcasecmp(optionList->optarg, 671 getTextString(TEXT_OFF))) { 672 mpstatus = 673 MP_DisableAutoProbing(pluginOid); 674 } else { 675 /* LINTED E_SEC_PRINTF_VAR_FMT */ 676 (void) fprintf(stderr, getTextString( 677 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 678 cmdStr, 679 getTextString(TEXT_ILLEGAL_ARGUMENT)); 680 (void) printf("\n"); 681 return (ERROR_CLI_FAILED); 682 } 683 break; 684 case 'b': 685 /* modify loadbalance type */ 686 cmdStr = getTextString(TEXT_LOAD_BALANCE); 687 /* user of the cli sends text string, we need the int */ 688 /* value to pass to the mpapi */ 689 lbValue = getLbValueFromString(optionList->optarg); 690 mpstatus = 691 MP_SetPluginLoadBalanceType(pluginOid, 692 lbValue); 693 break; 694 695 } /* switch */ 696 if (MP_STATUS_SUCCESS != mpstatus) { 697 /* LINTED E_SEC_PRINTF_VAR_FMT */ 698 (void) fprintf(stderr, 699 getTextString( 700 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 701 cmdStr, getMpStatusStr(mpstatus)); 702 (void) printf("\n"); 703 return (mpstatus); 704 } 705 /* end back-up indentation */ 706 707 } /* for each plugin */ 708 709 if (B_FALSE == bFoundIt) { 710 /* LINTED E_SEC_PRINTF_VAR_FMT */ 711 (void) fprintf(stderr, 712 getTextString( 713 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 714 cmdStr, 715 getTextString(TEXT_MPATH_SUPPORT_NOT_FOUND)); 716 (void) printf("\n"); 717 return (ERROR_CLI_FAILED); 718 } 719 720 } /* for each operand */ 721 722 return (mpstatus); 723 } 724 725 726 /* 727 * **************************************************************************** 728 * 729 * listLogicalUnit - 730 * mpathadm list {logical-unit | LU} [options] [<logical-unit name>, ...] 731 * 732 * operandLen - number of operands user passed into the cli 733 * operand - pointer to operand list from user 734 * options - pointer to option list from user 735 * 736 * **************************************************************************** 737 */ 738 int 739 listLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options) 740 { 741 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 742 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 743 MP_PLUGIN_PROPERTIES pluginProps; 744 MP_TARGET_PORT_PROPERTIES tportProps; 745 MP_OID_LIST *pPluginOidList, 746 *pLogicalUnitOidList, 747 *pTpgOidListArray, 748 *pTportOidListArray; 749 boolean_t bListIt = B_FALSE, 750 bFoundOperand = B_FALSE, 751 *bFoundOption, 752 bContinue = B_FALSE; 753 MP_OID luOid; 754 cmdOptions_t *optionList = options; 755 int opListCount = 0, 756 i = 0, 757 lu = 0, 758 tpg = 0, 759 opoffset = 0, 760 j = 0, 761 opStart = 0, 762 opEnd = 0, 763 opIndex; 764 765 /* count number of options */ 766 for (; optionList->optval; optionList++) { 767 opListCount++; 768 } 769 770 bFoundOption = malloc((sizeof (boolean_t)) * opListCount); 771 if (NULL == bFoundOption) { 772 (void) fprintf(stdout, "%s\n", 773 getTextString(ERR_MEMORY_ALLOCATION)); 774 return (ERROR_CLI_FAILED); 775 } 776 777 /* list to keep track of multiple options */ 778 optionList = options; 779 for (opIndex = 0; opIndex < opListCount; opIndex++) { 780 bFoundOption[opIndex] = B_FALSE; 781 } 782 783 optionList = options; 784 785 /* if no operands or options, list everything we find */ 786 if ((0 == operandLen) && (0 == opListCount)) { 787 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 788 != MP_STATUS_SUCCESS) { 789 (void) fprintf(stderr, "%s: %s\n", cmdName, 790 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 791 return (mpstatus); 792 } 793 if ((NULL == pPluginOidList) || 794 (pPluginOidList->oidCount < 1)) { 795 (void) fprintf(stderr, "%s: %s\n", cmdName, 796 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 797 return (ERROR_CLI_FAILED); 798 } 799 800 for (i = 0; i < pPluginOidList->oidCount; i++) { 801 /* get properties so we can list the name */ 802 (void) memset(&pluginProps, 0, 803 sizeof (MP_PLUGIN_PROPERTIES)); 804 if ((mpstatus = 805 MP_GetPluginProperties(pPluginOidList->oids[i], 806 &pluginProps)) != MP_STATUS_SUCCESS) { 807 (void) fprintf(stderr, "%s: %s\n", 808 cmdName, getTextString(ERR_NO_PROPERTIES)); 809 return (mpstatus); 810 } 811 812 /* attempt to find this logical unit */ 813 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i], 814 &pLogicalUnitOidList); 815 if (mpstatus != MP_STATUS_SUCCESS) { 816 (void) fprintf(stderr, "%s: %s\n", 817 cmdName, getTextString(ERR_NO_LU_LIST)); 818 return (mpstatus); 819 } 820 821 for (lu = 0; lu < pLogicalUnitOidList->oidCount; lu++) { 822 /* get lu properties so we can check the name */ 823 (void) memset(&luProps, 0, 824 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 825 mpstatus = 826 MP_GetMPLogicalUnitProperties( 827 pLogicalUnitOidList->oids[lu], 828 &luProps); 829 if (mpstatus != MP_STATUS_SUCCESS) { 830 (void) fprintf(stderr, "%s: %s\n", 831 cmdName, 832 getTextString(ERR_NO_PROPERTIES)); 833 return (mpstatus); 834 } 835 836 luOid = pLogicalUnitOidList->oids[lu]; 837 if (listIndividualLogicalUnit(luOid, luProps) 838 != 0) { 839 return (ERROR_CLI_FAILED); 840 } 841 } /* for each LU */ 842 } /* for each plugin */ 843 } else { /* we have operands and/or options */ 844 845 /* check if we have operands */ 846 if (0 == operandLen) { 847 /* no operands */ 848 opStart = -1; 849 opEnd = 0; 850 } else { 851 /* operands */ 852 opStart = 0; 853 opEnd = operandLen; 854 } 855 856 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 857 != MP_STATUS_SUCCESS) { 858 (void) fprintf(stderr, "%s: %s\n", cmdName, 859 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 860 return (mpstatus); 861 } 862 if ((NULL == pPluginOidList) || 863 (pPluginOidList->oidCount < 1)) { 864 (void) fprintf(stderr, "%s: %s\n", cmdName, 865 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 866 return (ERROR_CLI_FAILED); 867 } 868 869 for (opoffset = opStart; opoffset < opEnd; opoffset++) { 870 /* loop through operands */ 871 bFoundOperand = B_FALSE; 872 873 for (i = 0; i < pPluginOidList->oidCount; i++) { 874 875 /* 876 * loop through plugin, and get properties 877 * so we can list the name 878 */ 879 (void) memset(&pluginProps, 0, 880 sizeof (MP_PLUGIN_PROPERTIES)); 881 if ((mpstatus = 882 MP_GetPluginProperties( 883 pPluginOidList->oids[i], &pluginProps)) 884 != MP_STATUS_SUCCESS) { 885 (void) fprintf(stderr, "%s: %s\n", 886 cmdName, 887 getTextString(ERR_NO_PROPERTIES)); 888 return (mpstatus); 889 } 890 891 /* attempt to find this logical unit */ 892 mpstatus = 893 MP_GetMultipathLus(pPluginOidList->oids[i], 894 &pLogicalUnitOidList); 895 if (mpstatus != MP_STATUS_SUCCESS) { 896 (void) fprintf(stderr, "%s: %s\n", 897 cmdName, 898 getTextString(ERR_NO_LU_LIST)); 899 return (mpstatus); 900 } 901 902 for (lu = 0; 903 (lu < pLogicalUnitOidList->oidCount); 904 lu++) { 905 bListIt = B_FALSE; 906 /* get lu props & check the name */ 907 (void) memset(&luProps, 0, 908 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 909 mpstatus = 910 MP_GetMPLogicalUnitProperties( 911 pLogicalUnitOidList->oids[lu], 912 &luProps); 913 if (mpstatus != MP_STATUS_SUCCESS) { 914 (void) fprintf(stderr, 915 "%s: %s\n", cmdName, 916 getTextString( 917 ERR_NO_PROPERTIES)); 918 return (mpstatus); 919 } 920 921 /* 922 * compare operand - is it a match? 923 * If so, continue 924 */ 925 926 bContinue = B_TRUE; 927 if (operandLen > 0) { 928 bContinue = 929 compareLUName( 930 operand[opoffset], 931 luProps.deviceFileName); 932 } 933 934 if (B_TRUE == bContinue) { 935 936 if (0 != opListCount) { 937 /* check options */ 938 939 940 /* begin backup indentation */ 941 optionList = options; 942 943 for (opIndex = 0; optionList->optval; optionList++, opIndex++) { 944 switch (optionList->optval) { 945 case 'n': 946 if (B_TRUE == 947 compareLUName(optionList->optarg, luProps.name)) { 948 bListIt = B_TRUE; 949 bFoundOperand = B_TRUE; 950 bFoundOption[opIndex] = B_TRUE; 951 } 952 break; 953 case 't': 954 /* get TPG list */ 955 mpstatus = 956 MP_GetAssociatedTPGOidList(pLogicalUnitOidList->oids[lu], 957 &pTpgOidListArray); 958 if (mpstatus != MP_STATUS_SUCCESS) { 959 (void) fprintf(stderr, "%s: %s\n", cmdName, 960 getTextString(ERR_NO_ASSOC_TPGS)); 961 return (mpstatus); 962 } 963 964 /* get target ports */ 965 for (tpg = 0; 966 (NULL != pTpgOidListArray) && 967 (tpg < pTpgOidListArray->oidCount) && 968 (B_FALSE == bListIt); tpg++) { 969 mpstatus = 970 MP_GetTargetPortOidList(pTpgOidListArray->oids[tpg], 971 &pTportOidListArray); 972 if (mpstatus != MP_STATUS_SUCCESS) { 973 (void) fprintf(stderr, "%s: %s\n", 974 cmdName, 975 getTextString(ERR_NO_ASSOC_TPORTS)); 976 return (mpstatus); 977 } 978 979 /* get target port properties for the name */ 980 for (j = 0; (NULL != pTportOidListArray) && 981 (j < pTportOidListArray->oidCount) && 982 (B_FALSE == bListIt); j++) { 983 (void) memset(&tportProps, 0, 984 sizeof (MP_TARGET_PORT_PROPERTIES)); 985 mpstatus = 986 MP_GetTargetPortProperties( 987 pTportOidListArray->oids[j], &tportProps); 988 if (mpstatus != MP_STATUS_SUCCESS) { 989 (void) fprintf(stderr, "%s: %s\n", 990 cmdName, 991 getTextString(ERR_NO_PROPERTIES)); 992 return (mpstatus); 993 } 994 995 996 /* check the name */ 997 if (0 == strcmp(optionList->optarg, 998 tportProps.portID)) { 999 bListIt = B_TRUE; 1000 bFoundOperand = B_TRUE; 1001 bFoundOption[opIndex] = B_TRUE; 1002 } 1003 } /* for each target port */ 1004 } /* for each tpg */ 1005 } /* end switch */ 1006 } /* loop through options */ 1007 /* end back-up indentation */ 1008 1009 } else { 1010 /* 1011 * if no options, 1012 * listit 1013 */ 1014 bListIt = B_TRUE; 1015 bFoundOperand = B_TRUE; 1016 } 1017 } /* end bContinue check */ 1018 1019 if (bListIt) { 1020 (void) printf("%s %s\n", 1021 getTextString(TEXT_LB_MPATH_SUPPORT), 1022 pluginProps.fileName); 1023 luOid = pLogicalUnitOidList->oids[lu]; 1024 if (listIndividualLogicalUnit(luOid, luProps) 1025 != 0) { 1026 return (ERROR_CLI_FAILED); 1027 } 1028 1029 } 1030 1031 } /* end LU loop */ 1032 } /* end plugin loop */ 1033 if ((0 == opListCount) && (0 != operandLen)) { 1034 if (B_FALSE == bFoundOperand) { 1035 /* option/operand combo not found */ 1036 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1037 (void) fprintf(stderr, 1038 getTextString( 1039 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1040 operand[opoffset]); 1041 (void) fprintf(stderr, "\n"); 1042 } 1043 } 1044 1045 optionList = options; 1046 for (opIndex = 0; optionList->optval; optionList++, 1047 opIndex++) { 1048 if (B_FALSE == bFoundOption[opIndex]) { 1049 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1050 (void) fprintf(stderr, 1051 getTextString( 1052 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1053 optionList->optarg); 1054 (void) fprintf(stderr, "\n"); 1055 } 1056 } 1057 1058 1059 1060 } /* end loop through operands */ 1061 } /* we have operands and/or options */ 1062 1063 1064 return (mpstatus); 1065 } 1066 1067 1068 /* 1069 * **************************************************************************** 1070 * 1071 * compareLUName - 1072 * compare names directly and via devid if no match directly 1073 * 1074 * cmpString - first string to compare 1075 * deviceProperty - string from properties 1076 * sizeToCompare - size of deviceProperty 1077 * 1078 * returns B_TRUE if the strings match either directly or via devid 1079 * B_FALSE otherwise 1080 * 1081 * **************************************************************************** 1082 */ 1083 boolean_t 1084 compareLUName(MP_CHAR *cmpString, MP_CHAR *deviceProperty) 1085 { 1086 1087 boolean_t isSame = B_FALSE; 1088 int fd1, fd2; 1089 ddi_devid_t devid1 = NULL, devid2 = NULL; 1090 1091 if (0 == strcmp(cmpString, deviceProperty)) { 1092 isSame = B_TRUE; 1093 } else { 1094 /* user input didn't match, try via devid */ 1095 /* 1096 * I don't see a reason to print the error for 1097 * any of these since they'll get the error at 1098 * the end anyway 1099 */ 1100 1101 if (((fd1 = open(cmpString, O_RDONLY|O_NDELAY)) >= 0) && 1102 ((fd2 = open(deviceProperty, O_RDONLY|O_NDELAY)) >= 0) && 1103 (devid_get(fd1, &devid1) == 0) && 1104 (devid_get(fd2, &devid2) == 0) && 1105 ((NULL != devid1) && (NULL != devid2))) { 1106 if (0 == 1107 (devid_compare(devid1, devid2))) { 1108 isSame = B_TRUE; 1109 } 1110 } 1111 1112 if (NULL != devid1) { 1113 devid_free(devid1); 1114 } 1115 if (NULL != devid2) { 1116 devid_free(devid2); 1117 } 1118 } /* compare */ 1119 1120 return (isSame); 1121 } 1122 1123 1124 /* 1125 * **************************************************************************** 1126 * 1127 * listIndivudualLogicalUnit - 1128 * Used by list logical unit cli. 1129 * Displays info about an LU 1130 * 1131 * luOid - LU to list 1132 * luProps - properties of he LU to list 1133 * 1134 * **************************************************************************** 1135 */ 1136 int 1137 listIndividualLogicalUnit(MP_OID luOid, 1138 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps) 1139 { 1140 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 1141 MP_OID_LIST *pPathOidListArray; 1142 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1143 int numOperationalPaths, 1144 pa; 1145 1146 (void) printf("\t"); 1147 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName)); 1148 (void) printf("\n"); 1149 1150 mpstatus = MP_GetAssociatedPathOidList(luOid, 1151 &pPathOidListArray); 1152 if (mpstatus != MP_STATUS_SUCCESS) { 1153 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1154 (void) fprintf(stderr, 1155 getTextString(ERR_NO_LU_PATH_INFO_WITH_MISSING_LU_STR), 1156 getStringArray(luProps.deviceFileName, 1157 sizeof (luProps.deviceFileName))); 1158 (void) fprintf(stderr, "\n"); 1159 return (mpstatus); 1160 } 1161 (void) printf("\t\t%s %d\n", 1162 getTextString(TEXT_LB_PATH_COUNT), pPathOidListArray->oidCount); 1163 1164 numOperationalPaths = 0; 1165 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) { 1166 (void) memset(&pathProps, 0, 1167 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES)); 1168 mpstatus = 1169 MP_GetPathLogicalUnitProperties( 1170 pPathOidListArray->oids[pa], &pathProps); 1171 if (mpstatus != MP_STATUS_SUCCESS) { 1172 (void) fprintf(stderr, "%s: %s\n", 1173 cmdName, getTextString(ERR_NO_PROPERTIES)); 1174 return (mpstatus); 1175 } 1176 1177 /* cycle through and check status of each for */ 1178 /* operation path count */ 1179 if (MP_PATH_STATE_OKAY == pathProps.pathState) { 1180 numOperationalPaths++; 1181 } 1182 } 1183 1184 (void) printf("\t\t%s %d\n", 1185 getTextString(TEXT_LB_OP_PATH_COUNT), numOperationalPaths); 1186 1187 return (mpstatus); 1188 } 1189 1190 1191 /* 1192 * **************************************************************************** 1193 * 1194 * showLogicalUnit - 1195 * mpathadm show {logical-unit | LU} <logical-unit name>, ... 1196 * 1197 * operandLen - number of operands user passed into the cli 1198 * operand - pointer to operand list from user 1199 * 1200 * **************************************************************************** 1201 */ 1202 int 1203 showLogicalUnit(int operandLen, char *operand[]) 1204 { 1205 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1206 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1207 MP_PLUGIN_PROPERTIES pluginProps; 1208 MP_OID luOid, 1209 pluginOid; 1210 1211 int op; 1212 1213 for (op = 0; op < operandLen; op++) { 1214 if (op > 0) { 1215 (void) printf("\n"); 1216 } 1217 if (B_TRUE == getLogicalUnitOid(operand[op], &luOid)) { 1218 (void) memset(&luProps, 0, 1219 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1220 mpstatus = 1221 MP_GetMPLogicalUnitProperties( 1222 luOid, &luProps); 1223 if (mpstatus != MP_STATUS_SUCCESS) { 1224 (void) fprintf(stderr, "%s: %s\n", 1225 cmdName, getTextString(ERR_NO_PROPERTIES)); 1226 return (mpstatus); 1227 } 1228 1229 mpstatus = 1230 MP_GetAssociatedPluginOid(luOid, &pluginOid); 1231 if (mpstatus != MP_STATUS_SUCCESS) { 1232 (void) fprintf(stderr, "%s: %s\n", 1233 cmdName, 1234 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1235 return (mpstatus); 1236 } 1237 1238 mpstatus = 1239 MP_GetPluginProperties(pluginOid, &pluginProps); 1240 if (mpstatus != MP_STATUS_SUCCESS) { 1241 (void) fprintf(stderr, "%s: %s\n", 1242 cmdName, getTextString(ERR_NO_PROPERTIES)); 1243 return (mpstatus); 1244 } 1245 1246 if (showIndividualLogicalUnit(luOid, luProps, 1247 pluginProps) != 0) { 1248 return (ERROR_CLI_FAILED); 1249 } 1250 1251 } else { 1252 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1253 (void) fprintf(stderr, getTextString( 1254 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1255 operand[op]); 1256 (void) printf("\n"); 1257 } 1258 1259 } /* for each operand */ 1260 1261 return (mpstatus); 1262 } 1263 1264 1265 /* 1266 * **************************************************************************** 1267 * 1268 * showIndivudualLogicalUnit - 1269 * Used by show logical unit cli. 1270 * Displays info about an LU 1271 * 1272 * luOid - LU to show 1273 * luProps - properties of he LU to show 1274 * pluginProps - propertis of the plugin this LU belongs to 1275 * 1276 * **************************************************************************** 1277 */ 1278 int 1279 showIndividualLogicalUnit(MP_OID luOid, 1280 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps, 1281 MP_PLUGIN_PROPERTIES pluginProps) 1282 { 1283 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 1284 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps; 1285 MP_TARGET_PORT_PROPERTIES tportProps; 1286 MP_INITIATOR_PORT_PROPERTIES initProps; 1287 MP_OID_LIST *pPathOidListArray, 1288 *pTPGOidListArray, 1289 *pTportOidListArray; 1290 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1291 boolean_t showTportLabel = B_TRUE; 1292 1293 int pa, 1294 tpg, 1295 tport; 1296 1297 (void) printf("%s ", getTextString(TEXT_LB_LOGICAL_UNIT)); 1298 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName)); 1299 (void) printf("\n"); 1300 (void) printf("\t%s %s\n", getTextString(TEXT_LB_MPATH_SUPPORT), 1301 pluginProps.fileName); 1302 1303 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR)); 1304 displayArray(luProps.vendor, 1305 sizeof (luProps.vendor)); 1306 (void) printf("\n\t%s ", getTextString(TEXT_LB_PRODUCT)); 1307 displayArray(luProps.product, 1308 sizeof (luProps.product)); 1309 (void) printf("\n\t%s ", getTextString(TEXT_LB_REVISION)); 1310 displayArray(luProps.revision, 1311 sizeof (luProps.revision)); 1312 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME_TYPE)); 1313 displayLogicalUnitNameTypeString(luProps.nameType); 1314 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME)); 1315 displayArray(luProps.name, sizeof (luProps.name)); 1316 (void) printf("\n\t%s %s\n", getTextString(TEXT_LB_ASYMMETRIC), 1317 (MP_TRUE == luProps.asymmetric)? 1318 getTextString(TEXT_YES):getTextString(TEXT_NO)); 1319 1320 (void) printf("\t%s ", getTextString(TEXT_LB_CURR_LOAD_BALANCE)); 1321 /* don't ignore load balance type none. */ 1322 if (luProps.currentLoadBalanceType == 0) { 1323 (void) printf("%s", getTextString(TEXT_LBTYPE_NONE)); 1324 } else { 1325 displayLoadBalanceString(luProps.currentLoadBalanceType); 1326 } 1327 (void) printf("\n"); 1328 1329 (void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID)); 1330 if (0xffffffff == luProps.logicalUnitGroupID) { 1331 (void) printf("%s\n", getTextString(TEXT_NA)); 1332 } else { 1333 (void) printf("0x%x\n", luProps.logicalUnitGroupID); 1334 } 1335 1336 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB)); 1337 if (MP_FALSE == pluginProps.autoFailbackSupport) { 1338 (void) printf("%s\n", getTextString(TEXT_NA)); 1339 } else { 1340 (void) printf("%s\n", (MP_TRUE == luProps.autoFailbackEnabled)? 1341 getTextString(TEXT_ON):getTextString(TEXT_OFF)); 1342 } 1343 1344 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB)); 1345 if (MP_FALSE == pluginProps.autoProbingSupport) { 1346 (void) printf("%s\n", getTextString(TEXT_NA)); 1347 } else { 1348 (void) printf("%s\n", (MP_TRUE == luProps.autoProbingEnabled)? 1349 getTextString(TEXT_ON):getTextString(TEXT_OFF)); 1350 } 1351 1352 1353 /* get path info */ 1354 mpstatus = MP_GetAssociatedPathOidList(luOid, &pPathOidListArray); 1355 if (mpstatus != MP_STATUS_SUCCESS) { 1356 (void) fprintf(stderr, "%s: %s", cmdName, 1357 getTextString(ERR_NO_LU_PATH_INFO)); 1358 displayArray(luProps.deviceFileName, 1359 sizeof (luProps.deviceFileName)); 1360 (void) fprintf(stderr, "\n"); 1361 return (mpstatus); 1362 } 1363 1364 (void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO)); 1365 1366 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) { 1367 (void) memset(&pathProps, 0, 1368 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES)); 1369 mpstatus = MP_GetPathLogicalUnitProperties( 1370 pPathOidListArray->oids[pa], &pathProps); 1371 if (mpstatus != MP_STATUS_SUCCESS) { 1372 (void) fprintf(stderr, "%s: %s\n", 1373 cmdName, getTextString(ERR_NO_PROPERTIES)); 1374 return (mpstatus); 1375 } 1376 1377 (void) printf("\t\t%s ", 1378 getTextString(TEXT_LB_INIT_PORT_NAME)); 1379 if ((mpstatus = 1380 MP_GetInitiatorPortProperties(pathProps.initiatorPortOid, 1381 &initProps)) != MP_STATUS_SUCCESS) { 1382 (void) printf("%s\n", getTextString(TEXT_UNKNOWN)); 1383 } else { 1384 displayArray(initProps.portID, 1385 sizeof (initProps.portID)); 1386 (void) printf("\n"); 1387 } 1388 1389 (void) printf("\t\t%s ", 1390 getTextString(TEXT_LB_TARGET_PORT_NAME)); 1391 if ((mpstatus = 1392 MP_GetTargetPortProperties(pathProps.targetPortOid, 1393 &tportProps)) != MP_STATUS_SUCCESS) { 1394 (void) printf("%s\n", getTextString(TEXT_UNKNOWN)); 1395 } else { 1396 displayArray(tportProps.portID, 1397 sizeof (tportProps.portID)); 1398 (void) printf("\n"); 1399 } 1400 1401 (void) printf("\t\t%s ", getTextString(TEXT_LB_OVERRIDE_PATH)); 1402 if (MP_FALSE == pluginProps.canOverridePaths) { 1403 (void) printf("%s\n", getTextString(TEXT_NA)); 1404 } else if (luProps.overridePath.objectSequenceNumber == 1405 pPathOidListArray->oids[pa].objectSequenceNumber) { 1406 (void) printf("%s\n", getTextString(TEXT_YES)); 1407 } else { 1408 (void) printf("%s\n", getTextString(TEXT_NO)); 1409 } 1410 1411 (void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE), 1412 getPathStateStr(pathProps.pathState)); 1413 1414 (void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED), 1415 pathProps.disabled?getTextString(TEXT_YES): 1416 getTextString(TEXT_NO)); 1417 1418 } 1419 1420 /* get tpg info */ 1421 mpstatus = MP_GetAssociatedTPGOidList(luOid, &pTPGOidListArray); 1422 if (mpstatus != MP_STATUS_SUCCESS) { 1423 (void) fprintf(stderr, "%s: %s", cmdName, 1424 getTextString(ERR_NO_ASSOC_TPGS)); 1425 } else { 1426 1427 /* display tpg info only if is assymetric */ 1428 if (MP_TRUE == luProps.asymmetric) { 1429 (void) printf("\t%s \n", getTextString(TEXT_LB_TPG_INFO)); 1430 } 1431 1432 for (tpg = 0; tpg < pTPGOidListArray->oidCount; tpg++) { 1433 (void) memset(&tpgProps, 0, 1434 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES)); 1435 mpstatus = MP_GetTargetPortGroupProperties( 1436 pTPGOidListArray->oids[tpg], &tpgProps); 1437 if (mpstatus != MP_STATUS_SUCCESS) { 1438 (void) fprintf(stderr, "%s: %s", 1439 cmdName, getTextString(ERR_NO_PROPERTIES)); 1440 } else { 1441 /* display tpg info only if is assymetric */ 1442 if (tpg > 0) { 1443 (void) printf("\n"); 1444 } 1445 if (MP_TRUE == luProps.asymmetric) { 1446 (void) printf("\t\t%s %d\n", 1447 getTextString(TEXT_LB_ID), 1448 tpgProps.tpgID); 1449 (void) printf("\t\t%s %s\n", 1450 getTextString( 1451 TEXT_LB_EXPLICIT_FAILOVER), 1452 (MP_TRUE == 1453 tpgProps.explicitFailover)? 1454 getTextString(TEXT_YES): 1455 getTextString(TEXT_NO)); 1456 (void) printf("\t\t%s %s\n", 1457 getTextString( 1458 TEXT_LB_ACCESS_STATE), 1459 getAccessStateStr( 1460 tpgProps.accessState)); 1461 /* display label for each tpg. */ 1462 (void) printf("\t\t%s\n", 1463 getTextString(TEXT_TPORT_LIST)); 1464 } else { 1465 /* display label once for symmetric. */ 1466 if (B_TRUE == showTportLabel) { 1467 (void) printf("\t%s\n", 1468 getTextString(TEXT_TPORT_LIST)); 1469 showTportLabel = B_FALSE; 1470 } 1471 } 1472 1473 /* get target port info */ 1474 mpstatus = MP_GetTargetPortOidList( 1475 pTPGOidListArray->oids[tpg], 1476 &pTportOidListArray); 1477 if (mpstatus != MP_STATUS_SUCCESS) { 1478 (void) fprintf(stderr, "%s: %s", 1479 cmdName, 1480 getTextString(ERR_NO_ASSOC_TPORTS)); 1481 } else { 1482 1483 /* begin back-up indentation */ 1484 for (tport = 0; tport < pTportOidListArray->oidCount; tport++) { 1485 (void) memset(&tportProps, 0, 1486 sizeof (MP_TARGET_PORT_PROPERTIES)); 1487 if ((mpstatus = 1488 MP_GetTargetPortProperties(pTportOidListArray->oids[tport], 1489 &tportProps)) != MP_STATUS_SUCCESS) { 1490 (void) fprintf(stderr, "%s: %s", 1491 cmdName, getTextString(ERR_NO_PROPERTIES)); 1492 } else { 1493 if (MP_TRUE == luProps.asymmetric) { 1494 (void) printf("\t\t\t%s ", 1495 getTextString(TEXT_LB_NAME)); 1496 displayArray(tportProps.portID, 1497 sizeof (tportProps.portID)); 1498 (void) printf("\n\t\t\t%s %d\n", 1499 getTextString(TEXT_LB_RELATIVE_ID), 1500 tportProps.relativePortID); 1501 } else { 1502 (void) printf("\t\t%s ", 1503 getTextString(TEXT_LB_NAME)); 1504 displayArray(tportProps.portID, 1505 sizeof (tportProps.portID)); 1506 (void) printf("\n\t\t%s %d\n", 1507 getTextString(TEXT_LB_RELATIVE_ID), 1508 tportProps.relativePortID); 1509 } 1510 /* insert blank line if not the last target port. */ 1511 if (!(tport == (pTportOidListArray->oidCount - 1))) { 1512 (void) printf("\n"); 1513 } 1514 } 1515 } /* for each target port */ 1516 /* end back-up indentation */ 1517 1518 } /* else got target port props */ 1519 } /* else got TPG props */ 1520 } /* for each TPG */ 1521 } /* else got tpg list */ 1522 1523 1524 return (mpstatus); 1525 } 1526 1527 1528 /* 1529 * **************************************************************************** 1530 * 1531 * modifyLogicalUnit - 1532 * mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ... 1533 * 1534 * operandLen - number of operands user passed into the cli 1535 * operand - pointer to operand list from user 1536 * options - pointer to option list from user 1537 * 1538 * **************************************************************************** 1539 */ 1540 int 1541 modifyLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options) 1542 { 1543 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1544 MP_OID luOid; 1545 cmdOptions_t *optionList = options; 1546 char *cmdStr = 1547 getTextString( 1548 TEXT_UNKNOWN); 1549 int op; 1550 1551 for (op = 0; op < operandLen; op++) { 1552 if (B_TRUE != getLogicalUnitOid(operand[op], &luOid)) { 1553 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1554 (void) fprintf(stderr, 1555 getTextString(ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1556 operand[op]); 1557 (void) printf("\n"); 1558 return (ERROR_CLI_FAILED); 1559 } 1560 1561 /* we found the lu oid, now change the options requested */ 1562 switch (optionList->optval) { 1563 case 'a': 1564 /* modify autofailback */ 1565 cmdStr = getTextString(TEXT_AUTO_FAILBACK); 1566 if (0 == strcasecmp(optionList->optarg, 1567 getTextString(TEXT_ON))) { 1568 mpstatus = 1569 MP_EnableAutoFailback(luOid); 1570 } else if (0 == strcasecmp(optionList->optarg, 1571 getTextString(TEXT_OFF))) { 1572 mpstatus = 1573 MP_DisableAutoFailback(luOid); 1574 } else { 1575 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1576 (void) fprintf(stderr, getTextString( 1577 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1578 cmdStr, 1579 getTextString( 1580 TEXT_ILLEGAL_ARGUMENT)); 1581 (void) printf("\n"); 1582 return (ERROR_CLI_FAILED); 1583 } 1584 break; 1585 case 'p': 1586 /* modify autoprobing */ 1587 cmdStr = getTextString(TEXT_AUTO_PROBING); 1588 if (0 == strcasecmp(optionList->optarg, 1589 getTextString(TEXT_ON))) { 1590 mpstatus = 1591 MP_EnableAutoProbing(luOid); 1592 } else if (0 == strcasecmp(optionList->optarg, 1593 getTextString(TEXT_OFF))) { 1594 mpstatus = 1595 MP_DisableAutoProbing(luOid); 1596 } else { 1597 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1598 (void) fprintf(stderr, getTextString( 1599 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1600 cmdStr, 1601 getTextString( 1602 TEXT_ILLEGAL_ARGUMENT)); 1603 (void) printf("\n"); 1604 return (ERROR_CLI_FAILED); 1605 } 1606 break; 1607 case 'b': 1608 /* modify loadbalance type */ 1609 cmdStr = getTextString(TEXT_LOAD_BALANCE); 1610 mpstatus = 1611 MP_SetLogicalUnitLoadBalanceType(luOid, 1612 getLbValueFromString(optionList->optarg)); 1613 break; 1614 1615 } /* switch */ 1616 if (MP_STATUS_SUCCESS != mpstatus) { 1617 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1618 (void) fprintf(stderr, 1619 getTextString( 1620 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1621 cmdStr, getMpStatusStr(mpstatus)); 1622 (void) printf("\n"); 1623 return (ERROR_CLI_FAILED); 1624 } 1625 } /* for each operand */ 1626 return (mpstatus); 1627 } 1628 1629 1630 /* 1631 * **************************************************************************** 1632 * 1633 * failoverLogicalUnit - 1634 * mpathadm failover {logical-unit | LU} <logical-unit name>, ... 1635 * 1636 * operand - pointer to operand list from user 1637 * 1638 * **************************************************************************** 1639 */ 1640 int 1641 failoverLogicalUnit(char *operand[]) 1642 { 1643 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1644 MP_OID luOid; 1645 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1646 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps; 1647 MP_OID_LIST *pTpgOidListArray; 1648 boolean_t bFoundIt = B_FALSE; 1649 MP_TPG_STATE_PAIR tpgStatePair; 1650 1651 int tpg; 1652 1653 if (B_TRUE != getLogicalUnitOid(operand[0], &luOid)) { 1654 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1655 (void) fprintf(stderr, getTextString( 1656 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1657 operand[0]); 1658 (void) printf("\n"); 1659 return (ERROR_CLI_FAILED); 1660 } 1661 1662 /* get LUN properties and check to be sure it's asymmetric */ 1663 (void) memset(&luProps, 0, 1664 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1665 mpstatus = 1666 MP_GetMPLogicalUnitProperties(luOid, &luProps); 1667 if (mpstatus != MP_STATUS_SUCCESS) { 1668 (void) fprintf(stderr, "%s: %s\n", 1669 cmdName, getTextString(ERR_NO_PROPERTIES)); 1670 return (mpstatus); 1671 } 1672 1673 if (MP_TRUE != luProps.asymmetric) { 1674 (void) fprintf(stderr, "%s: %s\n", 1675 cmdName, getTextString(ERR_LU_NOT_ASYMMETRIC)); 1676 return (ERROR_CLI_FAILED); 1677 } 1678 1679 /* get TPGs for this LUN */ 1680 mpstatus = 1681 MP_GetAssociatedTPGOidList(luOid, &pTpgOidListArray); 1682 if (mpstatus != MP_STATUS_SUCCESS) { 1683 (void) fprintf(stderr, "%s: %s\n", 1684 cmdName, getTextString(ERR_NO_ASSOC_TPGS)); 1685 return (mpstatus); 1686 } 1687 1688 /* pick a TPG whose state is active or standby, and change it */ 1689 /* to opposite via MP_SetTPGAccessState */ 1690 bFoundIt = B_FALSE; 1691 for (tpg = 0; tpg < pTpgOidListArray->oidCount; tpg++) { 1692 (void) memset(&tpgProps, 0, 1693 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES)); 1694 mpstatus = 1695 MP_GetTargetPortGroupProperties( 1696 pTpgOidListArray->oids[tpg], &tpgProps); 1697 if (mpstatus != MP_STATUS_SUCCESS) { 1698 (void) fprintf(stderr, "%s: %s\n", 1699 cmdName, getTextString(ERR_NO_PROPERTIES)); 1700 return (ERROR_CLI_FAILED); 1701 } 1702 if (MP_FALSE == tpgProps.explicitFailover) { 1703 (void) fprintf(stderr, "%s: %s\n", 1704 cmdName, getTextString(ERR_NO_FAILOVER_ALLOWED)); 1705 return (ERROR_CLI_FAILED); 1706 } 1707 1708 /* find one that is standby */ 1709 if ((MP_ACCESS_STATE_STANDBY == 1710 tpgProps.accessState) && (B_FALSE == bFoundIt)) { 1711 1712 bFoundIt = B_TRUE; 1713 1714 tpgStatePair.tpgOid = 1715 pTpgOidListArray->oids[tpg]; 1716 tpgStatePair.desiredState = 1717 MP_ACCESS_STATE_ACTIVE; 1718 mpstatus = 1719 MP_SetTPGAccess(luOid, 1, &tpgStatePair); 1720 if (MP_STATUS_SUCCESS != mpstatus) { 1721 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1722 (void) fprintf(stderr, getTextString( 1723 ERR_FAILED_TO_FAILOVER_WITH_REASON), 1724 getMpStatusStr(mpstatus)); 1725 (void) printf("\n"); 1726 return (mpstatus); 1727 } 1728 } 1729 1730 1731 } /* for each tpg */ 1732 1733 if (B_FALSE == bFoundIt) { 1734 (void) fprintf(stderr, "%s: %s\n", 1735 cmdName, getTextString(ERR_LU_ACCESS_STATE_UNCHANGED)); 1736 return (ERROR_CLI_FAILED); 1737 } 1738 1739 return (mpstatus); 1740 } 1741 1742 1743 /* 1744 * **************************************************************************** 1745 * 1746 * getLogicalUnitOid - 1747 * Search through all plugins and get the OID for specified logical unit 1748 * 1749 * luFileName - file name of LU (specified by the user) to find 1750 * pLuOid - OID to return 1751 * 1752 * **************************************************************************** 1753 */ 1754 boolean_t 1755 getLogicalUnitOid(MP_CHAR *luFileName, MP_OID *pluOid) 1756 { 1757 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1758 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1759 MP_PLUGIN_PROPERTIES pluginProps; 1760 MP_OID_LIST *pPluginOidList, 1761 *pLogicalUnitOidList; 1762 boolean_t foundIt = B_FALSE; 1763 1764 int i, 1765 lu; 1766 1767 int fd1, fd2; 1768 ddi_devid_t devid1 = NULL, devid2 = NULL; 1769 1770 if (NULL == pluOid) { 1771 /* print some kind of error msg here - should never happen */ 1772 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1773 (void) fprintf(stderr, getTextString(ERR_MEMORY_ALLOCATION)); 1774 (void) printf("\n"); 1775 return (B_FALSE); 1776 } 1777 1778 pluOid->objectSequenceNumber = 0; 1779 pluOid->objectType = 0; 1780 pluOid->ownerId = 0; 1781 1782 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 1783 != MP_STATUS_SUCCESS) { 1784 (void) fprintf(stderr, "%s: %s\n", cmdName, 1785 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1786 return (B_FALSE); 1787 } 1788 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 1789 (void) fprintf(stderr, "%s: %s\n", cmdName, 1790 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1791 return (ERROR_CLI_FAILED); 1792 } 1793 for (i = 0; i < pPluginOidList->oidCount; i++) { 1794 1795 /* get properties so we can list the name */ 1796 (void) memset(&pluginProps, 0, sizeof (MP_PLUGIN_PROPERTIES)); 1797 if ((mpstatus = 1798 MP_GetPluginProperties(pPluginOidList->oids[i], 1799 &pluginProps)) != MP_STATUS_SUCCESS) { 1800 (void) fprintf(stderr, "%s: %s\n", 1801 cmdName, getTextString(ERR_NO_PROPERTIES)); 1802 return (B_FALSE); 1803 } 1804 1805 /* attempt to find this logical unit */ 1806 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i], 1807 &pLogicalUnitOidList); 1808 if (mpstatus != MP_STATUS_SUCCESS) { 1809 (void) fprintf(stderr, "%s: %s\n", 1810 cmdName, getTextString(ERR_NO_LU_LIST)); 1811 return (B_FALSE); 1812 } 1813 1814 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) && 1815 (B_FALSE == foundIt); lu++) { 1816 1817 /* get lu properties so we can check the name */ 1818 (void) memset(&luProps, 0, 1819 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1820 mpstatus = 1821 MP_GetMPLogicalUnitProperties( 1822 pLogicalUnitOidList->oids[lu], &luProps); 1823 if (mpstatus != MP_STATUS_SUCCESS) { 1824 (void) fprintf(stderr, "%s: %s\n", 1825 cmdName, getTextString(ERR_NO_PROPERTIES)); 1826 return (B_FALSE); 1827 } 1828 1829 if (0 == strcmp(luFileName, luProps.deviceFileName)) { 1830 foundIt = B_TRUE; 1831 } else { 1832 /* user input didn't match, try via devid */ 1833 /* 1834 * I don't see a reason to print the error for 1835 * any of these since they'll get the error at 1836 * the end anyway 1837 */ 1838 1839 1840 if (((fd1 = open(luFileName, 1841 O_RDONLY|O_NDELAY)) >= 0) && 1842 ((fd2 = open(luProps.deviceFileName, 1843 O_RDONLY|O_NDELAY)) >= 0) && 1844 (devid_get(fd1, &devid1) == 0) && 1845 (devid_get(fd2, &devid2) == 0) && 1846 ((NULL != devid1) && (NULL != devid2))) { 1847 if (0 == 1848 (devid_compare(devid1, devid2))) { 1849 foundIt = B_TRUE; 1850 } 1851 } 1852 1853 if (NULL != devid1) { 1854 devid_free(devid1); 1855 } 1856 if (NULL != devid2) { 1857 devid_free(devid2); 1858 } 1859 } 1860 if (B_TRUE == foundIt) { 1861 pluOid->objectSequenceNumber = 1862 pLogicalUnitOidList-> 1863 oids[lu].objectSequenceNumber; 1864 pluOid->objectType = 1865 pLogicalUnitOidList-> 1866 oids[lu].objectType; 1867 pluOid->ownerId = 1868 pLogicalUnitOidList->oids[lu].ownerId; 1869 } 1870 } 1871 } 1872 1873 return (foundIt); 1874 } 1875 1876 1877 /* 1878 * **************************************************************************** 1879 * 1880 * listInitiatorPort - 1881 * mpathadm list initiator-port [<initiator-port name>, ...] 1882 * 1883 * operandLen - number of operands user passed into the cli 1884 * operand - pointer to operand list from user 1885 * 1886 * **************************************************************************** 1887 */ 1888 int 1889 listInitiatorPort(int operandLen, char *operand[]) 1890 { 1891 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1892 MP_INITIATOR_PORT_PROPERTIES initProps; 1893 MP_OID_LIST *pPluginOidList, 1894 *pInitOidList; 1895 boolean_t bListIt = B_FALSE; 1896 boolean_t *foundOp; 1897 1898 int ol, 1899 i, 1900 iport; 1901 1902 foundOp = malloc((sizeof (boolean_t)) * operandLen); 1903 if (NULL == foundOp) { 1904 (void) fprintf(stdout, "%s\n", 1905 getTextString(ERR_MEMORY_ALLOCATION)); 1906 return (ERROR_CLI_FAILED); 1907 } 1908 1909 for (ol = 0; ol < operandLen; ol++) { 1910 foundOp[ol] = B_FALSE; 1911 } 1912 1913 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 1914 != MP_STATUS_SUCCESS) { 1915 (void) fprintf(stderr, "%s: %s\n", cmdName, 1916 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1917 return (mpstatus); 1918 } 1919 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 1920 (void) fprintf(stderr, "%s: %s\n", cmdName, 1921 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1922 return (ERROR_CLI_FAILED); 1923 } 1924 1925 for (i = 0; i < pPluginOidList->oidCount; i++) { 1926 mpstatus = 1927 MP_GetInitiatorPortOidList(pPluginOidList->oids[i], 1928 &pInitOidList); 1929 if (mpstatus != MP_STATUS_SUCCESS) { 1930 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1931 (void) fprintf(stderr, 1932 getTextString(ERR_NO_INIT_PORT_LIST_WITH_REASON), 1933 getMpStatusStr(mpstatus)); 1934 (void) printf("\n"); 1935 } else if ((NULL == pInitOidList) || 1936 (pInitOidList->oidCount < 1)) { 1937 (void) fprintf(stderr, "%s: %s\n", cmdName, 1938 getTextString(ERR_NO_INIT_PORTS)); 1939 } else { 1940 for (iport = 0; 1941 iport < pInitOidList->oidCount; iport ++) { 1942 bListIt = B_FALSE; 1943 if ((mpstatus = 1944 MP_GetInitiatorPortProperties( 1945 pInitOidList->oids[iport], 1946 &initProps)) != MP_STATUS_SUCCESS) { 1947 (void) fprintf(stderr, 1948 "%s: %s\n", cmdName, 1949 getTextString(ERR_NO_PROPERTIES)); 1950 } else { 1951 /* if no operands listed, */ 1952 /* list all we find */ 1953 if (0 == operandLen) { 1954 bListIt = B_TRUE; 1955 } else { 1956 1957 /* check each operand */ 1958 /* Is it */ 1959 /* the one we want to list? */ 1960 for (ol = 0; 1961 ol < operandLen; ol++) { 1962 if (0 == 1963 strcmp(operand[ol], 1964 initProps. 1965 portID)) { 1966 bListIt = 1967 B_TRUE; 1968 foundOp[ol] = 1969 B_TRUE; 1970 } 1971 } 1972 } 1973 } 1974 1975 if (B_TRUE == bListIt) { 1976 1977 if (listIndividualInitiatorPort( 1978 initProps) != 0) { 1979 return (ERROR_CLI_FAILED); 1980 } 1981 1982 } /* list It */ 1983 1984 } /* for each initiator port */ 1985 } /* else found an init port */ 1986 1987 } /* for each plugin */ 1988 1989 for (ol = 0; ol < operandLen; ol++) { 1990 if (B_FALSE == foundOp[ol]) { 1991 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1992 (void) fprintf(stderr, getTextString( 1993 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR), 1994 operand[ol]); 1995 (void) printf("\n"); 1996 } 1997 } 1998 1999 return (mpstatus); 2000 } 2001 2002 2003 /* 2004 * **************************************************************************** 2005 * 2006 * listIndividualInitiatorPort - 2007 * used by listInitiatorPort to list info for one init port 2008 * 2009 * initProps - properties of initiator port to list 2010 * 2011 * **************************************************************************** 2012 */ 2013 int 2014 listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps) 2015 { 2016 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2017 2018 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT)); 2019 displayArray(initProps.portID, 2020 sizeof (initProps.portID)); 2021 (void) printf("\n"); 2022 2023 return (mpstatus); 2024 2025 } 2026 2027 2028 /* 2029 * **************************************************************************** 2030 * 2031 * showInitiatorPort - 2032 * mpathadm show initiator-port <initiator-port name>, ... 2033 * 2034 * operandLen - number of operands user passed into the cli 2035 * operand - pointer to operand list from user 2036 * 2037 * **************************************************************************** 2038 */ 2039 int 2040 showInitiatorPort(int operandLen, char *operand[]) 2041 { 2042 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2043 MP_INITIATOR_PORT_PROPERTIES initProps; 2044 MP_OID_LIST *pPluginOidList, 2045 *pInitOidList; 2046 boolean_t bListIt = B_FALSE, 2047 bFoundIt = B_FALSE; 2048 int op, 2049 i, 2050 iport; 2051 2052 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 2053 != MP_STATUS_SUCCESS) { 2054 (void) fprintf(stderr, "%s: %s\n", cmdName, 2055 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2056 return (mpstatus); 2057 } 2058 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 2059 (void) fprintf(stderr, "%s: %s\n", cmdName, 2060 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2061 return (ERROR_CLI_FAILED); 2062 } 2063 2064 for (op = 0; op < operandLen; op++) { 2065 bFoundIt = B_FALSE; 2066 2067 for (i = 0; i < pPluginOidList->oidCount; i++) { 2068 2069 mpstatus = 2070 MP_GetInitiatorPortOidList(pPluginOidList->oids[i], 2071 &pInitOidList); 2072 if (mpstatus != MP_STATUS_SUCCESS) { 2073 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2074 (void) fprintf(stderr, 2075 getTextString( 2076 ERR_NO_INIT_PORT_LIST_WITH_REASON), 2077 getMpStatusStr(mpstatus)); 2078 (void) printf("\n"); 2079 } else if ((NULL == pInitOidList) || 2080 (pInitOidList->oidCount < 1)) { 2081 (void) fprintf(stderr, "%s: %s\n", cmdName, 2082 getTextString(ERR_NO_INIT_PORTS)); 2083 } else { 2084 2085 for (iport = 0; 2086 iport < pInitOidList->oidCount; 2087 iport ++) { 2088 bListIt = B_FALSE; 2089 2090 if ((mpstatus = 2091 MP_GetInitiatorPortProperties( 2092 pInitOidList->oids[iport], 2093 &initProps)) 2094 != MP_STATUS_SUCCESS) { 2095 (void) fprintf(stderr, 2096 "%s: %s\n", cmdName, 2097 getTextString(ERR_NO_PROPERTIES)); 2098 } else { 2099 if (0 == strcmp(operand[op], 2100 initProps.portID)) { 2101 bListIt = B_TRUE; 2102 bFoundIt = B_TRUE; 2103 } 2104 } 2105 2106 if (B_TRUE == bListIt) { 2107 mpstatus = 2108 showIndividualInitiatorPort( 2109 initProps); 2110 if (0 != mpstatus) { 2111 return (mpstatus); 2112 } 2113 2114 } /* list It */ 2115 2116 } /* for each initiator port */ 2117 } /* else found an init port */ 2118 2119 } /* for each plugin */ 2120 2121 if (B_FALSE == bFoundIt) { 2122 /* need temp string here since we need to fill in a */ 2123 /* name in the error string */ 2124 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2125 (void) fprintf(stderr, getTextString( 2126 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR), 2127 operand[op]); 2128 (void) printf("\n"); 2129 } 2130 2131 } /* for each operand */ 2132 2133 return (mpstatus); 2134 } 2135 2136 2137 /* 2138 * **************************************************************************** 2139 * 2140 * showIndividualInitiatorPort - 2141 * used by showInitiatorPort to show info for one init port 2142 * 2143 * initProps - properties of initiator port to show 2144 * 2145 * **************************************************************************** 2146 */ 2147 int 2148 showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps) 2149 { 2150 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2151 2152 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT)); 2153 displayArray(initProps.portID, 2154 sizeof (initProps.portID)); 2155 2156 (void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE)); 2157 displayTransportTypeString(initProps.portType); 2158 (void) printf("\n"); 2159 2160 (void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE)); 2161 displayArray(initProps.osDeviceFile, 2162 sizeof (initProps.osDeviceFile)); 2163 (void) printf("\n"); 2164 2165 return (mpstatus); 2166 } 2167 2168 2169 /* 2170 * **************************************************************************** 2171 * 2172 * enablePath - 2173 * mpathadm enable path -i <initiator-port> 2174 * -t <target-port name> -l <logical-unit name> 2175 * 2176 * options - pointer to option list from user 2177 * 2178 * **************************************************************************** 2179 */ 2180 int 2181 enablePath(cmdOptions_t *options) 2182 { 2183 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2184 MP_OID pathOid; 2185 2186 cmdOptions_t *optionList = options; 2187 boolean_t bHaveInit = B_FALSE, 2188 bHaveTarg = B_FALSE, 2189 bHaveLu = B_FALSE; 2190 2191 for (; optionList->optval; optionList++) { 2192 switch (optionList->optval) { 2193 case 'i': 2194 /* have init port name */ 2195 bHaveInit = B_TRUE; 2196 break; 2197 case 't': 2198 /* have target port id */ 2199 bHaveTarg = B_TRUE; 2200 break; 2201 case 'l': 2202 /* have LU name */ 2203 bHaveLu = B_TRUE; 2204 break; 2205 } 2206 } 2207 if (B_FALSE == bHaveInit) { 2208 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2209 (void) fprintf(stderr, 2210 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2211 getTextString(MISSING_INIT_PORT_NAME)); 2212 (void) printf("\n"); 2213 return (ERROR_CLI_FAILED); 2214 } else if (B_FALSE == bHaveTarg) { 2215 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2216 (void) fprintf(stderr, 2217 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2218 getTextString(MISSING_TARGET_PORT_NAME)); 2219 (void) printf("\n"); 2220 return (ERROR_CLI_FAILED); 2221 } else if (B_FALSE == bHaveLu) { 2222 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2223 (void) fprintf(stderr, 2224 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2225 getTextString(MISSING_LU_NAME)); 2226 (void) printf("\n"); 2227 return (ERROR_CLI_FAILED); 2228 } 2229 2230 if (B_FALSE == getPathOid(options, &pathOid)) { 2231 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2232 (void) fprintf(stderr, 2233 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2234 getTextString(FAILED_TO_FIND_PATH)); 2235 (void) printf("\n"); 2236 return (ERROR_CLI_FAILED); 2237 } 2238 2239 /* found the path, attempt to enable it */ 2240 mpstatus = MP_EnablePath(pathOid); 2241 if (mpstatus != MP_STATUS_SUCCESS) { 2242 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2243 (void) fprintf(stderr, 2244 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2245 getMpStatusStr(mpstatus)); 2246 (void) printf("\n"); 2247 return (mpstatus); 2248 } 2249 2250 return (mpstatus); 2251 } 2252 2253 2254 /* 2255 * **************************************************************************** 2256 * 2257 * disablePath - 2258 * mpathadm disable path -i <initiator-port> 2259 * -t <target-port name> -l <logical-unit name> 2260 * 2261 * options - pointer to option list from user 2262 * 2263 * **************************************************************************** 2264 */ 2265 int 2266 disablePath(cmdOptions_t *options) 2267 { 2268 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2269 MP_OID pathOid; 2270 2271 cmdOptions_t *optionList = options; 2272 boolean_t bHaveInit = B_FALSE, 2273 bHaveTarg = B_FALSE, 2274 bHaveLu = B_FALSE; 2275 2276 for (; optionList->optval; optionList++) { 2277 switch (optionList->optval) { 2278 case 'i': 2279 /* have init port name */ 2280 bHaveInit = B_TRUE; 2281 break; 2282 case 't': 2283 /* have target port id */ 2284 bHaveTarg = B_TRUE; 2285 break; 2286 case 'l': 2287 /* have LU name */ 2288 bHaveLu = B_TRUE; 2289 break; 2290 } 2291 } 2292 if (B_FALSE == bHaveInit) { 2293 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2294 (void) fprintf(stderr, 2295 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2296 getTextString(MISSING_INIT_PORT_NAME)); 2297 (void) printf("\n"); 2298 return (ERROR_CLI_FAILED); 2299 } else if (B_FALSE == bHaveTarg) { 2300 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2301 (void) fprintf(stderr, 2302 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2303 getTextString(MISSING_TARGET_PORT_NAME)); 2304 (void) printf("\n"); 2305 return (ERROR_CLI_FAILED); 2306 } else if (B_FALSE == bHaveLu) { 2307 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2308 (void) fprintf(stderr, 2309 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2310 getTextString(MISSING_LU_NAME)); 2311 (void) printf("\n"); 2312 return (ERROR_CLI_FAILED); 2313 } 2314 2315 if (B_FALSE == getPathOid(options, &pathOid)) { 2316 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2317 (void) fprintf(stderr, 2318 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2319 getTextString(FAILED_TO_FIND_PATH)); 2320 (void) printf("\n"); 2321 return (ERROR_CLI_FAILED); 2322 } 2323 2324 /* found the path, attempt to enable it */ 2325 mpstatus = MP_DisablePath(pathOid); 2326 if (MP_STATUS_SUCCESS != mpstatus) { 2327 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2328 (void) fprintf(stderr, getTextString( 2329 ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2330 getMpStatusStr(mpstatus)); 2331 (void) printf("\n"); 2332 return (mpstatus); 2333 } 2334 2335 2336 return (mpstatus); 2337 } 2338 2339 2340 /* 2341 * **************************************************************************** 2342 * 2343 * overridePath - 2344 * mpathadm override path {-i <initiator-port> 2345 * -t <target-port name> | -c} <logical-unit name> 2346 * 2347 * options - pointer to option list from user 2348 * 2349 * **************************************************************************** 2350 */ 2351 int 2352 overridePath(cmdOptions_t *options) 2353 { 2354 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2355 MP_OID pathOid, luOid; 2356 boolean_t bCancelOverride = B_FALSE; 2357 MP_CHAR pLuDeviceFileName[256]; 2358 cmdOptions_t *optionList = options; 2359 2360 /* First check to see if we have the cancel option, */ 2361 /* May as well save off the lun while we're at it */ 2362 for (; optionList->optval; optionList++) { 2363 switch (optionList->optval) { 2364 case 'c': 2365 /* we have a cancel */ 2366 bCancelOverride = B_TRUE; 2367 break; 2368 case 'l': 2369 /* we have a lun- save it while we're here */ 2370 (void) memcpy(pLuDeviceFileName, 2371 optionList->optarg, 256); 2372 break; 2373 } 2374 } 2375 2376 if (B_TRUE == bCancelOverride) { 2377 /* if we have the cancel option, */ 2378 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) { 2379 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2380 (void) fprintf(stderr, 2381 getTextString( 2382 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON), 2383 getTextString(LU_NOT_FOUND)); 2384 (void) printf("\n"); 2385 return (ERROR_CLI_FAILED); 2386 } 2387 2388 /* cancel the override path for the specified LU */ 2389 mpstatus = MP_CancelOverridePath(luOid); 2390 if (MP_STATUS_SUCCESS != mpstatus) { 2391 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2392 (void) fprintf(stderr, 2393 getTextString( 2394 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON), 2395 getMpStatusStr(mpstatus)); 2396 (void) printf("\n"); 2397 return (mpstatus); 2398 } 2399 } else { 2400 /* must be wanting to override the path */ 2401 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) { 2402 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2403 (void) fprintf(stderr, 2404 getTextString( 2405 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2406 getTextString(LU_NOT_FOUND)); 2407 (void) printf("\n"); 2408 return (ERROR_CLI_FAILED); 2409 } 2410 2411 if (B_FALSE == getPathOid(options, &pathOid)) { 2412 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2413 (void) fprintf(stderr, 2414 getTextString( 2415 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2416 getTextString(FAILED_TO_FIND_PATH)); 2417 2418 (void) printf("\n"); 2419 return (ERROR_CLI_FAILED); 2420 } 2421 2422 /* attempt to set the override path */ 2423 mpstatus = MP_SetOverridePath(luOid, pathOid); 2424 if (mpstatus != MP_STATUS_SUCCESS) { 2425 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2426 (void) fprintf(stderr, 2427 getTextString( 2428 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2429 getMpStatusStr(mpstatus)); 2430 (void) printf("\n"); 2431 return (mpstatus); 2432 } 2433 } 2434 2435 return (mpstatus); 2436 } 2437 2438 2439 /* 2440 * **************************************************************************** 2441 * 2442 * getPathOid - 2443 * Search through all plugins and get the OID for specified path 2444 * 2445 * operand - pointer to operand list from user 2446 * options - pointer to option list from user 2447 * 2448 * **************************************************************************** 2449 */ 2450 boolean_t 2451 getPathOid(cmdOptions_t *options, MP_OID *pPathOid) 2452 { 2453 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2454 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 2455 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 2456 MP_INITIATOR_PORT_PROPERTIES initProps; 2457 MP_TARGET_PORT_PROPERTIES targProps; 2458 2459 MP_OID_LIST *pPluginOidList, 2460 *pLogicalUnitOidList, 2461 *pathOidListArray; 2462 2463 boolean_t bFoundIt = B_FALSE; 2464 MP_CHAR initPortID[256]; 2465 MP_CHAR targetPortID[256]; 2466 MP_CHAR luDeviceFileName[256]; 2467 boolean_t bHaveTarg = B_FALSE, 2468 bHaveLu = B_FALSE, 2469 bHaveInit = B_FALSE; 2470 2471 2472 cmdOptions_t *optionList = options; 2473 2474 int i, 2475 lu, 2476 pa; 2477 if (NULL == pPathOid) { 2478 return (B_FALSE); 2479 } 2480 2481 for (; optionList->optval; optionList++) { 2482 switch (optionList->optval) { 2483 case 'i': 2484 /* save init port name */ 2485 (void) memcpy(initPortID, 2486 optionList->optarg, 256); 2487 bHaveInit = B_TRUE; 2488 break; 2489 case 't': 2490 /* save target port id */ 2491 (void) memcpy(targetPortID, 2492 optionList->optarg, 256); 2493 bHaveTarg = B_TRUE; 2494 break; 2495 case 'l': 2496 /* save LU name */ 2497 (void) memcpy(luDeviceFileName, 2498 optionList->optarg, 256); 2499 bHaveLu = B_TRUE; 2500 break; 2501 } 2502 } 2503 2504 2505 if ((B_FALSE == bHaveInit) || 2506 (B_FALSE == bHaveTarg) || 2507 (B_FALSE == bHaveLu)) { 2508 /* if we don't have all three pieces, we can't find the path */ 2509 2510 return (B_FALSE); 2511 } 2512 2513 /* get the plugin ist */ 2514 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 2515 != MP_STATUS_SUCCESS) { 2516 (void) fprintf(stderr, "%s: %s\n", cmdName, 2517 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2518 return (B_FALSE); 2519 } 2520 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 2521 (void) fprintf(stderr, "%s: %s\n", cmdName, 2522 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2523 return (B_FALSE); 2524 } 2525 2526 for (i = 0; i < pPluginOidList->oidCount; i++) { 2527 2528 /* get Logical Unit list */ 2529 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i], 2530 &pLogicalUnitOidList); 2531 if (mpstatus != MP_STATUS_SUCCESS) { 2532 (void) fprintf(stderr, "%s: %s\n", 2533 cmdName, getTextString(ERR_NO_LU_LIST)); 2534 return (B_FALSE); 2535 } 2536 2537 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) && 2538 (B_FALSE == bFoundIt); lu++) { 2539 2540 /* get lu properties so we can check the name */ 2541 (void) memset(&luProps, 0, 2542 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 2543 mpstatus = 2544 MP_GetMPLogicalUnitProperties( 2545 pLogicalUnitOidList->oids[lu], &luProps); 2546 if (mpstatus != MP_STATUS_SUCCESS) { 2547 (void) fprintf(stderr, "%s: %s\n", 2548 cmdName, getTextString(ERR_NO_PROPERTIES)); 2549 return (B_FALSE); 2550 } 2551 if (0 == strcmp(luDeviceFileName, 2552 luProps.deviceFileName)) { 2553 /* get paths for this LU and search from here */ 2554 mpstatus = 2555 MP_GetAssociatedPathOidList( 2556 pLogicalUnitOidList->oids[lu], 2557 &pathOidListArray); 2558 if (mpstatus != MP_STATUS_SUCCESS) { 2559 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2560 (void) fprintf(stderr, 2561 getTextString( 2562 ERR_FAILED_TO_FIND_PATH)); 2563 (void) printf("\n"); 2564 return (B_FALSE); 2565 } 2566 2567 for (pa = 0; 2568 (pa < pathOidListArray->oidCount) && 2569 (B_FALSE == bFoundIt); pa++) { 2570 mpstatus = 2571 MP_GetPathLogicalUnitProperties 2572 (pathOidListArray->oids[pa], 2573 &pathProps); 2574 if (mpstatus != MP_STATUS_SUCCESS) { 2575 (void) fprintf(stderr, 2576 "%s: %s\n", cmdName, 2577 getTextString( 2578 ERR_NO_PROPERTIES)); 2579 return (B_FALSE); 2580 } 2581 2582 /* 2583 * get properties of iniator port and 2584 * target port to see if we have the 2585 * right path 2586 */ 2587 mpstatus = 2588 MP_GetInitiatorPortProperties( 2589 pathProps.initiatorPortOid, 2590 &initProps); 2591 2592 if (mpstatus != MP_STATUS_SUCCESS) { 2593 (void) fprintf(stderr, 2594 "%s: %s\n", cmdName, 2595 getTextString( 2596 ERR_NO_PROPERTIES)); 2597 return (B_FALSE); 2598 } 2599 if (0 == strcmp(initPortID, initProps.portID)) { 2600 /* lu and init port matches, check target port */ 2601 mpstatus = MP_GetTargetPortProperties(pathProps.targetPortOid, 2602 &targProps); 2603 if (mpstatus != MP_STATUS_SUCCESS) { 2604 (void) fprintf(stderr, "%s: %s\n", cmdName, 2605 getTextString(ERR_NO_PROPERTIES)); 2606 return (B_FALSE); 2607 } 2608 2609 if (0 == strcmp(targetPortID, targProps.portID)) { 2610 /* we found our path */ 2611 pPathOid->objectSequenceNumber = 2612 pathOidListArray->oids[pa].objectSequenceNumber; 2613 pPathOid->objectType = 2614 pathOidListArray->oids[pa].objectType; 2615 pPathOid->ownerId = pathOidListArray->oids[pa].ownerId; 2616 bFoundIt = B_TRUE; 2617 } 2618 } /* init port matched */ 2619 2620 } /* for each path associated with this lu */ 2621 2622 } /* lu matched */ 2623 2624 } /* for each lu */ 2625 2626 } /* for each plugin */ 2627 2628 return (bFoundIt); 2629 } 2630 2631 2632 /* 2633 * **************************************************************************** 2634 * 2635 * getLbValueFromString 2636 * Gets the MP_LOAD_BALANCE_TYPE specified load balance type string 2637 * 2638 * lbStr - load balance string defined in the .h file 2639 * This is what users will be required to feed into the 2640 * modify lu command. 2641 * 2642 * **************************************************************************** 2643 */ 2644 MP_LOAD_BALANCE_TYPE 2645 getLbValueFromString(char *lbStr) 2646 { 2647 MP_LOAD_BALANCE_TYPE lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN; 2648 2649 if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_ROUNDROBIN))) { 2650 lbVal = MP_LOAD_BALANCE_TYPE_ROUNDROBIN; 2651 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTBLOCKS))) { 2652 lbVal = MP_LOAD_BALANCE_TYPE_LEASTBLOCKS; 2653 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTIO))) { 2654 lbVal = MP_LOAD_BALANCE_TYPE_LEASTIO; 2655 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_DEVICEPROD))) { 2656 lbVal = MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT; 2657 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LBAREGION))) { 2658 lbVal = MP_LOAD_BALANCE_TYPE_LBA_REGION; 2659 } else if (0 == strcmp(lbStr, 2660 getTextString(TEXT_LBTYPE_FAILOVER_ONLY))) { 2661 lbVal = MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY; 2662 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_UNKNOWN))) { 2663 lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN; 2664 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_NONE))) { 2665 lbVal = 0; 2666 } else if (0 == strcmp(lbStr, 2667 getTextString(TEXT_LBTYPE_PROPRIETARY1))) { 2668 lbVal = ((MP_UINT32)0x00000001)<<16; 2669 } else if (0 == strcmp(lbStr, 2670 getTextString(TEXT_LBTYPE_PROPRIETARY2))) { 2671 lbVal = ((MP_UINT32)0x00000001)<<17; 2672 } else if (0 == strcmp(lbStr, 2673 getTextString(TEXT_LBTYPE_PROPRIETARY3))) { 2674 lbVal = ((MP_UINT32)0x00000001)<<18; 2675 } else if (0 == strcmp(lbStr, 2676 getTextString(TEXT_LBTYPE_PROPRIETARY4))) { 2677 lbVal = ((MP_UINT32)0x00000001)<<19; 2678 } else if (0 == strcmp(lbStr, 2679 getTextString(TEXT_LBTYPE_PROPRIETARY5))) { 2680 lbVal = ((MP_UINT32)0x00000001)<<20; 2681 } else if (0 == strcmp(lbStr, 2682 getTextString(TEXT_LBTYPE_PROPRIETARY6))) { 2683 lbVal = ((MP_UINT32)0x00000001)<<21; 2684 } else if (0 == strcmp(lbStr, 2685 getTextString(TEXT_LBTYPE_PROPRIETARY7))) { 2686 lbVal = ((MP_UINT32)0x00000001)<<22; 2687 } else if (0 == strcmp(lbStr, 2688 getTextString(TEXT_LBTYPE_PROPRIETARY8))) { 2689 lbVal = ((MP_UINT32)0x00000001)<<23; 2690 } else if (0 == strcmp(lbStr, 2691 getTextString(TEXT_LBTYPE_PROPRIETARY9))) { 2692 lbVal = ((MP_UINT32)0x00000001)<<24; 2693 } else if (0 == strcmp(lbStr, 2694 getTextString(TEXT_LBTYPE_PROPRIETARY10))) { 2695 lbVal = ((MP_UINT32)0x00000001)<<25; 2696 } else if (0 == strcmp(lbStr, 2697 getTextString(TEXT_LBTYPE_PROPRIETARY11))) { 2698 lbVal = ((MP_UINT32)0x00000001)<<26; 2699 } else if (0 == strcmp(lbStr, 2700 getTextString(TEXT_LBTYPE_PROPRIETARY12))) { 2701 lbVal = ((MP_UINT32)0x00000001)<<27; 2702 } else if (0 == strcmp(lbStr, 2703 getTextString(TEXT_LBTYPE_PROPRIETARY13))) { 2704 lbVal = ((MP_UINT32)0x00000001)<<28; 2705 } else if (0 == strcmp(lbStr, 2706 getTextString(TEXT_LBTYPE_PROPRIETARY14))) { 2707 lbVal = ((MP_UINT32)0x00000001)<<29; 2708 } else if (0 == strcmp(lbStr, 2709 getTextString(TEXT_LBTYPE_PROPRIETARY15))) { 2710 lbVal = ((MP_UINT32)0x00000001)<<30; 2711 } else if (0 == strcmp(lbStr, 2712 getTextString(TEXT_LBTYPE_PROPRIETARY16))) { 2713 lbVal = ((MP_UINT32)0x00000001)<<31; 2714 } 2715 2716 return (lbVal); 2717 2718 2719 } /* end getLbValueFromString */ 2720 2721 2722 /* 2723 * **************************************************************************** 2724 * 2725 * displayLogicalUnitNameTypeString 2726 * Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE 2727 * specified load balance type 2728 * 2729 * typeVal - load balance type defined in the MPAPI spec 2730 * 2731 * **************************************************************************** 2732 */ 2733 void 2734 displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal) 2735 { 2736 2737 char *typeString; 2738 2739 switch (typeVal) { 2740 2741 case MP_LU_NAME_TYPE_UNKNOWN: 2742 typeString = getTextString(TEXT_NAME_TYPE_UNKNOWN); 2743 break; 2744 case MP_LU_NAME_TYPE_VPD83_TYPE1: 2745 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE1); 2746 break; 2747 case MP_LU_NAME_TYPE_VPD83_TYPE2: 2748 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE2); 2749 break; 2750 case MP_LU_NAME_TYPE_VPD83_TYPE3: 2751 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE3); 2752 break; 2753 case MP_LU_NAME_TYPE_DEVICE_SPECIFIC: 2754 typeString = 2755 getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC); 2756 break; 2757 default: 2758 typeString = getTextString(TEXT_UNKNOWN); 2759 break; 2760 } 2761 2762 (void) printf("%s", typeString); 2763 2764 2765 } /* end displayLogicalUnitNameTypeString */ 2766 2767 /* 2768 * **************************************************************************** 2769 * 2770 * displayLoadBalanceString 2771 * Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE 2772 * specified load balance type 2773 * 2774 * lbVal - load balance type defined in the MPAPI spec 2775 * 2776 * **************************************************************************** 2777 */ 2778 void 2779 displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal) 2780 { 2781 2782 char *lbString; 2783 2784 switch (lbVal) { 2785 2786 case MP_LOAD_BALANCE_TYPE_UNKNOWN: 2787 lbString = getTextString(TEXT_LBTYPE_UNKNOWN); 2788 break; 2789 case MP_LOAD_BALANCE_TYPE_ROUNDROBIN: 2790 lbString = getTextString(TEXT_LBTYPE_ROUNDROBIN); 2791 break; 2792 case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS: 2793 lbString = getTextString(TEXT_LBTYPE_LEASTBLOCKS); 2794 break; 2795 case MP_LOAD_BALANCE_TYPE_LEASTIO: 2796 lbString = getTextString(TEXT_LBTYPE_LEASTIO); 2797 break; 2798 case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT: 2799 lbString = getTextString(TEXT_LBTYPE_DEVICEPROD); 2800 break; 2801 case MP_LOAD_BALANCE_TYPE_LBA_REGION: 2802 lbString = getTextString(TEXT_LBTYPE_LBAREGION); 2803 break; 2804 case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY: 2805 lbString = getTextString(TEXT_LBTYPE_FAILOVER_ONLY); 2806 break; 2807 case (((MP_UINT32)0x00000001)<<16): 2808 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY1); 2809 break; 2810 case (((MP_UINT32)0x00000001)<<17): 2811 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY2); 2812 break; 2813 case (((MP_UINT32)0x00000001)<<18): 2814 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY3); 2815 break; 2816 case (((MP_UINT32)0x00000001)<<19): 2817 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY4); 2818 break; 2819 case (((MP_UINT32)0x00000001)<<20): 2820 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY5); 2821 break; 2822 case (((MP_UINT32)0x00000001)<<21): 2823 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY6); 2824 break; 2825 case (((MP_UINT32)0x00000001)<<22): 2826 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY7); 2827 break; 2828 case (((MP_UINT32)0x00000001)<<23): 2829 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY8); 2830 break; 2831 case (((MP_UINT32)0x00000001)<<24): 2832 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY9); 2833 break; 2834 case (((MP_UINT32)0x00000001)<<25): 2835 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY10); 2836 break; 2837 case (((MP_UINT32)0x00000001)<<26): 2838 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY11); 2839 break; 2840 case (((MP_UINT32)0x00000001)<<27): 2841 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY12); 2842 break; 2843 case (((MP_UINT32)0x00000001)<<28): 2844 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY13); 2845 break; 2846 case (((MP_UINT32)0x00000001)<<29): 2847 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY14); 2848 break; 2849 case (((MP_UINT32)0x00000001)<<30): 2850 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY15); 2851 break; 2852 case (((MP_UINT32)0x00000001)<<31): 2853 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY16); 2854 break; 2855 default: 2856 lbString = getTextString(TEXT_UNKNOWN); 2857 break; 2858 } 2859 2860 (void) printf("%s", lbString); 2861 2862 2863 } /* end displayLoadBalanceString */ 2864 2865 /* 2866 * **************************************************************************** 2867 * 2868 * displayTransportTypeString 2869 * Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE 2870 * specified load balance type 2871 * 2872 * transportTypeVal - transport type defined in the MPAPI spec 2873 * 2874 * **************************************************************************** 2875 */ 2876 void 2877 displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal) 2878 { 2879 2880 char *ttypeString; 2881 switch (transportTypeVal) { 2882 2883 case MP_PORT_TRANSPORT_TYPE_MPNODE: 2884 ttypeString = 2885 getTextString(TEXT_TRANS_PORT_TYPE_MPNODE); 2886 break; 2887 case MP_PORT_TRANSPORT_TYPE_FC: 2888 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_FC); 2889 break; 2890 case MP_PORT_TRANSPORT_TYPE_SPI: 2891 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_SPI); 2892 break; 2893 case MP_PORT_TRANSPORT_TYPE_ISCSI: 2894 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_ISCSI); 2895 break; 2896 case MP_PORT_TRANSPORT_TYPE_IFB: 2897 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_IFB); 2898 break; 2899 default: 2900 ttypeString = getTextString(TEXT_UNKNOWN); 2901 break; 2902 } 2903 2904 (void) printf("%s", ttypeString); 2905 2906 } /* end displayTransportTypeString */ 2907 2908 2909 /* 2910 * **************************************************************************** 2911 * 2912 * getMpStatusStr 2913 * Gets the string description for the specified load balance type value 2914 * 2915 * mpstatus - MP_STATUS value 2916 * 2917 * **************************************************************************** 2918 */ 2919 char * 2920 getMpStatusStr(MP_STATUS mpstatus) 2921 { 2922 char *statString; 2923 2924 switch (mpstatus) { 2925 case MP_STATUS_SUCCESS: 2926 statString = getTextString(TEXT_MPSTATUS_SUCCESS); 2927 break; 2928 case MP_STATUS_INVALID_PARAMETER: 2929 statString = getTextString(TEXT_MPSTATUS_INV_PARAMETER); 2930 break; 2931 case MP_STATUS_UNKNOWN_FN: 2932 statString = getTextString(TEXT_MPSTATUS_UNKNOWN_FN); 2933 break; 2934 case MP_STATUS_FAILED: 2935 statString = getTextString(TEXT_MPSTATUS_FAILED); 2936 break; 2937 case MP_STATUS_INSUFFICIENT_MEMORY: 2938 statString = getTextString(TEXT_MPSTATUS_INSUFF_MEMORY); 2939 break; 2940 case MP_STATUS_INVALID_OBJECT_TYPE: 2941 statString = getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE); 2942 break; 2943 case MP_STATUS_UNSUPPORTED: 2944 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED); 2945 break; 2946 case MP_STATUS_OBJECT_NOT_FOUND: 2947 statString = getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND); 2948 break; 2949 case MP_STATUS_ACCESS_STATE_INVALID: 2950 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED); 2951 break; 2952 case MP_STATUS_FN_REPLACED: 2953 statString = getTextString(TEXT_MPSTATUS_FN_REPLACED); 2954 break; 2955 case MP_STATUS_PATH_NONOPERATIONAL: 2956 statString = getTextString(TEXT_MPSTATUS_PATH_NONOP); 2957 break; 2958 case MP_STATUS_TRY_AGAIN: 2959 statString = getTextString(TEXT_MPSTATUS_TRY_AGAIN); 2960 break; 2961 case MP_STATUS_NOT_PERMITTED: 2962 statString = getTextString(TEXT_MPSTATUS_NOT_PERMITTED); 2963 break; 2964 default: 2965 statString = getTextString(TEXT_UNKNOWN); 2966 break; 2967 } 2968 2969 return (statString); 2970 } /* end getMpStatusStr */ 2971 2972 2973 /* 2974 * **************************************************************************** 2975 * 2976 * GetPathStateStr 2977 * Gets the string description for the specified path state type value 2978 * 2979 * pathState - MP_PATH_STATE values 2980 * 2981 * **************************************************************************** 2982 */ 2983 char * 2984 getPathStateStr(MP_PATH_STATE pathState) 2985 { 2986 char *pathString; 2987 2988 switch (pathState) { 2989 case MP_PATH_STATE_OKAY: 2990 pathString = getTextString(TEXT_PATH_STATE_OKAY); 2991 break; 2992 case MP_PATH_STATE_PATH_ERR: 2993 pathString = getTextString(TEXT_PATH_STATE_PATH_ERR); 2994 break; 2995 case MP_PATH_STATE_LU_ERR: 2996 pathString = getTextString(TEXT_PATH_STATE_LU_ERR); 2997 break; 2998 case MP_PATH_STATE_RESERVED: 2999 pathString = getTextString(TEXT_PATH_STATE_RESERVED); 3000 break; 3001 case MP_PATH_STATE_REMOVED: 3002 pathString = getTextString(TEXT_PATH_STATE_REMOVED); 3003 break; 3004 case MP_PATH_STATE_TRANSITIONING: 3005 pathString = 3006 getTextString(TEXT_PATH_STATE_TRANSITIONING); 3007 break; 3008 case MP_PATH_STATE_OPERATIONAL_CLOSED: 3009 pathString = 3010 getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED); 3011 break; 3012 case MP_PATH_STATE_INVALID_CLOSED: 3013 pathString = 3014 getTextString(TEXT_PATH_STATE_INVALID_CLOSED); 3015 break; 3016 case MP_PATH_STATE_OFFLINE_CLOSED: 3017 pathString = 3018 getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED); 3019 break; 3020 default: 3021 pathString = getTextString(TEXT_UNKNOWN); 3022 break; 3023 } 3024 3025 return (pathString); 3026 } /* end getPathStateStr */ 3027 3028 3029 3030 /* 3031 * **************************************************************************** 3032 * 3033 * getAccessStateStr 3034 * Gets the string description for the specified access state type value 3035 * 3036 * accessState - MP_ACCESS_STATE_TYPE values 3037 * 3038 * **************************************************************************** 3039 */ 3040 char * 3041 getAccessStateStr(MP_ACCESS_STATE_TYPE accessState) 3042 { 3043 char *accessString; 3044 3045 switch (accessState) { 3046 case MP_ACCESS_STATE_ACTIVE_OPTIMIZED: 3047 accessString = 3048 getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED); 3049 break; 3050 case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED: 3051 accessString = 3052 getTextString( 3053 TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED); 3054 break; 3055 case MP_ACCESS_STATE_STANDBY: 3056 accessString = 3057 getTextString(TEXT_ACCESS_STATE_STANDBY); 3058 break; 3059 case MP_ACCESS_STATE_UNAVAILABLE: 3060 accessString = 3061 getTextString(TEXT_ACCESS_STATE_UNAVAILABLE); 3062 break; 3063 case MP_ACCESS_STATE_TRANSITIONING: 3064 accessString = 3065 getTextString(TEXT_ACCESS_STATE_TRANSITIONING); 3066 break; 3067 case MP_ACCESS_STATE_ACTIVE: 3068 accessString = getTextString(TEXT_ACCESS_STATE_ACTIVE); 3069 break; 3070 default: 3071 accessString = getTextString(TEXT_UNKNOWN); 3072 break; 3073 } 3074 return (accessString); 3075 } /* end getAccessStateStr */ 3076 3077 3078 /* 3079 * **************************************************************************** 3080 * 3081 * displayArray 3082 * Print out the specified array. 3083 * 3084 * arrayToDisplay - array to display 3085 * arraySize - size of array to display 3086 * 3087 * **************************************************************************** 3088 */ 3089 void 3090 displayArray(MP_CHAR *arrayToDisplay, int arraySize) 3091 { 3092 int i; 3093 3094 for (i = 0; i < arraySize; i++) { 3095 if ('\0' != arrayToDisplay[i]) { 3096 (void) fprintf(stdout, "%c", arrayToDisplay[i]); 3097 } 3098 } 3099 3100 } 3101 3102 3103 /* 3104 * **************************************************************************** 3105 * 3106 * getStringArray 3107 * Return a null terminated array for the specified array as a string, 3108 * This is used for inputting into the %s in formatted strings. 3109 * 3110 * arrayToDisplay - array to display 3111 * arraySize - size of array to display 3112 * 3113 * **************************************************************************** 3114 */ 3115 MP_CHAR * 3116 getStringArray(MP_CHAR *arrayToDisplay, int arraySize) 3117 { 3118 MP_CHAR *newStr; 3119 3120 int i; 3121 3122 newStr = malloc(((sizeof (MP_CHAR)) * arraySize) + 1); 3123 if (NULL == newStr) { 3124 (void) fprintf(stdout, "%s\n", 3125 getTextString(ERR_MEMORY_ALLOCATION)); 3126 } else { 3127 3128 for (i = 0; i < arraySize; i++) { 3129 newStr[i] = arrayToDisplay[i]; 3130 } 3131 newStr[arraySize] = '\0'; 3132 } 3133 3134 return (newStr); 3135 } 3136 3137 3138 /* 3139 * **************************************************************************** 3140 * 3141 * displayWideArray 3142 * Print out the specified wide character array as a string, 3143 * adding the null termination 3144 * 3145 * arrayToDisplay - array to display 3146 * arraySize - size of array to display 3147 * 3148 * **************************************************************************** 3149 */ 3150 void 3151 displayWideArray(MP_WCHAR *arrayToDisplay, int arraySize) 3152 { 3153 int i; 3154 int numChars = arraySize/4; 3155 3156 for (i = 0; i < numChars; i++) { 3157 if (L'\0' != arrayToDisplay[i]) { 3158 (void) fprintf(stdout, "%wc", arrayToDisplay[i]); 3159 } 3160 } 3161 } 3162 3163 3164 /* 3165 * **************************************************************************** 3166 * 3167 * listfunc 3168 * Used by cmdparse for list clis 3169 * 3170 * **************************************************************************** 3171 */ 3172 /*ARGSUSED*/ 3173 static int 3174 listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3175 void *addArgs) 3176 { 3177 int ret = 0; 3178 3179 switch (object) { 3180 case MPATH_SUPPORT: 3181 ret = listMpathSupport(operandLen, operand); 3182 break; 3183 case LOGICAL_UNIT: 3184 ret = listLogicalUnit(operandLen, operand, options); 3185 break; 3186 case INITIATOR_PORT: 3187 ret = listInitiatorPort(operandLen, operand); 3188 break; 3189 default: 3190 (void) fprintf(stderr, "%s: %s\n", 3191 cmdName, getTextString(TEXT_UNKNOWN_OBJECT)); 3192 ret = 1; 3193 break; 3194 } 3195 3196 return (ret); 3197 } 3198 3199 3200 /* 3201 * **************************************************************************** 3202 * 3203 * showFunc 3204 * used bycmdparse for show clis 3205 * 3206 * **************************************************************************** 3207 */ 3208 /*ARGSUSED*/ 3209 static int 3210 showFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3211 void *addArgs) 3212 { 3213 int ret = 0; 3214 3215 switch (object) { 3216 case MPATH_SUPPORT: 3217 ret = showMpathSupport(operandLen, operand); 3218 break; 3219 case LOGICAL_UNIT: 3220 ret = showLogicalUnit(operandLen, operand); 3221 break; 3222 case INITIATOR_PORT: 3223 ret = showInitiatorPort(operandLen, operand); 3224 break; 3225 default: 3226 ret = 1; 3227 break; 3228 } 3229 3230 return (ret); 3231 } 3232 3233 3234 /* 3235 * **************************************************************************** 3236 * 3237 * modifyFunc 3238 * Used by cmdparse for midify clis 3239 * 3240 * 3241 * **************************************************************************** 3242 */ 3243 /*ARGSUSED*/ 3244 static int 3245 modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3246 void *addArgs) 3247 { 3248 int ret = 0; 3249 3250 switch (object) { 3251 case MPATH_SUPPORT: 3252 ret = modifyMpathSupport(operandLen, operand, options); 3253 break; 3254 case LOGICAL_UNIT: 3255 ret = modifyLogicalUnit(operandLen, operand, options); 3256 break; 3257 default: 3258 ret = 1; 3259 break; 3260 } 3261 3262 3263 return (ret); 3264 } 3265 3266 3267 /* 3268 * **************************************************************************** 3269 * 3270 * enableFunc 3271 * Used by cmdpars for enable clis 3272 * 3273 * **************************************************************************** 3274 */ 3275 /*ARGSUSED*/ 3276 static int 3277 enableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3278 void *addArgs) 3279 { 3280 int ret = 0; 3281 3282 switch (object) { 3283 case PATH: 3284 ret = enablePath(options); 3285 break; 3286 default: 3287 ret = 1; 3288 break; 3289 } 3290 3291 return (ret); 3292 } 3293 3294 3295 /* 3296 * **************************************************************************** 3297 * 3298 * disableFunc 3299 * Used by cmdpars for disable clis 3300 * 3301 * **************************************************************************** 3302 */ 3303 /*ARGSUSED*/ 3304 static int 3305 disableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3306 void *addArgs) 3307 { 3308 int ret = 0; 3309 3310 switch (object) { 3311 case PATH: 3312 ret = disablePath(options); 3313 break; 3314 default: 3315 ret = 1; 3316 break; 3317 } 3318 3319 return (ret); 3320 } 3321 3322 3323 /* 3324 * **************************************************************************** 3325 * 3326 * failoverFunc 3327 * Used by cmdpars for failover clis 3328 * 3329 * **************************************************************************** 3330 */ 3331 /*ARGSUSED*/ 3332 static int 3333 failoverFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3334 void *addArgs) 3335 { 3336 int ret = 0; 3337 3338 switch (object) { 3339 case LOGICAL_UNIT: 3340 ret = failoverLogicalUnit(operand); 3341 break; 3342 default: 3343 ret = 1; 3344 break; 3345 } 3346 3347 return (ret); 3348 } 3349 3350 3351 /* 3352 * **************************************************************************** 3353 * 3354 * overrideFunc 3355 * Used by cmdpars for override clis 3356 * 3357 * **************************************************************************** 3358 */ 3359 /*ARGSUSED*/ 3360 static int 3361 overrideFunc(int operandLen, char *operand[], 3362 int object, cmdOptions_t *options, 3363 void *addArgs) 3364 { 3365 int ret = 0; 3366 3367 switch (object) { 3368 case PATH: 3369 ret = overridePath(options); 3370 break; 3371 default: 3372 ret = 1; 3373 break; 3374 } 3375 3376 3377 return (ret); 3378 } 3379 3380 3381 /* 3382 * ************************************************************************* 3383 * 3384 * main 3385 * 3386 * ************************************************************************* 3387 */ 3388 int 3389 main(int argc, char *argv[]) 3390 { 3391 synTables_t synTables; 3392 char versionString[VERSION_STRING_MAX_LEN]; 3393 int ret; 3394 int funcRet; 3395 void *subcommandArgs = NULL; 3396 3397 /* set global command name */ 3398 cmdName = getExecBasename(argv[0]); 3399 3400 (void) sprintf(versionString, "%2s.%2s", 3401 VERSION_STRING_MAJOR, VERSION_STRING_MINOR); 3402 synTables.versionString = versionString; 3403 synTables.longOptionTbl = &longOptions[0]; 3404 synTables.subcommandTbl = &subcommands[0]; 3405 synTables.objectTbl = &objects[0]; 3406 synTables.objectRulesTbl = &objectRules[0]; 3407 synTables.optionRulesTbl = &optionRules[0]; 3408 3409 ret = cmdParse(argc, argv, /* SUB_COMMAND_ISSUED, */ synTables, 3410 subcommandArgs, &funcRet); 3411 if (ret == 1) { 3412 (void) fprintf(stdout, "%s %s(1M)\n", 3413 getTextString(TEXT_MORE_INFO), cmdName); 3414 return (ERROR_CLI_FAILED); 3415 } else if (ret == -1) { 3416 perror(argv[0]); 3417 return (1); 3418 } 3419 3420 if (funcRet != 0) { 3421 (void) fprintf(stderr, "%s: %s\n", 3422 argv[0], getTextString(TEXT_UNABLE_TO_COMPLETE)); 3423 return (1); 3424 } 3425 return (0); 3426 3427 } /* end main */ 3428