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