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 fd1 = fd2 = -1; 1102 if (((fd1 = open(cmpString, O_RDONLY|O_NDELAY)) >= 0) && 1103 ((fd2 = open(deviceProperty, O_RDONLY|O_NDELAY)) >= 0) && 1104 (devid_get(fd1, &devid1) == 0) && 1105 (devid_get(fd2, &devid2) == 0) && 1106 ((NULL != devid1) && (NULL != devid2))) { 1107 if (0 == 1108 (devid_compare(devid1, devid2))) { 1109 isSame = B_TRUE; 1110 } 1111 } 1112 1113 if (NULL != devid1) { 1114 devid_free(devid1); 1115 } 1116 if (NULL != devid2) { 1117 devid_free(devid2); 1118 } 1119 1120 if (fd1 >= 0) { 1121 (void) close(fd1); 1122 } 1123 if (fd2 >= 0) { 1124 (void) close(fd2); 1125 } 1126 } /* compare */ 1127 1128 return (isSame); 1129 } 1130 1131 1132 /* 1133 * **************************************************************************** 1134 * 1135 * listIndivudualLogicalUnit - 1136 * Used by list logical unit cli. 1137 * Displays info about an LU 1138 * 1139 * luOid - LU to list 1140 * luProps - properties of he LU to list 1141 * 1142 * **************************************************************************** 1143 */ 1144 int 1145 listIndividualLogicalUnit(MP_OID luOid, 1146 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps) 1147 { 1148 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 1149 MP_OID_LIST *pPathOidListArray; 1150 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1151 int numOperationalPaths, 1152 pa; 1153 1154 (void) printf("\t"); 1155 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName)); 1156 (void) printf("\n"); 1157 1158 mpstatus = MP_GetAssociatedPathOidList(luOid, 1159 &pPathOidListArray); 1160 if (mpstatus != MP_STATUS_SUCCESS) { 1161 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1162 (void) fprintf(stderr, 1163 getTextString(ERR_NO_LU_PATH_INFO_WITH_MISSING_LU_STR), 1164 getStringArray(luProps.deviceFileName, 1165 sizeof (luProps.deviceFileName))); 1166 (void) fprintf(stderr, "\n"); 1167 return (mpstatus); 1168 } 1169 (void) printf("\t\t%s %d\n", 1170 getTextString(TEXT_LB_PATH_COUNT), pPathOidListArray->oidCount); 1171 1172 numOperationalPaths = 0; 1173 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) { 1174 (void) memset(&pathProps, 0, 1175 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES)); 1176 mpstatus = 1177 MP_GetPathLogicalUnitProperties( 1178 pPathOidListArray->oids[pa], &pathProps); 1179 if (mpstatus != MP_STATUS_SUCCESS) { 1180 (void) fprintf(stderr, "%s: %s\n", 1181 cmdName, getTextString(ERR_NO_PROPERTIES)); 1182 return (mpstatus); 1183 } 1184 1185 /* cycle through and check status of each for */ 1186 /* operation path count */ 1187 if (MP_PATH_STATE_OKAY == pathProps.pathState) { 1188 numOperationalPaths++; 1189 } 1190 } 1191 1192 (void) printf("\t\t%s %d\n", 1193 getTextString(TEXT_LB_OP_PATH_COUNT), numOperationalPaths); 1194 1195 return (mpstatus); 1196 } 1197 1198 1199 /* 1200 * **************************************************************************** 1201 * 1202 * showLogicalUnit - 1203 * mpathadm show {logical-unit | LU} <logical-unit name>, ... 1204 * 1205 * operandLen - number of operands user passed into the cli 1206 * operand - pointer to operand list from user 1207 * 1208 * **************************************************************************** 1209 */ 1210 int 1211 showLogicalUnit(int operandLen, char *operand[]) 1212 { 1213 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1214 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1215 MP_PLUGIN_PROPERTIES pluginProps; 1216 MP_OID luOid, 1217 pluginOid; 1218 1219 int op; 1220 1221 for (op = 0; op < operandLen; op++) { 1222 if (op > 0) { 1223 (void) printf("\n"); 1224 } 1225 if (B_TRUE == getLogicalUnitOid(operand[op], &luOid)) { 1226 (void) memset(&luProps, 0, 1227 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1228 mpstatus = 1229 MP_GetMPLogicalUnitProperties( 1230 luOid, &luProps); 1231 if (mpstatus != MP_STATUS_SUCCESS) { 1232 (void) fprintf(stderr, "%s: %s\n", 1233 cmdName, getTextString(ERR_NO_PROPERTIES)); 1234 return (mpstatus); 1235 } 1236 1237 mpstatus = 1238 MP_GetAssociatedPluginOid(luOid, &pluginOid); 1239 if (mpstatus != MP_STATUS_SUCCESS) { 1240 (void) fprintf(stderr, "%s: %s\n", 1241 cmdName, 1242 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1243 return (mpstatus); 1244 } 1245 1246 mpstatus = 1247 MP_GetPluginProperties(pluginOid, &pluginProps); 1248 if (mpstatus != MP_STATUS_SUCCESS) { 1249 (void) fprintf(stderr, "%s: %s\n", 1250 cmdName, getTextString(ERR_NO_PROPERTIES)); 1251 return (mpstatus); 1252 } 1253 1254 if (showIndividualLogicalUnit(luOid, luProps, 1255 pluginProps) != 0) { 1256 return (ERROR_CLI_FAILED); 1257 } 1258 1259 } else { 1260 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1261 (void) fprintf(stderr, getTextString( 1262 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1263 operand[op]); 1264 (void) printf("\n"); 1265 } 1266 1267 } /* for each operand */ 1268 1269 return (mpstatus); 1270 } 1271 1272 1273 /* 1274 * **************************************************************************** 1275 * 1276 * showIndivudualLogicalUnit - 1277 * Used by show logical unit cli. 1278 * Displays info about an LU 1279 * 1280 * luOid - LU to show 1281 * luProps - properties of he LU to show 1282 * pluginProps - propertis of the plugin this LU belongs to 1283 * 1284 * **************************************************************************** 1285 */ 1286 int 1287 showIndividualLogicalUnit(MP_OID luOid, 1288 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps, 1289 MP_PLUGIN_PROPERTIES pluginProps) 1290 { 1291 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 1292 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps; 1293 MP_TARGET_PORT_PROPERTIES tportProps; 1294 MP_INITIATOR_PORT_PROPERTIES initProps; 1295 MP_OID_LIST *pPathOidListArray, 1296 *pTPGOidListArray, 1297 *pTportOidListArray; 1298 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1299 boolean_t showTportLabel = B_TRUE; 1300 1301 int pa, 1302 tpg, 1303 tport; 1304 1305 (void) printf("%s ", getTextString(TEXT_LB_LOGICAL_UNIT)); 1306 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName)); 1307 (void) printf("\n"); 1308 (void) printf("\t%s %s\n", getTextString(TEXT_LB_MPATH_SUPPORT), 1309 pluginProps.fileName); 1310 1311 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR)); 1312 displayArray(luProps.vendor, 1313 sizeof (luProps.vendor)); 1314 (void) printf("\n\t%s ", getTextString(TEXT_LB_PRODUCT)); 1315 displayArray(luProps.product, 1316 sizeof (luProps.product)); 1317 (void) printf("\n\t%s ", getTextString(TEXT_LB_REVISION)); 1318 displayArray(luProps.revision, 1319 sizeof (luProps.revision)); 1320 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME_TYPE)); 1321 displayLogicalUnitNameTypeString(luProps.nameType); 1322 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME)); 1323 displayArray(luProps.name, sizeof (luProps.name)); 1324 (void) printf("\n\t%s %s\n", getTextString(TEXT_LB_ASYMMETRIC), 1325 (MP_TRUE == luProps.asymmetric)? 1326 getTextString(TEXT_YES):getTextString(TEXT_NO)); 1327 1328 (void) printf("\t%s ", getTextString(TEXT_LB_CURR_LOAD_BALANCE)); 1329 /* don't ignore load balance type none. */ 1330 if (luProps.currentLoadBalanceType == 0) { 1331 (void) printf("%s", getTextString(TEXT_LBTYPE_NONE)); 1332 } else { 1333 displayLoadBalanceString(luProps.currentLoadBalanceType); 1334 } 1335 (void) printf("\n"); 1336 1337 (void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID)); 1338 if (0xffffffff == luProps.logicalUnitGroupID) { 1339 (void) printf("%s\n", getTextString(TEXT_NA)); 1340 } else { 1341 (void) printf("0x%x\n", luProps.logicalUnitGroupID); 1342 } 1343 1344 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB)); 1345 if (MP_FALSE == pluginProps.autoFailbackSupport) { 1346 (void) printf("%s\n", getTextString(TEXT_NA)); 1347 } else { 1348 (void) printf("%s\n", (MP_TRUE == luProps.autoFailbackEnabled)? 1349 getTextString(TEXT_ON):getTextString(TEXT_OFF)); 1350 } 1351 1352 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB)); 1353 if (MP_FALSE == pluginProps.autoProbingSupport) { 1354 (void) printf("%s\n", getTextString(TEXT_NA)); 1355 } else { 1356 (void) printf("%s\n", (MP_TRUE == luProps.autoProbingEnabled)? 1357 getTextString(TEXT_ON):getTextString(TEXT_OFF)); 1358 } 1359 1360 1361 /* get path info */ 1362 mpstatus = MP_GetAssociatedPathOidList(luOid, &pPathOidListArray); 1363 if (mpstatus != MP_STATUS_SUCCESS) { 1364 (void) fprintf(stderr, "%s: %s", cmdName, 1365 getTextString(ERR_NO_LU_PATH_INFO)); 1366 displayArray(luProps.deviceFileName, 1367 sizeof (luProps.deviceFileName)); 1368 (void) fprintf(stderr, "\n"); 1369 return (mpstatus); 1370 } 1371 1372 (void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO)); 1373 1374 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) { 1375 (void) memset(&pathProps, 0, 1376 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES)); 1377 mpstatus = MP_GetPathLogicalUnitProperties( 1378 pPathOidListArray->oids[pa], &pathProps); 1379 if (mpstatus != MP_STATUS_SUCCESS) { 1380 (void) fprintf(stderr, "%s: %s\n", 1381 cmdName, getTextString(ERR_NO_PROPERTIES)); 1382 return (mpstatus); 1383 } 1384 1385 (void) printf("\t\t%s ", 1386 getTextString(TEXT_LB_INIT_PORT_NAME)); 1387 if ((mpstatus = 1388 MP_GetInitiatorPortProperties(pathProps.initiatorPortOid, 1389 &initProps)) != MP_STATUS_SUCCESS) { 1390 (void) printf("%s\n", getTextString(TEXT_UNKNOWN)); 1391 } else { 1392 displayArray(initProps.portID, 1393 sizeof (initProps.portID)); 1394 (void) printf("\n"); 1395 } 1396 1397 (void) printf("\t\t%s ", 1398 getTextString(TEXT_LB_TARGET_PORT_NAME)); 1399 if ((mpstatus = 1400 MP_GetTargetPortProperties(pathProps.targetPortOid, 1401 &tportProps)) != MP_STATUS_SUCCESS) { 1402 (void) printf("%s\n", getTextString(TEXT_UNKNOWN)); 1403 } else { 1404 displayArray(tportProps.portID, 1405 sizeof (tportProps.portID)); 1406 (void) printf("\n"); 1407 } 1408 1409 (void) printf("\t\t%s ", getTextString(TEXT_LB_OVERRIDE_PATH)); 1410 if (MP_FALSE == pluginProps.canOverridePaths) { 1411 (void) printf("%s\n", getTextString(TEXT_NA)); 1412 } else if (luProps.overridePath.objectSequenceNumber == 1413 pPathOidListArray->oids[pa].objectSequenceNumber) { 1414 (void) printf("%s\n", getTextString(TEXT_YES)); 1415 } else { 1416 (void) printf("%s\n", getTextString(TEXT_NO)); 1417 } 1418 1419 (void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE), 1420 getPathStateStr(pathProps.pathState)); 1421 1422 (void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED), 1423 pathProps.disabled?getTextString(TEXT_YES): 1424 getTextString(TEXT_NO)); 1425 1426 } 1427 1428 /* get tpg info */ 1429 mpstatus = MP_GetAssociatedTPGOidList(luOid, &pTPGOidListArray); 1430 if (mpstatus != MP_STATUS_SUCCESS) { 1431 (void) fprintf(stderr, "%s: %s", cmdName, 1432 getTextString(ERR_NO_ASSOC_TPGS)); 1433 } else { 1434 1435 /* display tpg info only if is assymetric */ 1436 if (MP_TRUE == luProps.asymmetric) { 1437 (void) printf("\t%s \n", getTextString(TEXT_LB_TPG_INFO)); 1438 } 1439 1440 for (tpg = 0; tpg < pTPGOidListArray->oidCount; tpg++) { 1441 (void) memset(&tpgProps, 0, 1442 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES)); 1443 mpstatus = MP_GetTargetPortGroupProperties( 1444 pTPGOidListArray->oids[tpg], &tpgProps); 1445 if (mpstatus != MP_STATUS_SUCCESS) { 1446 (void) fprintf(stderr, "%s: %s", 1447 cmdName, getTextString(ERR_NO_PROPERTIES)); 1448 } else { 1449 /* display tpg info only if is assymetric */ 1450 if (tpg > 0) { 1451 (void) printf("\n"); 1452 } 1453 if (MP_TRUE == luProps.asymmetric) { 1454 (void) printf("\t\t%s %d\n", 1455 getTextString(TEXT_LB_ID), 1456 tpgProps.tpgID); 1457 (void) printf("\t\t%s %s\n", 1458 getTextString( 1459 TEXT_LB_EXPLICIT_FAILOVER), 1460 (MP_TRUE == 1461 tpgProps.explicitFailover)? 1462 getTextString(TEXT_YES): 1463 getTextString(TEXT_NO)); 1464 (void) printf("\t\t%s %s\n", 1465 getTextString( 1466 TEXT_LB_ACCESS_STATE), 1467 getAccessStateStr( 1468 tpgProps.accessState)); 1469 /* display label for each tpg. */ 1470 (void) printf("\t\t%s\n", 1471 getTextString(TEXT_TPORT_LIST)); 1472 } else { 1473 /* display label once for symmetric. */ 1474 if (B_TRUE == showTportLabel) { 1475 (void) printf("\t%s\n", 1476 getTextString(TEXT_TPORT_LIST)); 1477 showTportLabel = B_FALSE; 1478 } 1479 } 1480 1481 /* get target port info */ 1482 mpstatus = MP_GetTargetPortOidList( 1483 pTPGOidListArray->oids[tpg], 1484 &pTportOidListArray); 1485 if (mpstatus != MP_STATUS_SUCCESS) { 1486 (void) fprintf(stderr, "%s: %s", 1487 cmdName, 1488 getTextString(ERR_NO_ASSOC_TPORTS)); 1489 } else { 1490 1491 /* begin back-up indentation */ 1492 for (tport = 0; tport < pTportOidListArray->oidCount; tport++) { 1493 (void) memset(&tportProps, 0, 1494 sizeof (MP_TARGET_PORT_PROPERTIES)); 1495 if ((mpstatus = 1496 MP_GetTargetPortProperties(pTportOidListArray->oids[tport], 1497 &tportProps)) != MP_STATUS_SUCCESS) { 1498 (void) fprintf(stderr, "%s: %s", 1499 cmdName, getTextString(ERR_NO_PROPERTIES)); 1500 } else { 1501 if (MP_TRUE == luProps.asymmetric) { 1502 (void) printf("\t\t\t%s ", 1503 getTextString(TEXT_LB_NAME)); 1504 displayArray(tportProps.portID, 1505 sizeof (tportProps.portID)); 1506 (void) printf("\n\t\t\t%s %d\n", 1507 getTextString(TEXT_LB_RELATIVE_ID), 1508 tportProps.relativePortID); 1509 } else { 1510 (void) printf("\t\t%s ", 1511 getTextString(TEXT_LB_NAME)); 1512 displayArray(tportProps.portID, 1513 sizeof (tportProps.portID)); 1514 (void) printf("\n\t\t%s %d\n", 1515 getTextString(TEXT_LB_RELATIVE_ID), 1516 tportProps.relativePortID); 1517 } 1518 /* insert blank line if not the last target port. */ 1519 if (!(tport == (pTportOidListArray->oidCount - 1))) { 1520 (void) printf("\n"); 1521 } 1522 } 1523 } /* for each target port */ 1524 /* end back-up indentation */ 1525 1526 } /* else got target port props */ 1527 } /* else got TPG props */ 1528 } /* for each TPG */ 1529 } /* else got tpg list */ 1530 1531 1532 return (mpstatus); 1533 } 1534 1535 1536 /* 1537 * **************************************************************************** 1538 * 1539 * modifyLogicalUnit - 1540 * mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ... 1541 * 1542 * operandLen - number of operands user passed into the cli 1543 * operand - pointer to operand list from user 1544 * options - pointer to option list from user 1545 * 1546 * **************************************************************************** 1547 */ 1548 int 1549 modifyLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options) 1550 { 1551 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1552 MP_OID luOid; 1553 cmdOptions_t *optionList = options; 1554 char *cmdStr = 1555 getTextString( 1556 TEXT_UNKNOWN); 1557 int op; 1558 1559 for (op = 0; op < operandLen; op++) { 1560 if (B_TRUE != getLogicalUnitOid(operand[op], &luOid)) { 1561 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1562 (void) fprintf(stderr, 1563 getTextString(ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1564 operand[op]); 1565 (void) printf("\n"); 1566 return (ERROR_CLI_FAILED); 1567 } 1568 1569 /* we found the lu oid, now change the options requested */ 1570 switch (optionList->optval) { 1571 case 'a': 1572 /* modify autofailback */ 1573 cmdStr = getTextString(TEXT_AUTO_FAILBACK); 1574 if (0 == strcasecmp(optionList->optarg, 1575 getTextString(TEXT_ON))) { 1576 mpstatus = 1577 MP_EnableAutoFailback(luOid); 1578 } else if (0 == strcasecmp(optionList->optarg, 1579 getTextString(TEXT_OFF))) { 1580 mpstatus = 1581 MP_DisableAutoFailback(luOid); 1582 } else { 1583 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1584 (void) fprintf(stderr, getTextString( 1585 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1586 cmdStr, 1587 getTextString( 1588 TEXT_ILLEGAL_ARGUMENT)); 1589 (void) printf("\n"); 1590 return (ERROR_CLI_FAILED); 1591 } 1592 break; 1593 case 'p': 1594 /* modify autoprobing */ 1595 cmdStr = getTextString(TEXT_AUTO_PROBING); 1596 if (0 == strcasecmp(optionList->optarg, 1597 getTextString(TEXT_ON))) { 1598 mpstatus = 1599 MP_EnableAutoProbing(luOid); 1600 } else if (0 == strcasecmp(optionList->optarg, 1601 getTextString(TEXT_OFF))) { 1602 mpstatus = 1603 MP_DisableAutoProbing(luOid); 1604 } else { 1605 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1606 (void) fprintf(stderr, getTextString( 1607 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1608 cmdStr, 1609 getTextString( 1610 TEXT_ILLEGAL_ARGUMENT)); 1611 (void) printf("\n"); 1612 return (ERROR_CLI_FAILED); 1613 } 1614 break; 1615 case 'b': 1616 /* modify loadbalance type */ 1617 cmdStr = getTextString(TEXT_LOAD_BALANCE); 1618 mpstatus = 1619 MP_SetLogicalUnitLoadBalanceType(luOid, 1620 getLbValueFromString(optionList->optarg)); 1621 break; 1622 1623 } /* switch */ 1624 if (MP_STATUS_SUCCESS != mpstatus) { 1625 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1626 (void) fprintf(stderr, 1627 getTextString( 1628 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON), 1629 cmdStr, getMpStatusStr(mpstatus)); 1630 (void) printf("\n"); 1631 return (ERROR_CLI_FAILED); 1632 } 1633 } /* for each operand */ 1634 return (mpstatus); 1635 } 1636 1637 1638 /* 1639 * **************************************************************************** 1640 * 1641 * failoverLogicalUnit - 1642 * mpathadm failover {logical-unit | LU} <logical-unit name>, ... 1643 * 1644 * operand - pointer to operand list from user 1645 * 1646 * **************************************************************************** 1647 */ 1648 int 1649 failoverLogicalUnit(char *operand[]) 1650 { 1651 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1652 MP_OID luOid; 1653 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1654 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps; 1655 MP_OID_LIST *pTpgOidListArray; 1656 boolean_t bFoundIt = B_FALSE; 1657 MP_TPG_STATE_PAIR tpgStatePair; 1658 1659 int tpg; 1660 1661 if (B_TRUE != getLogicalUnitOid(operand[0], &luOid)) { 1662 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1663 (void) fprintf(stderr, getTextString( 1664 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR), 1665 operand[0]); 1666 (void) printf("\n"); 1667 return (ERROR_CLI_FAILED); 1668 } 1669 1670 /* get LUN properties and check to be sure it's asymmetric */ 1671 (void) memset(&luProps, 0, 1672 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1673 mpstatus = 1674 MP_GetMPLogicalUnitProperties(luOid, &luProps); 1675 if (mpstatus != MP_STATUS_SUCCESS) { 1676 (void) fprintf(stderr, "%s: %s\n", 1677 cmdName, getTextString(ERR_NO_PROPERTIES)); 1678 return (mpstatus); 1679 } 1680 1681 if (MP_TRUE != luProps.asymmetric) { 1682 (void) fprintf(stderr, "%s: %s\n", 1683 cmdName, getTextString(ERR_LU_NOT_ASYMMETRIC)); 1684 return (ERROR_CLI_FAILED); 1685 } 1686 1687 /* get TPGs for this LUN */ 1688 mpstatus = 1689 MP_GetAssociatedTPGOidList(luOid, &pTpgOidListArray); 1690 if (mpstatus != MP_STATUS_SUCCESS) { 1691 (void) fprintf(stderr, "%s: %s\n", 1692 cmdName, getTextString(ERR_NO_ASSOC_TPGS)); 1693 return (mpstatus); 1694 } 1695 1696 /* pick a TPG whose state is active or standby, and change it */ 1697 /* to opposite via MP_SetTPGAccessState */ 1698 bFoundIt = B_FALSE; 1699 for (tpg = 0; tpg < pTpgOidListArray->oidCount; tpg++) { 1700 (void) memset(&tpgProps, 0, 1701 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES)); 1702 mpstatus = 1703 MP_GetTargetPortGroupProperties( 1704 pTpgOidListArray->oids[tpg], &tpgProps); 1705 if (mpstatus != MP_STATUS_SUCCESS) { 1706 (void) fprintf(stderr, "%s: %s\n", 1707 cmdName, getTextString(ERR_NO_PROPERTIES)); 1708 return (ERROR_CLI_FAILED); 1709 } 1710 if (MP_FALSE == tpgProps.explicitFailover) { 1711 (void) fprintf(stderr, "%s: %s\n", 1712 cmdName, getTextString(ERR_NO_FAILOVER_ALLOWED)); 1713 return (ERROR_CLI_FAILED); 1714 } 1715 1716 /* find one that is standby */ 1717 if ((MP_ACCESS_STATE_STANDBY == 1718 tpgProps.accessState) && (B_FALSE == bFoundIt)) { 1719 1720 bFoundIt = B_TRUE; 1721 1722 tpgStatePair.tpgOid = 1723 pTpgOidListArray->oids[tpg]; 1724 tpgStatePair.desiredState = 1725 MP_ACCESS_STATE_ACTIVE; 1726 mpstatus = 1727 MP_SetTPGAccess(luOid, 1, &tpgStatePair); 1728 if (MP_STATUS_SUCCESS != mpstatus) { 1729 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1730 (void) fprintf(stderr, getTextString( 1731 ERR_FAILED_TO_FAILOVER_WITH_REASON), 1732 getMpStatusStr(mpstatus)); 1733 (void) printf("\n"); 1734 return (mpstatus); 1735 } 1736 } 1737 1738 1739 } /* for each tpg */ 1740 1741 if (B_FALSE == bFoundIt) { 1742 (void) fprintf(stderr, "%s: %s\n", 1743 cmdName, getTextString(ERR_LU_ACCESS_STATE_UNCHANGED)); 1744 return (ERROR_CLI_FAILED); 1745 } 1746 1747 return (mpstatus); 1748 } 1749 1750 1751 /* 1752 * **************************************************************************** 1753 * 1754 * getLogicalUnitOid - 1755 * Search through all plugins and get the OID for specified logical unit 1756 * 1757 * luFileName - file name of LU (specified by the user) to find 1758 * pLuOid - OID to return 1759 * 1760 * **************************************************************************** 1761 */ 1762 boolean_t 1763 getLogicalUnitOid(MP_CHAR *luFileName, MP_OID *pluOid) 1764 { 1765 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1766 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 1767 MP_PLUGIN_PROPERTIES pluginProps; 1768 MP_OID_LIST *pPluginOidList, 1769 *pLogicalUnitOidList; 1770 boolean_t foundIt = B_FALSE; 1771 1772 int i, 1773 lu; 1774 1775 int fd1, fd2; 1776 ddi_devid_t devid1 = NULL, devid2 = NULL; 1777 1778 if (NULL == pluOid) { 1779 /* print some kind of error msg here - should never happen */ 1780 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1781 (void) fprintf(stderr, getTextString(ERR_MEMORY_ALLOCATION)); 1782 (void) printf("\n"); 1783 return (B_FALSE); 1784 } 1785 1786 pluOid->objectSequenceNumber = 0; 1787 pluOid->objectType = 0; 1788 pluOid->ownerId = 0; 1789 1790 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 1791 != MP_STATUS_SUCCESS) { 1792 (void) fprintf(stderr, "%s: %s\n", cmdName, 1793 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1794 return (B_FALSE); 1795 } 1796 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 1797 (void) fprintf(stderr, "%s: %s\n", cmdName, 1798 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1799 return (ERROR_CLI_FAILED); 1800 } 1801 for (i = 0; i < pPluginOidList->oidCount; i++) { 1802 1803 /* get properties so we can list the name */ 1804 (void) memset(&pluginProps, 0, sizeof (MP_PLUGIN_PROPERTIES)); 1805 if ((mpstatus = 1806 MP_GetPluginProperties(pPluginOidList->oids[i], 1807 &pluginProps)) != MP_STATUS_SUCCESS) { 1808 (void) fprintf(stderr, "%s: %s\n", 1809 cmdName, getTextString(ERR_NO_PROPERTIES)); 1810 return (B_FALSE); 1811 } 1812 1813 /* attempt to find this logical unit */ 1814 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i], 1815 &pLogicalUnitOidList); 1816 if (mpstatus != MP_STATUS_SUCCESS) { 1817 (void) fprintf(stderr, "%s: %s\n", 1818 cmdName, getTextString(ERR_NO_LU_LIST)); 1819 return (B_FALSE); 1820 } 1821 1822 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) && 1823 (B_FALSE == foundIt); lu++) { 1824 1825 /* get lu properties so we can check the name */ 1826 (void) memset(&luProps, 0, 1827 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 1828 mpstatus = 1829 MP_GetMPLogicalUnitProperties( 1830 pLogicalUnitOidList->oids[lu], &luProps); 1831 if (mpstatus != MP_STATUS_SUCCESS) { 1832 (void) fprintf(stderr, "%s: %s\n", 1833 cmdName, getTextString(ERR_NO_PROPERTIES)); 1834 return (B_FALSE); 1835 } 1836 1837 if (0 == strcmp(luFileName, luProps.deviceFileName)) { 1838 foundIt = B_TRUE; 1839 } else { 1840 /* user input didn't match, try via devid */ 1841 /* 1842 * I don't see a reason to print the error for 1843 * any of these since they'll get the error at 1844 * the end anyway 1845 */ 1846 1847 fd1 = fd2 = -1; 1848 if (((fd1 = open(luFileName, 1849 O_RDONLY|O_NDELAY)) >= 0) && 1850 ((fd2 = open(luProps.deviceFileName, 1851 O_RDONLY|O_NDELAY)) >= 0) && 1852 (devid_get(fd1, &devid1) == 0) && 1853 (devid_get(fd2, &devid2) == 0) && 1854 ((NULL != devid1) && (NULL != devid2))) { 1855 if (0 == 1856 (devid_compare(devid1, devid2))) { 1857 foundIt = B_TRUE; 1858 } 1859 } 1860 1861 if (NULL != devid1) { 1862 devid_free(devid1); 1863 } 1864 if (NULL != devid2) { 1865 devid_free(devid2); 1866 } 1867 1868 if (fd1 >= 0) { 1869 (void) close(fd1); 1870 } 1871 if (fd2 >= 0) { 1872 (void) close(fd2); 1873 } 1874 } 1875 if (B_TRUE == foundIt) { 1876 pluOid->objectSequenceNumber = 1877 pLogicalUnitOidList-> 1878 oids[lu].objectSequenceNumber; 1879 pluOid->objectType = 1880 pLogicalUnitOidList-> 1881 oids[lu].objectType; 1882 pluOid->ownerId = 1883 pLogicalUnitOidList->oids[lu].ownerId; 1884 } 1885 } 1886 } 1887 1888 return (foundIt); 1889 } 1890 1891 1892 /* 1893 * **************************************************************************** 1894 * 1895 * listInitiatorPort - 1896 * mpathadm list initiator-port [<initiator-port name>, ...] 1897 * 1898 * operandLen - number of operands user passed into the cli 1899 * operand - pointer to operand list from user 1900 * 1901 * **************************************************************************** 1902 */ 1903 int 1904 listInitiatorPort(int operandLen, char *operand[]) 1905 { 1906 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 1907 MP_INITIATOR_PORT_PROPERTIES initProps; 1908 MP_OID_LIST *pPluginOidList, 1909 *pInitOidList; 1910 boolean_t bListIt = B_FALSE; 1911 boolean_t *foundOp; 1912 1913 int ol, 1914 i, 1915 iport; 1916 1917 foundOp = malloc((sizeof (boolean_t)) * operandLen); 1918 if (NULL == foundOp) { 1919 (void) fprintf(stdout, "%s\n", 1920 getTextString(ERR_MEMORY_ALLOCATION)); 1921 return (ERROR_CLI_FAILED); 1922 } 1923 1924 for (ol = 0; ol < operandLen; ol++) { 1925 foundOp[ol] = B_FALSE; 1926 } 1927 1928 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 1929 != MP_STATUS_SUCCESS) { 1930 (void) fprintf(stderr, "%s: %s\n", cmdName, 1931 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1932 return (mpstatus); 1933 } 1934 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 1935 (void) fprintf(stderr, "%s: %s\n", cmdName, 1936 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 1937 return (ERROR_CLI_FAILED); 1938 } 1939 1940 for (i = 0; i < pPluginOidList->oidCount; i++) { 1941 mpstatus = 1942 MP_GetInitiatorPortOidList(pPluginOidList->oids[i], 1943 &pInitOidList); 1944 if (mpstatus != MP_STATUS_SUCCESS) { 1945 /* LINTED E_SEC_PRINTF_VAR_FMT */ 1946 (void) fprintf(stderr, 1947 getTextString(ERR_NO_INIT_PORT_LIST_WITH_REASON), 1948 getMpStatusStr(mpstatus)); 1949 (void) printf("\n"); 1950 } else if ((NULL == pInitOidList) || 1951 (pInitOidList->oidCount < 1)) { 1952 (void) fprintf(stderr, "%s: %s\n", cmdName, 1953 getTextString(ERR_NO_INIT_PORTS)); 1954 } else { 1955 for (iport = 0; 1956 iport < pInitOidList->oidCount; iport ++) { 1957 bListIt = B_FALSE; 1958 if ((mpstatus = 1959 MP_GetInitiatorPortProperties( 1960 pInitOidList->oids[iport], 1961 &initProps)) != MP_STATUS_SUCCESS) { 1962 (void) fprintf(stderr, 1963 "%s: %s\n", cmdName, 1964 getTextString(ERR_NO_PROPERTIES)); 1965 } else { 1966 /* if no operands listed, */ 1967 /* list all we find */ 1968 if (0 == operandLen) { 1969 bListIt = B_TRUE; 1970 } else { 1971 1972 /* check each operand */ 1973 /* Is it */ 1974 /* the one we want to list? */ 1975 for (ol = 0; 1976 ol < operandLen; ol++) { 1977 if (0 == 1978 strcmp(operand[ol], 1979 initProps. 1980 portID)) { 1981 bListIt = 1982 B_TRUE; 1983 foundOp[ol] = 1984 B_TRUE; 1985 } 1986 } 1987 } 1988 } 1989 1990 if (B_TRUE == bListIt) { 1991 1992 if (listIndividualInitiatorPort( 1993 initProps) != 0) { 1994 return (ERROR_CLI_FAILED); 1995 } 1996 1997 } /* list It */ 1998 1999 } /* for each initiator port */ 2000 } /* else found an init port */ 2001 2002 } /* for each plugin */ 2003 2004 for (ol = 0; ol < operandLen; ol++) { 2005 if (B_FALSE == foundOp[ol]) { 2006 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2007 (void) fprintf(stderr, getTextString( 2008 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR), 2009 operand[ol]); 2010 (void) printf("\n"); 2011 } 2012 } 2013 2014 return (mpstatus); 2015 } 2016 2017 2018 /* 2019 * **************************************************************************** 2020 * 2021 * listIndividualInitiatorPort - 2022 * used by listInitiatorPort to list info for one init port 2023 * 2024 * initProps - properties of initiator port to list 2025 * 2026 * **************************************************************************** 2027 */ 2028 int 2029 listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps) 2030 { 2031 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2032 2033 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT)); 2034 displayArray(initProps.portID, 2035 sizeof (initProps.portID)); 2036 (void) printf("\n"); 2037 2038 return (mpstatus); 2039 2040 } 2041 2042 2043 /* 2044 * **************************************************************************** 2045 * 2046 * showInitiatorPort - 2047 * mpathadm show initiator-port <initiator-port name>, ... 2048 * 2049 * operandLen - number of operands user passed into the cli 2050 * operand - pointer to operand list from user 2051 * 2052 * **************************************************************************** 2053 */ 2054 int 2055 showInitiatorPort(int operandLen, char *operand[]) 2056 { 2057 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2058 MP_INITIATOR_PORT_PROPERTIES initProps; 2059 MP_OID_LIST *pPluginOidList, 2060 *pInitOidList; 2061 boolean_t bListIt = B_FALSE, 2062 bFoundIt = B_FALSE; 2063 int op, 2064 i, 2065 iport; 2066 2067 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 2068 != MP_STATUS_SUCCESS) { 2069 (void) fprintf(stderr, "%s: %s\n", cmdName, 2070 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2071 return (mpstatus); 2072 } 2073 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 2074 (void) fprintf(stderr, "%s: %s\n", cmdName, 2075 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2076 return (ERROR_CLI_FAILED); 2077 } 2078 2079 for (op = 0; op < operandLen; op++) { 2080 bFoundIt = B_FALSE; 2081 2082 for (i = 0; i < pPluginOidList->oidCount; i++) { 2083 2084 mpstatus = 2085 MP_GetInitiatorPortOidList(pPluginOidList->oids[i], 2086 &pInitOidList); 2087 if (mpstatus != MP_STATUS_SUCCESS) { 2088 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2089 (void) fprintf(stderr, 2090 getTextString( 2091 ERR_NO_INIT_PORT_LIST_WITH_REASON), 2092 getMpStatusStr(mpstatus)); 2093 (void) printf("\n"); 2094 } else if ((NULL == pInitOidList) || 2095 (pInitOidList->oidCount < 1)) { 2096 (void) fprintf(stderr, "%s: %s\n", cmdName, 2097 getTextString(ERR_NO_INIT_PORTS)); 2098 } else { 2099 2100 for (iport = 0; 2101 iport < pInitOidList->oidCount; 2102 iport ++) { 2103 bListIt = B_FALSE; 2104 2105 if ((mpstatus = 2106 MP_GetInitiatorPortProperties( 2107 pInitOidList->oids[iport], 2108 &initProps)) 2109 != MP_STATUS_SUCCESS) { 2110 (void) fprintf(stderr, 2111 "%s: %s\n", cmdName, 2112 getTextString(ERR_NO_PROPERTIES)); 2113 } else { 2114 if (0 == strcmp(operand[op], 2115 initProps.portID)) { 2116 bListIt = B_TRUE; 2117 bFoundIt = B_TRUE; 2118 } 2119 } 2120 2121 if (B_TRUE == bListIt) { 2122 mpstatus = 2123 showIndividualInitiatorPort( 2124 initProps); 2125 if (0 != mpstatus) { 2126 return (mpstatus); 2127 } 2128 2129 } /* list It */ 2130 2131 } /* for each initiator port */ 2132 } /* else found an init port */ 2133 2134 } /* for each plugin */ 2135 2136 if (B_FALSE == bFoundIt) { 2137 /* need temp string here since we need to fill in a */ 2138 /* name in the error string */ 2139 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2140 (void) fprintf(stderr, getTextString( 2141 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR), 2142 operand[op]); 2143 (void) printf("\n"); 2144 } 2145 2146 } /* for each operand */ 2147 2148 return (mpstatus); 2149 } 2150 2151 2152 /* 2153 * **************************************************************************** 2154 * 2155 * showIndividualInitiatorPort - 2156 * used by showInitiatorPort to show info for one init port 2157 * 2158 * initProps - properties of initiator port to show 2159 * 2160 * **************************************************************************** 2161 */ 2162 int 2163 showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps) 2164 { 2165 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2166 2167 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT)); 2168 displayArray(initProps.portID, 2169 sizeof (initProps.portID)); 2170 2171 (void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE)); 2172 displayTransportTypeString(initProps.portType); 2173 (void) printf("\n"); 2174 2175 (void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE)); 2176 displayArray(initProps.osDeviceFile, 2177 sizeof (initProps.osDeviceFile)); 2178 (void) printf("\n"); 2179 2180 return (mpstatus); 2181 } 2182 2183 2184 /* 2185 * **************************************************************************** 2186 * 2187 * enablePath - 2188 * mpathadm enable path -i <initiator-port> 2189 * -t <target-port name> -l <logical-unit name> 2190 * 2191 * options - pointer to option list from user 2192 * 2193 * **************************************************************************** 2194 */ 2195 int 2196 enablePath(cmdOptions_t *options) 2197 { 2198 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2199 MP_OID pathOid; 2200 2201 cmdOptions_t *optionList = options; 2202 boolean_t bHaveInit = B_FALSE, 2203 bHaveTarg = B_FALSE, 2204 bHaveLu = B_FALSE; 2205 2206 for (; optionList->optval; optionList++) { 2207 switch (optionList->optval) { 2208 case 'i': 2209 /* have init port name */ 2210 bHaveInit = B_TRUE; 2211 break; 2212 case 't': 2213 /* have target port id */ 2214 bHaveTarg = B_TRUE; 2215 break; 2216 case 'l': 2217 /* have LU name */ 2218 bHaveLu = B_TRUE; 2219 break; 2220 } 2221 } 2222 if (B_FALSE == bHaveInit) { 2223 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2224 (void) fprintf(stderr, 2225 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2226 getTextString(MISSING_INIT_PORT_NAME)); 2227 (void) printf("\n"); 2228 return (ERROR_CLI_FAILED); 2229 } else if (B_FALSE == bHaveTarg) { 2230 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2231 (void) fprintf(stderr, 2232 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2233 getTextString(MISSING_TARGET_PORT_NAME)); 2234 (void) printf("\n"); 2235 return (ERROR_CLI_FAILED); 2236 } else if (B_FALSE == bHaveLu) { 2237 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2238 (void) fprintf(stderr, 2239 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2240 getTextString(MISSING_LU_NAME)); 2241 (void) printf("\n"); 2242 return (ERROR_CLI_FAILED); 2243 } 2244 2245 if (B_FALSE == getPathOid(options, &pathOid)) { 2246 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2247 (void) fprintf(stderr, 2248 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2249 getTextString(FAILED_TO_FIND_PATH)); 2250 (void) printf("\n"); 2251 return (ERROR_CLI_FAILED); 2252 } 2253 2254 /* found the path, attempt to enable it */ 2255 mpstatus = MP_EnablePath(pathOid); 2256 if (mpstatus != MP_STATUS_SUCCESS) { 2257 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2258 (void) fprintf(stderr, 2259 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON), 2260 getMpStatusStr(mpstatus)); 2261 (void) printf("\n"); 2262 return (mpstatus); 2263 } 2264 2265 return (mpstatus); 2266 } 2267 2268 2269 /* 2270 * **************************************************************************** 2271 * 2272 * disablePath - 2273 * mpathadm disable path -i <initiator-port> 2274 * -t <target-port name> -l <logical-unit name> 2275 * 2276 * options - pointer to option list from user 2277 * 2278 * **************************************************************************** 2279 */ 2280 int 2281 disablePath(cmdOptions_t *options) 2282 { 2283 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2284 MP_OID pathOid; 2285 2286 cmdOptions_t *optionList = options; 2287 boolean_t bHaveInit = B_FALSE, 2288 bHaveTarg = B_FALSE, 2289 bHaveLu = B_FALSE; 2290 2291 for (; optionList->optval; optionList++) { 2292 switch (optionList->optval) { 2293 case 'i': 2294 /* have init port name */ 2295 bHaveInit = B_TRUE; 2296 break; 2297 case 't': 2298 /* have target port id */ 2299 bHaveTarg = B_TRUE; 2300 break; 2301 case 'l': 2302 /* have LU name */ 2303 bHaveLu = B_TRUE; 2304 break; 2305 } 2306 } 2307 if (B_FALSE == bHaveInit) { 2308 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2309 (void) fprintf(stderr, 2310 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2311 getTextString(MISSING_INIT_PORT_NAME)); 2312 (void) printf("\n"); 2313 return (ERROR_CLI_FAILED); 2314 } else if (B_FALSE == bHaveTarg) { 2315 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2316 (void) fprintf(stderr, 2317 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2318 getTextString(MISSING_TARGET_PORT_NAME)); 2319 (void) printf("\n"); 2320 return (ERROR_CLI_FAILED); 2321 } else if (B_FALSE == bHaveLu) { 2322 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2323 (void) fprintf(stderr, 2324 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2325 getTextString(MISSING_LU_NAME)); 2326 (void) printf("\n"); 2327 return (ERROR_CLI_FAILED); 2328 } 2329 2330 if (B_FALSE == getPathOid(options, &pathOid)) { 2331 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2332 (void) fprintf(stderr, 2333 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2334 getTextString(FAILED_TO_FIND_PATH)); 2335 (void) printf("\n"); 2336 return (ERROR_CLI_FAILED); 2337 } 2338 2339 /* found the path, attempt to enable it */ 2340 mpstatus = MP_DisablePath(pathOid); 2341 if (MP_STATUS_SUCCESS != mpstatus) { 2342 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2343 (void) fprintf(stderr, getTextString( 2344 ERR_FAILED_TO_DISABLE_PATH_WITH_REASON), 2345 getMpStatusStr(mpstatus)); 2346 (void) printf("\n"); 2347 return (mpstatus); 2348 } 2349 2350 2351 return (mpstatus); 2352 } 2353 2354 2355 /* 2356 * **************************************************************************** 2357 * 2358 * overridePath - 2359 * mpathadm override path {-i <initiator-port> 2360 * -t <target-port name> | -c} <logical-unit name> 2361 * 2362 * options - pointer to option list from user 2363 * 2364 * **************************************************************************** 2365 */ 2366 int 2367 overridePath(cmdOptions_t *options) 2368 { 2369 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2370 MP_OID pathOid, luOid; 2371 boolean_t bCancelOverride = B_FALSE; 2372 MP_CHAR pLuDeviceFileName[256]; 2373 cmdOptions_t *optionList = options; 2374 2375 /* First check to see if we have the cancel option, */ 2376 /* May as well save off the lun while we're at it */ 2377 for (; optionList->optval; optionList++) { 2378 switch (optionList->optval) { 2379 case 'c': 2380 /* we have a cancel */ 2381 bCancelOverride = B_TRUE; 2382 break; 2383 case 'l': 2384 /* we have a lun- save it while we're here */ 2385 (void) memcpy(pLuDeviceFileName, 2386 optionList->optarg, 256); 2387 break; 2388 } 2389 } 2390 2391 if (B_TRUE == bCancelOverride) { 2392 /* if we have the cancel option, */ 2393 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) { 2394 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2395 (void) fprintf(stderr, 2396 getTextString( 2397 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON), 2398 getTextString(LU_NOT_FOUND)); 2399 (void) printf("\n"); 2400 return (ERROR_CLI_FAILED); 2401 } 2402 2403 /* cancel the override path for the specified LU */ 2404 mpstatus = MP_CancelOverridePath(luOid); 2405 if (MP_STATUS_SUCCESS != mpstatus) { 2406 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2407 (void) fprintf(stderr, 2408 getTextString( 2409 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON), 2410 getMpStatusStr(mpstatus)); 2411 (void) printf("\n"); 2412 return (mpstatus); 2413 } 2414 } else { 2415 /* must be wanting to override the path */ 2416 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) { 2417 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2418 (void) fprintf(stderr, 2419 getTextString( 2420 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2421 getTextString(LU_NOT_FOUND)); 2422 (void) printf("\n"); 2423 return (ERROR_CLI_FAILED); 2424 } 2425 2426 if (B_FALSE == getPathOid(options, &pathOid)) { 2427 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2428 (void) fprintf(stderr, 2429 getTextString( 2430 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2431 getTextString(FAILED_TO_FIND_PATH)); 2432 2433 (void) printf("\n"); 2434 return (ERROR_CLI_FAILED); 2435 } 2436 2437 /* attempt to set the override path */ 2438 mpstatus = MP_SetOverridePath(luOid, pathOid); 2439 if (mpstatus != MP_STATUS_SUCCESS) { 2440 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2441 (void) fprintf(stderr, 2442 getTextString( 2443 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON), 2444 getMpStatusStr(mpstatus)); 2445 (void) printf("\n"); 2446 return (mpstatus); 2447 } 2448 } 2449 2450 return (mpstatus); 2451 } 2452 2453 2454 /* 2455 * **************************************************************************** 2456 * 2457 * getPathOid - 2458 * Search through all plugins and get the OID for specified path 2459 * 2460 * operand - pointer to operand list from user 2461 * options - pointer to option list from user 2462 * 2463 * **************************************************************************** 2464 */ 2465 boolean_t 2466 getPathOid(cmdOptions_t *options, MP_OID *pPathOid) 2467 { 2468 MP_STATUS mpstatus = MP_STATUS_SUCCESS; 2469 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps; 2470 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps; 2471 MP_INITIATOR_PORT_PROPERTIES initProps; 2472 MP_TARGET_PORT_PROPERTIES targProps; 2473 2474 MP_OID_LIST *pPluginOidList, 2475 *pLogicalUnitOidList, 2476 *pathOidListArray; 2477 2478 boolean_t bFoundIt = B_FALSE; 2479 MP_CHAR initPortID[256]; 2480 MP_CHAR targetPortID[256]; 2481 MP_CHAR luDeviceFileName[256]; 2482 boolean_t bHaveTarg = B_FALSE, 2483 bHaveLu = B_FALSE, 2484 bHaveInit = B_FALSE; 2485 2486 2487 cmdOptions_t *optionList = options; 2488 2489 int i, 2490 lu, 2491 pa; 2492 if (NULL == pPathOid) { 2493 return (B_FALSE); 2494 } 2495 2496 for (; optionList->optval; optionList++) { 2497 switch (optionList->optval) { 2498 case 'i': 2499 /* save init port name */ 2500 (void) memcpy(initPortID, 2501 optionList->optarg, 256); 2502 bHaveInit = B_TRUE; 2503 break; 2504 case 't': 2505 /* save target port id */ 2506 (void) memcpy(targetPortID, 2507 optionList->optarg, 256); 2508 bHaveTarg = B_TRUE; 2509 break; 2510 case 'l': 2511 /* save LU name */ 2512 (void) memcpy(luDeviceFileName, 2513 optionList->optarg, 256); 2514 bHaveLu = B_TRUE; 2515 break; 2516 } 2517 } 2518 2519 2520 if ((B_FALSE == bHaveInit) || 2521 (B_FALSE == bHaveTarg) || 2522 (B_FALSE == bHaveLu)) { 2523 /* if we don't have all three pieces, we can't find the path */ 2524 2525 return (B_FALSE); 2526 } 2527 2528 /* get the plugin ist */ 2529 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) 2530 != MP_STATUS_SUCCESS) { 2531 (void) fprintf(stderr, "%s: %s\n", cmdName, 2532 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2533 return (B_FALSE); 2534 } 2535 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) { 2536 (void) fprintf(stderr, "%s: %s\n", cmdName, 2537 getTextString(ERR_NO_MPATH_SUPPORT_LIST)); 2538 return (B_FALSE); 2539 } 2540 2541 for (i = 0; i < pPluginOidList->oidCount; i++) { 2542 2543 /* get Logical Unit list */ 2544 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i], 2545 &pLogicalUnitOidList); 2546 if (mpstatus != MP_STATUS_SUCCESS) { 2547 (void) fprintf(stderr, "%s: %s\n", 2548 cmdName, getTextString(ERR_NO_LU_LIST)); 2549 return (B_FALSE); 2550 } 2551 2552 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) && 2553 (B_FALSE == bFoundIt); lu++) { 2554 2555 /* get lu properties so we can check the name */ 2556 (void) memset(&luProps, 0, 2557 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES)); 2558 mpstatus = 2559 MP_GetMPLogicalUnitProperties( 2560 pLogicalUnitOidList->oids[lu], &luProps); 2561 if (mpstatus != MP_STATUS_SUCCESS) { 2562 (void) fprintf(stderr, "%s: %s\n", 2563 cmdName, getTextString(ERR_NO_PROPERTIES)); 2564 return (B_FALSE); 2565 } 2566 if (0 == strcmp(luDeviceFileName, 2567 luProps.deviceFileName)) { 2568 /* get paths for this LU and search from here */ 2569 mpstatus = 2570 MP_GetAssociatedPathOidList( 2571 pLogicalUnitOidList->oids[lu], 2572 &pathOidListArray); 2573 if (mpstatus != MP_STATUS_SUCCESS) { 2574 /* LINTED E_SEC_PRINTF_VAR_FMT */ 2575 (void) fprintf(stderr, 2576 getTextString( 2577 ERR_FAILED_TO_FIND_PATH)); 2578 (void) printf("\n"); 2579 return (B_FALSE); 2580 } 2581 2582 for (pa = 0; 2583 (pa < pathOidListArray->oidCount) && 2584 (B_FALSE == bFoundIt); pa++) { 2585 mpstatus = 2586 MP_GetPathLogicalUnitProperties 2587 (pathOidListArray->oids[pa], 2588 &pathProps); 2589 if (mpstatus != MP_STATUS_SUCCESS) { 2590 (void) fprintf(stderr, 2591 "%s: %s\n", cmdName, 2592 getTextString( 2593 ERR_NO_PROPERTIES)); 2594 return (B_FALSE); 2595 } 2596 2597 /* 2598 * get properties of iniator port and 2599 * target port to see if we have the 2600 * right path 2601 */ 2602 mpstatus = 2603 MP_GetInitiatorPortProperties( 2604 pathProps.initiatorPortOid, 2605 &initProps); 2606 2607 if (mpstatus != MP_STATUS_SUCCESS) { 2608 (void) fprintf(stderr, 2609 "%s: %s\n", cmdName, 2610 getTextString( 2611 ERR_NO_PROPERTIES)); 2612 return (B_FALSE); 2613 } 2614 if (0 == strcmp(initPortID, initProps.portID)) { 2615 /* lu and init port matches, check target port */ 2616 mpstatus = MP_GetTargetPortProperties(pathProps.targetPortOid, 2617 &targProps); 2618 if (mpstatus != MP_STATUS_SUCCESS) { 2619 (void) fprintf(stderr, "%s: %s\n", cmdName, 2620 getTextString(ERR_NO_PROPERTIES)); 2621 return (B_FALSE); 2622 } 2623 2624 if (0 == strcmp(targetPortID, targProps.portID)) { 2625 /* we found our path */ 2626 pPathOid->objectSequenceNumber = 2627 pathOidListArray->oids[pa].objectSequenceNumber; 2628 pPathOid->objectType = 2629 pathOidListArray->oids[pa].objectType; 2630 pPathOid->ownerId = pathOidListArray->oids[pa].ownerId; 2631 bFoundIt = B_TRUE; 2632 } 2633 } /* init port matched */ 2634 2635 } /* for each path associated with this lu */ 2636 2637 } /* lu matched */ 2638 2639 } /* for each lu */ 2640 2641 } /* for each plugin */ 2642 2643 return (bFoundIt); 2644 } 2645 2646 2647 /* 2648 * **************************************************************************** 2649 * 2650 * getLbValueFromString 2651 * Gets the MP_LOAD_BALANCE_TYPE specified load balance type string 2652 * 2653 * lbStr - load balance string defined in the .h file 2654 * This is what users will be required to feed into the 2655 * modify lu command. 2656 * 2657 * **************************************************************************** 2658 */ 2659 MP_LOAD_BALANCE_TYPE 2660 getLbValueFromString(char *lbStr) 2661 { 2662 MP_LOAD_BALANCE_TYPE lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN; 2663 2664 if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_ROUNDROBIN))) { 2665 lbVal = MP_LOAD_BALANCE_TYPE_ROUNDROBIN; 2666 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTBLOCKS))) { 2667 lbVal = MP_LOAD_BALANCE_TYPE_LEASTBLOCKS; 2668 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTIO))) { 2669 lbVal = MP_LOAD_BALANCE_TYPE_LEASTIO; 2670 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_DEVICEPROD))) { 2671 lbVal = MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT; 2672 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LBAREGION))) { 2673 lbVal = MP_LOAD_BALANCE_TYPE_LBA_REGION; 2674 } else if (0 == strcmp(lbStr, 2675 getTextString(TEXT_LBTYPE_FAILOVER_ONLY))) { 2676 lbVal = MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY; 2677 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_UNKNOWN))) { 2678 lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN; 2679 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_NONE))) { 2680 lbVal = 0; 2681 } else if (0 == strcmp(lbStr, 2682 getTextString(TEXT_LBTYPE_PROPRIETARY1))) { 2683 lbVal = ((MP_UINT32)0x00000001)<<16; 2684 } else if (0 == strcmp(lbStr, 2685 getTextString(TEXT_LBTYPE_PROPRIETARY2))) { 2686 lbVal = ((MP_UINT32)0x00000001)<<17; 2687 } else if (0 == strcmp(lbStr, 2688 getTextString(TEXT_LBTYPE_PROPRIETARY3))) { 2689 lbVal = ((MP_UINT32)0x00000001)<<18; 2690 } else if (0 == strcmp(lbStr, 2691 getTextString(TEXT_LBTYPE_PROPRIETARY4))) { 2692 lbVal = ((MP_UINT32)0x00000001)<<19; 2693 } else if (0 == strcmp(lbStr, 2694 getTextString(TEXT_LBTYPE_PROPRIETARY5))) { 2695 lbVal = ((MP_UINT32)0x00000001)<<20; 2696 } else if (0 == strcmp(lbStr, 2697 getTextString(TEXT_LBTYPE_PROPRIETARY6))) { 2698 lbVal = ((MP_UINT32)0x00000001)<<21; 2699 } else if (0 == strcmp(lbStr, 2700 getTextString(TEXT_LBTYPE_PROPRIETARY7))) { 2701 lbVal = ((MP_UINT32)0x00000001)<<22; 2702 } else if (0 == strcmp(lbStr, 2703 getTextString(TEXT_LBTYPE_PROPRIETARY8))) { 2704 lbVal = ((MP_UINT32)0x00000001)<<23; 2705 } else if (0 == strcmp(lbStr, 2706 getTextString(TEXT_LBTYPE_PROPRIETARY9))) { 2707 lbVal = ((MP_UINT32)0x00000001)<<24; 2708 } else if (0 == strcmp(lbStr, 2709 getTextString(TEXT_LBTYPE_PROPRIETARY10))) { 2710 lbVal = ((MP_UINT32)0x00000001)<<25; 2711 } else if (0 == strcmp(lbStr, 2712 getTextString(TEXT_LBTYPE_PROPRIETARY11))) { 2713 lbVal = ((MP_UINT32)0x00000001)<<26; 2714 } else if (0 == strcmp(lbStr, 2715 getTextString(TEXT_LBTYPE_PROPRIETARY12))) { 2716 lbVal = ((MP_UINT32)0x00000001)<<27; 2717 } else if (0 == strcmp(lbStr, 2718 getTextString(TEXT_LBTYPE_PROPRIETARY13))) { 2719 lbVal = ((MP_UINT32)0x00000001)<<28; 2720 } else if (0 == strcmp(lbStr, 2721 getTextString(TEXT_LBTYPE_PROPRIETARY14))) { 2722 lbVal = ((MP_UINT32)0x00000001)<<29; 2723 } else if (0 == strcmp(lbStr, 2724 getTextString(TEXT_LBTYPE_PROPRIETARY15))) { 2725 lbVal = ((MP_UINT32)0x00000001)<<30; 2726 } else if (0 == strcmp(lbStr, 2727 getTextString(TEXT_LBTYPE_PROPRIETARY16))) { 2728 lbVal = ((MP_UINT32)0x00000001)<<31; 2729 } 2730 2731 return (lbVal); 2732 2733 2734 } /* end getLbValueFromString */ 2735 2736 2737 /* 2738 * **************************************************************************** 2739 * 2740 * displayLogicalUnitNameTypeString 2741 * Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE 2742 * specified load balance type 2743 * 2744 * typeVal - load balance type defined in the MPAPI spec 2745 * 2746 * **************************************************************************** 2747 */ 2748 void 2749 displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal) 2750 { 2751 2752 char *typeString; 2753 2754 switch (typeVal) { 2755 2756 case MP_LU_NAME_TYPE_UNKNOWN: 2757 typeString = getTextString(TEXT_NAME_TYPE_UNKNOWN); 2758 break; 2759 case MP_LU_NAME_TYPE_VPD83_TYPE1: 2760 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE1); 2761 break; 2762 case MP_LU_NAME_TYPE_VPD83_TYPE2: 2763 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE2); 2764 break; 2765 case MP_LU_NAME_TYPE_VPD83_TYPE3: 2766 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE3); 2767 break; 2768 case MP_LU_NAME_TYPE_DEVICE_SPECIFIC: 2769 typeString = 2770 getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC); 2771 break; 2772 default: 2773 typeString = getTextString(TEXT_UNKNOWN); 2774 break; 2775 } 2776 2777 (void) printf("%s", typeString); 2778 2779 2780 } /* end displayLogicalUnitNameTypeString */ 2781 2782 /* 2783 * **************************************************************************** 2784 * 2785 * displayLoadBalanceString 2786 * Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE 2787 * specified load balance type 2788 * 2789 * lbVal - load balance type defined in the MPAPI spec 2790 * 2791 * **************************************************************************** 2792 */ 2793 void 2794 displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal) 2795 { 2796 2797 char *lbString; 2798 2799 switch (lbVal) { 2800 2801 case MP_LOAD_BALANCE_TYPE_UNKNOWN: 2802 lbString = getTextString(TEXT_LBTYPE_UNKNOWN); 2803 break; 2804 case MP_LOAD_BALANCE_TYPE_ROUNDROBIN: 2805 lbString = getTextString(TEXT_LBTYPE_ROUNDROBIN); 2806 break; 2807 case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS: 2808 lbString = getTextString(TEXT_LBTYPE_LEASTBLOCKS); 2809 break; 2810 case MP_LOAD_BALANCE_TYPE_LEASTIO: 2811 lbString = getTextString(TEXT_LBTYPE_LEASTIO); 2812 break; 2813 case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT: 2814 lbString = getTextString(TEXT_LBTYPE_DEVICEPROD); 2815 break; 2816 case MP_LOAD_BALANCE_TYPE_LBA_REGION: 2817 lbString = getTextString(TEXT_LBTYPE_LBAREGION); 2818 break; 2819 case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY: 2820 lbString = getTextString(TEXT_LBTYPE_FAILOVER_ONLY); 2821 break; 2822 case (((MP_UINT32)0x00000001)<<16): 2823 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY1); 2824 break; 2825 case (((MP_UINT32)0x00000001)<<17): 2826 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY2); 2827 break; 2828 case (((MP_UINT32)0x00000001)<<18): 2829 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY3); 2830 break; 2831 case (((MP_UINT32)0x00000001)<<19): 2832 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY4); 2833 break; 2834 case (((MP_UINT32)0x00000001)<<20): 2835 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY5); 2836 break; 2837 case (((MP_UINT32)0x00000001)<<21): 2838 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY6); 2839 break; 2840 case (((MP_UINT32)0x00000001)<<22): 2841 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY7); 2842 break; 2843 case (((MP_UINT32)0x00000001)<<23): 2844 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY8); 2845 break; 2846 case (((MP_UINT32)0x00000001)<<24): 2847 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY9); 2848 break; 2849 case (((MP_UINT32)0x00000001)<<25): 2850 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY10); 2851 break; 2852 case (((MP_UINT32)0x00000001)<<26): 2853 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY11); 2854 break; 2855 case (((MP_UINT32)0x00000001)<<27): 2856 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY12); 2857 break; 2858 case (((MP_UINT32)0x00000001)<<28): 2859 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY13); 2860 break; 2861 case (((MP_UINT32)0x00000001)<<29): 2862 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY14); 2863 break; 2864 case (((MP_UINT32)0x00000001)<<30): 2865 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY15); 2866 break; 2867 case (((MP_UINT32)0x00000001)<<31): 2868 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY16); 2869 break; 2870 default: 2871 lbString = getTextString(TEXT_UNKNOWN); 2872 break; 2873 } 2874 2875 (void) printf("%s", lbString); 2876 2877 2878 } /* end displayLoadBalanceString */ 2879 2880 /* 2881 * **************************************************************************** 2882 * 2883 * displayTransportTypeString 2884 * Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE 2885 * specified load balance type 2886 * 2887 * transportTypeVal - transport type defined in the MPAPI spec 2888 * 2889 * **************************************************************************** 2890 */ 2891 void 2892 displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal) 2893 { 2894 2895 char *ttypeString; 2896 switch (transportTypeVal) { 2897 2898 case MP_PORT_TRANSPORT_TYPE_MPNODE: 2899 ttypeString = 2900 getTextString(TEXT_TRANS_PORT_TYPE_MPNODE); 2901 break; 2902 case MP_PORT_TRANSPORT_TYPE_FC: 2903 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_FC); 2904 break; 2905 case MP_PORT_TRANSPORT_TYPE_SPI: 2906 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_SPI); 2907 break; 2908 case MP_PORT_TRANSPORT_TYPE_ISCSI: 2909 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_ISCSI); 2910 break; 2911 case MP_PORT_TRANSPORT_TYPE_IFB: 2912 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_IFB); 2913 break; 2914 default: 2915 ttypeString = getTextString(TEXT_UNKNOWN); 2916 break; 2917 } 2918 2919 (void) printf("%s", ttypeString); 2920 2921 } /* end displayTransportTypeString */ 2922 2923 2924 /* 2925 * **************************************************************************** 2926 * 2927 * getMpStatusStr 2928 * Gets the string description for the specified load balance type value 2929 * 2930 * mpstatus - MP_STATUS value 2931 * 2932 * **************************************************************************** 2933 */ 2934 char * 2935 getMpStatusStr(MP_STATUS mpstatus) 2936 { 2937 char *statString; 2938 2939 switch (mpstatus) { 2940 case MP_STATUS_SUCCESS: 2941 statString = getTextString(TEXT_MPSTATUS_SUCCESS); 2942 break; 2943 case MP_STATUS_INVALID_PARAMETER: 2944 statString = getTextString(TEXT_MPSTATUS_INV_PARAMETER); 2945 break; 2946 case MP_STATUS_UNKNOWN_FN: 2947 statString = getTextString(TEXT_MPSTATUS_UNKNOWN_FN); 2948 break; 2949 case MP_STATUS_FAILED: 2950 statString = getTextString(TEXT_MPSTATUS_FAILED); 2951 break; 2952 case MP_STATUS_INSUFFICIENT_MEMORY: 2953 statString = getTextString(TEXT_MPSTATUS_INSUFF_MEMORY); 2954 break; 2955 case MP_STATUS_INVALID_OBJECT_TYPE: 2956 statString = getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE); 2957 break; 2958 case MP_STATUS_UNSUPPORTED: 2959 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED); 2960 break; 2961 case MP_STATUS_OBJECT_NOT_FOUND: 2962 statString = getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND); 2963 break; 2964 case MP_STATUS_ACCESS_STATE_INVALID: 2965 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED); 2966 break; 2967 case MP_STATUS_FN_REPLACED: 2968 statString = getTextString(TEXT_MPSTATUS_FN_REPLACED); 2969 break; 2970 case MP_STATUS_PATH_NONOPERATIONAL: 2971 statString = getTextString(TEXT_MPSTATUS_PATH_NONOP); 2972 break; 2973 case MP_STATUS_TRY_AGAIN: 2974 statString = getTextString(TEXT_MPSTATUS_TRY_AGAIN); 2975 break; 2976 case MP_STATUS_NOT_PERMITTED: 2977 statString = getTextString(TEXT_MPSTATUS_NOT_PERMITTED); 2978 break; 2979 default: 2980 statString = getTextString(TEXT_UNKNOWN); 2981 break; 2982 } 2983 2984 return (statString); 2985 } /* end getMpStatusStr */ 2986 2987 2988 /* 2989 * **************************************************************************** 2990 * 2991 * GetPathStateStr 2992 * Gets the string description for the specified path state type value 2993 * 2994 * pathState - MP_PATH_STATE values 2995 * 2996 * **************************************************************************** 2997 */ 2998 char * 2999 getPathStateStr(MP_PATH_STATE pathState) 3000 { 3001 char *pathString; 3002 3003 switch (pathState) { 3004 case MP_PATH_STATE_OKAY: 3005 pathString = getTextString(TEXT_PATH_STATE_OKAY); 3006 break; 3007 case MP_PATH_STATE_PATH_ERR: 3008 pathString = getTextString(TEXT_PATH_STATE_PATH_ERR); 3009 break; 3010 case MP_PATH_STATE_LU_ERR: 3011 pathString = getTextString(TEXT_PATH_STATE_LU_ERR); 3012 break; 3013 case MP_PATH_STATE_RESERVED: 3014 pathString = getTextString(TEXT_PATH_STATE_RESERVED); 3015 break; 3016 case MP_PATH_STATE_REMOVED: 3017 pathString = getTextString(TEXT_PATH_STATE_REMOVED); 3018 break; 3019 case MP_PATH_STATE_TRANSITIONING: 3020 pathString = 3021 getTextString(TEXT_PATH_STATE_TRANSITIONING); 3022 break; 3023 case MP_PATH_STATE_OPERATIONAL_CLOSED: 3024 pathString = 3025 getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED); 3026 break; 3027 case MP_PATH_STATE_INVALID_CLOSED: 3028 pathString = 3029 getTextString(TEXT_PATH_STATE_INVALID_CLOSED); 3030 break; 3031 case MP_PATH_STATE_OFFLINE_CLOSED: 3032 pathString = 3033 getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED); 3034 break; 3035 default: 3036 pathString = getTextString(TEXT_UNKNOWN); 3037 break; 3038 } 3039 3040 return (pathString); 3041 } /* end getPathStateStr */ 3042 3043 3044 3045 /* 3046 * **************************************************************************** 3047 * 3048 * getAccessStateStr 3049 * Gets the string description for the specified access state type value 3050 * 3051 * accessState - MP_ACCESS_STATE_TYPE values 3052 * 3053 * **************************************************************************** 3054 */ 3055 char * 3056 getAccessStateStr(MP_ACCESS_STATE_TYPE accessState) 3057 { 3058 char *accessString; 3059 3060 switch (accessState) { 3061 case MP_ACCESS_STATE_ACTIVE_OPTIMIZED: 3062 accessString = 3063 getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED); 3064 break; 3065 case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED: 3066 accessString = 3067 getTextString( 3068 TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED); 3069 break; 3070 case MP_ACCESS_STATE_STANDBY: 3071 accessString = 3072 getTextString(TEXT_ACCESS_STATE_STANDBY); 3073 break; 3074 case MP_ACCESS_STATE_UNAVAILABLE: 3075 accessString = 3076 getTextString(TEXT_ACCESS_STATE_UNAVAILABLE); 3077 break; 3078 case MP_ACCESS_STATE_TRANSITIONING: 3079 accessString = 3080 getTextString(TEXT_ACCESS_STATE_TRANSITIONING); 3081 break; 3082 case MP_ACCESS_STATE_ACTIVE: 3083 accessString = getTextString(TEXT_ACCESS_STATE_ACTIVE); 3084 break; 3085 default: 3086 accessString = getTextString(TEXT_UNKNOWN); 3087 break; 3088 } 3089 return (accessString); 3090 } /* end getAccessStateStr */ 3091 3092 3093 /* 3094 * **************************************************************************** 3095 * 3096 * displayArray 3097 * Print out the specified array. 3098 * 3099 * arrayToDisplay - array to display 3100 * arraySize - size of array to display 3101 * 3102 * **************************************************************************** 3103 */ 3104 void 3105 displayArray(MP_CHAR *arrayToDisplay, int arraySize) 3106 { 3107 int i; 3108 3109 for (i = 0; i < arraySize; i++) { 3110 if ('\0' != arrayToDisplay[i]) { 3111 (void) fprintf(stdout, "%c", arrayToDisplay[i]); 3112 } 3113 } 3114 3115 } 3116 3117 3118 /* 3119 * **************************************************************************** 3120 * 3121 * getStringArray 3122 * Return a null terminated array for the specified array as a string, 3123 * This is used for inputting into the %s in formatted strings. 3124 * 3125 * arrayToDisplay - array to display 3126 * arraySize - size of array to display 3127 * 3128 * **************************************************************************** 3129 */ 3130 MP_CHAR * 3131 getStringArray(MP_CHAR *arrayToDisplay, int arraySize) 3132 { 3133 MP_CHAR *newStr; 3134 3135 int i; 3136 3137 newStr = malloc(((sizeof (MP_CHAR)) * arraySize) + 1); 3138 if (NULL == newStr) { 3139 (void) fprintf(stdout, "%s\n", 3140 getTextString(ERR_MEMORY_ALLOCATION)); 3141 } else { 3142 3143 for (i = 0; i < arraySize; i++) { 3144 newStr[i] = arrayToDisplay[i]; 3145 } 3146 newStr[arraySize] = '\0'; 3147 } 3148 3149 return (newStr); 3150 } 3151 3152 3153 /* 3154 * **************************************************************************** 3155 * 3156 * displayWideArray 3157 * Print out the specified wide character array as a string, 3158 * adding the null termination 3159 * 3160 * arrayToDisplay - array to display 3161 * arraySize - size of array to display 3162 * 3163 * **************************************************************************** 3164 */ 3165 void 3166 displayWideArray(MP_WCHAR *arrayToDisplay, int arraySize) 3167 { 3168 int i; 3169 int numChars = arraySize/4; 3170 3171 for (i = 0; i < numChars; i++) { 3172 if (L'\0' != arrayToDisplay[i]) { 3173 (void) fprintf(stdout, "%wc", arrayToDisplay[i]); 3174 } 3175 } 3176 } 3177 3178 3179 /* 3180 * **************************************************************************** 3181 * 3182 * listfunc 3183 * Used by cmdparse for list clis 3184 * 3185 * **************************************************************************** 3186 */ 3187 /*ARGSUSED*/ 3188 static int 3189 listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3190 void *addArgs) 3191 { 3192 int ret = 0; 3193 3194 switch (object) { 3195 case MPATH_SUPPORT: 3196 ret = listMpathSupport(operandLen, operand); 3197 break; 3198 case LOGICAL_UNIT: 3199 ret = listLogicalUnit(operandLen, operand, options); 3200 break; 3201 case INITIATOR_PORT: 3202 ret = listInitiatorPort(operandLen, operand); 3203 break; 3204 default: 3205 (void) fprintf(stderr, "%s: %s\n", 3206 cmdName, getTextString(TEXT_UNKNOWN_OBJECT)); 3207 ret = 1; 3208 break; 3209 } 3210 3211 return (ret); 3212 } 3213 3214 3215 /* 3216 * **************************************************************************** 3217 * 3218 * showFunc 3219 * used bycmdparse for show clis 3220 * 3221 * **************************************************************************** 3222 */ 3223 /*ARGSUSED*/ 3224 static int 3225 showFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3226 void *addArgs) 3227 { 3228 int ret = 0; 3229 3230 switch (object) { 3231 case MPATH_SUPPORT: 3232 ret = showMpathSupport(operandLen, operand); 3233 break; 3234 case LOGICAL_UNIT: 3235 ret = showLogicalUnit(operandLen, operand); 3236 break; 3237 case INITIATOR_PORT: 3238 ret = showInitiatorPort(operandLen, operand); 3239 break; 3240 default: 3241 ret = 1; 3242 break; 3243 } 3244 3245 return (ret); 3246 } 3247 3248 3249 /* 3250 * **************************************************************************** 3251 * 3252 * modifyFunc 3253 * Used by cmdparse for midify clis 3254 * 3255 * 3256 * **************************************************************************** 3257 */ 3258 /*ARGSUSED*/ 3259 static int 3260 modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3261 void *addArgs) 3262 { 3263 int ret = 0; 3264 3265 switch (object) { 3266 case MPATH_SUPPORT: 3267 ret = modifyMpathSupport(operandLen, operand, options); 3268 break; 3269 case LOGICAL_UNIT: 3270 ret = modifyLogicalUnit(operandLen, operand, options); 3271 break; 3272 default: 3273 ret = 1; 3274 break; 3275 } 3276 3277 3278 return (ret); 3279 } 3280 3281 3282 /* 3283 * **************************************************************************** 3284 * 3285 * enableFunc 3286 * Used by cmdpars for enable clis 3287 * 3288 * **************************************************************************** 3289 */ 3290 /*ARGSUSED*/ 3291 static int 3292 enableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3293 void *addArgs) 3294 { 3295 int ret = 0; 3296 3297 switch (object) { 3298 case PATH: 3299 ret = enablePath(options); 3300 break; 3301 default: 3302 ret = 1; 3303 break; 3304 } 3305 3306 return (ret); 3307 } 3308 3309 3310 /* 3311 * **************************************************************************** 3312 * 3313 * disableFunc 3314 * Used by cmdpars for disable clis 3315 * 3316 * **************************************************************************** 3317 */ 3318 /*ARGSUSED*/ 3319 static int 3320 disableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3321 void *addArgs) 3322 { 3323 int ret = 0; 3324 3325 switch (object) { 3326 case PATH: 3327 ret = disablePath(options); 3328 break; 3329 default: 3330 ret = 1; 3331 break; 3332 } 3333 3334 return (ret); 3335 } 3336 3337 3338 /* 3339 * **************************************************************************** 3340 * 3341 * failoverFunc 3342 * Used by cmdpars for failover clis 3343 * 3344 * **************************************************************************** 3345 */ 3346 /*ARGSUSED*/ 3347 static int 3348 failoverFunc(int operandLen, char *operand[], int object, cmdOptions_t *options, 3349 void *addArgs) 3350 { 3351 int ret = 0; 3352 3353 switch (object) { 3354 case LOGICAL_UNIT: 3355 ret = failoverLogicalUnit(operand); 3356 break; 3357 default: 3358 ret = 1; 3359 break; 3360 } 3361 3362 return (ret); 3363 } 3364 3365 3366 /* 3367 * **************************************************************************** 3368 * 3369 * overrideFunc 3370 * Used by cmdpars for override clis 3371 * 3372 * **************************************************************************** 3373 */ 3374 /*ARGSUSED*/ 3375 static int 3376 overrideFunc(int operandLen, char *operand[], 3377 int object, cmdOptions_t *options, 3378 void *addArgs) 3379 { 3380 int ret = 0; 3381 3382 switch (object) { 3383 case PATH: 3384 ret = overridePath(options); 3385 break; 3386 default: 3387 ret = 1; 3388 break; 3389 } 3390 3391 3392 return (ret); 3393 } 3394 3395 3396 /* 3397 * ************************************************************************* 3398 * 3399 * main 3400 * 3401 * ************************************************************************* 3402 */ 3403 int 3404 main(int argc, char *argv[]) 3405 { 3406 synTables_t synTables; 3407 char versionString[VERSION_STRING_MAX_LEN]; 3408 int ret; 3409 int funcRet; 3410 void *subcommandArgs = NULL; 3411 3412 /* set global command name */ 3413 cmdName = getExecBasename(argv[0]); 3414 3415 (void) sprintf(versionString, "%2s.%2s", 3416 VERSION_STRING_MAJOR, VERSION_STRING_MINOR); 3417 synTables.versionString = versionString; 3418 synTables.longOptionTbl = &longOptions[0]; 3419 synTables.subcommandTbl = &subcommands[0]; 3420 synTables.objectTbl = &objects[0]; 3421 synTables.objectRulesTbl = &objectRules[0]; 3422 synTables.optionRulesTbl = &optionRules[0]; 3423 3424 ret = cmdParse(argc, argv, /* SUB_COMMAND_ISSUED, */ synTables, 3425 subcommandArgs, &funcRet); 3426 if (ret == 1) { 3427 (void) fprintf(stdout, "%s %s(1M)\n", 3428 getTextString(TEXT_MORE_INFO), cmdName); 3429 return (ERROR_CLI_FAILED); 3430 } else if (ret == -1) { 3431 perror(argv[0]); 3432 return (1); 3433 } 3434 3435 if (funcRet != 0) { 3436 (void) fprintf(stderr, "%s: %s\n", 3437 argv[0], getTextString(TEXT_UNABLE_TO_COMPLETE)); 3438 return (1); 3439 } 3440 return (0); 3441 3442 } /* end main */ 3443