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