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.
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.
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]
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.
28 * mpathadm.c : MP API CLI program
36 #include "mpathadm_text.h"
39 #include <sys/types.h>
46 /* helper functions */
47 static char *getExecBasename(char *);
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 *);
58 #define VERSION_STRING_MAX_LEN 10
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"
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.
74 * MINOR - This should change whenever there is a new command or new feature
75 * with no incompatible change.
77 #define VERSION_STRING_MAJOR "1"
78 #define VERSION_STRING_MINOR "0"
86 * ****************************************************************************
88 * getExecBasename - copied from iscsiadm code
91 * execFullName - exec name of program (argv[0])
94 * command name portion of execFullName
96 * ****************************************************************************
99 getExecBasename(char *execFullname
)
101 char *lastSlash
, *execBasename
;
103 /* guard against '/' at end of command invocation */
105 lastSlash
= strrchr(execFullname
, '/');
106 if (lastSlash
== NULL
) {
107 execBasename
= execFullname
;
110 execBasename
= lastSlash
+ 1;
111 if (*execBasename
== '\0') {
118 return (execBasename
);
123 * Add new options here
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
},
142 * Add new subcommands here
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
},
158 object_t objects
[] = {
159 {"mpath-support", MPATH_SUPPORT
},
160 {"logical-unit", LOGICAL_UNIT
},
161 {"LU", LOGICAL_UNIT
},
162 {"initiator-port", INITIATOR_PORT
},
168 * Rules for subcommands and objects
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
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, NULL
}
196 * list of objects, subcommands, valid short options, required flag and
197 * exclusive option string
199 * If it's not here, there are no options for that object.
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
},
215 * ****************************************************************************
217 * listMpathSupport - mpathadm list mpath-support
219 * operandLen - number of operands user passed into the cli
220 * operand - pointer to operand list from user
222 * ****************************************************************************
225 listMpathSupport(int operandLen
, char *operand
[])
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 */
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
));
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
);
247 /* loop through operands first */
248 for (op
= 0; (op
< operandLen
) |
249 ((0 == operandLen
) && (B_FALSE
== shown
)); op
++) {
251 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
253 (void) memset(&pluginProps
, 0,
254 sizeof (MP_PLUGIN_PROPERTIES
));
256 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
258 if (mpstatus
!= MP_STATUS_SUCCESS
) {
259 (void) fprintf(stderr
, "%s: %s\n",
260 cmdName
, getTextString(ERR_NO_PROPERTIES
));
262 if (0 == operandLen
) {
263 /* if no operands, list them all */
264 (void) printf("%s %s\n",
266 TEXT_LB_MPATH_SUPPORT
),
267 pluginProps
.fileName
);
269 /* if there is an operand... */
270 /* ... compare and display if match */
273 pluginProps
.fileName
)) {
274 (void) printf("%s %s\n",
276 TEXT_LB_MPATH_SUPPORT
),
277 pluginProps
.fileName
);
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
),
284 /* end back-up indentation */
297 * ****************************************************************************
299 * showMpathSupport - mpathadm show mpath-support <mpath-support name>, ...
301 * operandLen - number of operands user passed into the cli
302 * operand - pointer to operand list from user
304 * ****************************************************************************
307 showMpathSupport(int operandLen
, char *operand
[])
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
;
316 MP_LOAD_BALANCE_TYPE lb
;
319 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
)) !=
321 (void) fprintf(stderr
, "%s: %s\n",
322 cmdName
, getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
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
);
331 for (op
= 0; op
< operandLen
; op
++) {
334 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
336 (void) memset(&pluginProps
, 0,
337 sizeof (MP_PLUGIN_PROPERTIES
));
339 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
341 if (MP_STATUS_SUCCESS
!= mpstatus
) {
342 (void) fprintf(stderr
, "%s: %s\n",
343 cmdName
, getTextString(ERR_NO_PROPERTIES
));
347 if (0 == operandLen
) {
348 /* if no operand, list it */
351 /* ... compare and display if match */
354 pluginProps
.fileName
)) {
359 if (B_TRUE
!= bListIt
) {
363 (void) printf("%s %s\n",
364 getTextString(TEXT_LB_MPATH_SUPPORT
),
365 pluginProps
.fileName
);
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) {
380 getTextString(TEXT_LBTYPE_NONE
));
382 displayLoadBalanceString(
383 pluginProps
.defaultloadBalanceType
);
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
));
397 if (0 != (lb
& pluginProps
.
398 supportedLoadBalanceTypes
)) {
399 (void) printf("\t\t");
400 displayLoadBalanceString(lb
&
402 supportedLoadBalanceTypes
);
406 } while (lb
< 0x80000000);
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
);
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
));
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
),
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
);
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
));
470 (void) printf("\t%s\n",
471 getTextString(TEXT_LB_SUPP_DEVICES
));
475 pluginProps
.onlySupportsSpecifiedProducts
) {
476 /* LINTED E_SEC_PRINTF_VAR_FMT */
477 (void) printf(getTextString(TEXT_ANY_DEVICE
));
479 /* if only supports specific products, */
480 /* get device product properties supported */
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 */
494 for (j
= 0; j
< deviceOidListArray
->oidCount
;
496 /* begin backup indentation */
497 (void) memset(&devProps
, 0,
498 sizeof (MP_DEVICE_PRODUCT_PROPERTIES
));
499 /* end backup indentation */
501 MP_GetDeviceProductProperties(\
502 deviceOidListArray
->oids
[j
],
503 &devProps
)) == MP_STATUS_SUCCESS
) {
505 (void) printf("\t\t%s ",
508 displayArray(devProps
.vendor
,
509 sizeof (devProps
.vendor
));
510 (void) printf("\n\t\t%s ",
513 displayArray(devProps
.product
,
514 sizeof (devProps
.product
));
515 (void) printf("\n\t\t%s ",
518 displayArray(devProps
.revision
,
519 sizeof (devProps
.revision
));
521 (void) printf("\n\t\t%s\n",
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
));
532 devProps
.supportedLoadBalanceTypes
)) {
533 (void) printf("\t\t\t");
534 displayLoadBalanceString(lb
&
535 devProps
.supportedLoadBalanceTypes
);
539 } while (lb
< 0x80000000);
541 /* end back-up indentation */
545 (void) fprintf(stderr
,
548 ERR_NO_SUPP_DEVICE_INFO
));
551 } /* if only supports specified devices */
553 } /* for each plugin */
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
),
564 } /* for each operand */
572 * ****************************************************************************
574 * modifyMpathSupport -
575 * mpathadm modify mpath-support [options] <mpath-support name>, ...
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
581 * ****************************************************************************
584 modifyMpathSupport(int operandLen
, char *operand
[], cmdOptions_t
*options
)
586 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
587 MP_PLUGIN_PROPERTIES pluginProps
;
588 MP_OID_LIST
*pPluginOidList
;
589 boolean_t bFoundIt
= B_FALSE
;
591 cmdOptions_t
*optionList
= options
;
592 char *cmdStr
= getTextString(TEXT_UNKNOWN
);
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
));
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
);
607 for (op
= 0; op
< operandLen
; op
++) {
610 (i
< pPluginOidList
->oidCount
) && (B_TRUE
!= bFoundIt
);
613 (void) memset(&pluginProps
, 0,
614 sizeof (MP_PLUGIN_PROPERTIES
));
616 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
617 &pluginProps
)) == MP_STATUS_SUCCESS
) {
619 if (0 == strcmp(operand
[op
],
620 pluginProps
.fileName
)) {
622 pluginOid
= pPluginOidList
->oids
[i
];
625 (void) fprintf(stderr
, "%s: %s\n",
626 cmdName
, getTextString(ERR_NO_PROPERTIES
));
629 if (B_FALSE
== bFoundIt
) {
633 /* begin back-up indentation */
634 /* we found the plugin oid */
635 /* now change the options requested */
636 switch (optionList
->optval
) {
638 /* modify autofailback */
639 cmdStr
= getTextString(TEXT_AUTO_FAILBACK
);
640 if (0 == strcasecmp(optionList
->optarg
,
641 getTextString(TEXT_ON
))) {
643 MP_EnableAutoFailback(pluginOid
);
645 strcasecmp(optionList
->optarg
,
646 getTextString(TEXT_OFF
))) {
648 MP_DisableAutoFailback(pluginOid
);
650 /* LINTED E_SEC_PRINTF_VAR_FMT */
651 (void) fprintf(stderr
, getTextString(
652 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
654 getTextString(TEXT_ILLEGAL_ARGUMENT
));
656 return (ERROR_CLI_FAILED
);
660 /* modify autoprobing */
661 cmdStr
= getTextString(TEXT_AUTO_PROBING
);
662 if (0 == strcasecmp(optionList
->optarg
,
663 getTextString(TEXT_ON
))) {
665 MP_EnableAutoProbing(pluginOid
);
667 strcasecmp(optionList
->optarg
,
668 getTextString(TEXT_OFF
))) {
670 MP_DisableAutoProbing(pluginOid
);
672 /* LINTED E_SEC_PRINTF_VAR_FMT */
673 (void) fprintf(stderr
, getTextString(
674 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
676 getTextString(TEXT_ILLEGAL_ARGUMENT
));
678 return (ERROR_CLI_FAILED
);
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
);
688 MP_SetPluginLoadBalanceType(pluginOid
,
693 if (MP_STATUS_SUCCESS
!= mpstatus
) {
694 /* LINTED E_SEC_PRINTF_VAR_FMT */
695 (void) fprintf(stderr
,
697 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
698 cmdStr
, getMpStatusStr(mpstatus
));
702 /* end back-up indentation */
704 } /* for each plugin */
706 if (B_FALSE
== bFoundIt
) {
707 /* LINTED E_SEC_PRINTF_VAR_FMT */
708 (void) fprintf(stderr
,
710 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
712 getTextString(TEXT_MPATH_SUPPORT_NOT_FOUND
));
714 return (ERROR_CLI_FAILED
);
717 } /* for each operand */
724 * ****************************************************************************
727 * mpathadm list {logical-unit | LU} [options] [<logical-unit name>, ...]
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
733 * ****************************************************************************
736 listLogicalUnit(int operandLen
, char *operand
[], cmdOptions_t
*options
)
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
;
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
;
751 /* count number of options */
752 for (; optionList
->optval
; optionList
++) {
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
);
763 /* list to keep track of multiple options */
764 optionList
= options
;
765 for (opIndex
= 0; opIndex
< opListCount
; opIndex
++) {
766 bFoundOption
[opIndex
] = B_FALSE
;
769 optionList
= options
;
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
));
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
);
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
));
791 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
792 &pluginProps
)) != MP_STATUS_SUCCESS
) {
793 (void) fprintf(stderr
, "%s: %s\n",
794 cmdName
, getTextString(ERR_NO_PROPERTIES
));
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
));
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 */
814 MP_GetMPLogicalUnitProperties(
815 pLogicalUnitOidList
->oids
[lu
],
817 if (mpstatus
!= MP_STATUS_SUCCESS
) {
818 (void) fprintf(stderr
, "%s: %s\n",
820 getTextString(ERR_NO_PROPERTIES
));
824 luOid
= pLogicalUnitOidList
->oids
[lu
];
825 if (listIndividualLogicalUnit(luOid
, luProps
)
827 return (ERROR_CLI_FAILED
);
830 } /* for each plugin */
831 } else { /* we have operands and/or options */
833 /* check if we have operands */
834 if (0 == operandLen
) {
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
));
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
);
857 for (opoffset
= opStart
; opoffset
< opEnd
; opoffset
++) {
858 /* loop through operands */
859 bFoundOperand
= B_FALSE
;
861 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
864 * loop through plugin, and get properties
865 * so we can list the name
867 (void) memset(&pluginProps
, 0,
868 sizeof (MP_PLUGIN_PROPERTIES
));
870 MP_GetPluginProperties(
871 pPluginOidList
->oids
[i
], &pluginProps
))
872 != MP_STATUS_SUCCESS
) {
873 (void) fprintf(stderr
, "%s: %s\n",
875 getTextString(ERR_NO_PROPERTIES
));
879 /* attempt to find this logical unit */
881 MP_GetMultipathLus(pPluginOidList
->oids
[i
],
882 &pLogicalUnitOidList
);
883 if (mpstatus
!= MP_STATUS_SUCCESS
) {
884 (void) fprintf(stderr
, "%s: %s\n",
886 getTextString(ERR_NO_LU_LIST
));
891 (lu
< pLogicalUnitOidList
->oidCount
);
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 */
900 MP_GetMPLogicalUnitProperties(
901 pLogicalUnitOidList
->oids
[lu
],
903 if (mpstatus
!= MP_STATUS_SUCCESS
) {
904 (void) fprintf(stderr
,
912 * compare operand - is it a match?
917 if (operandLen
> 0) {
921 luProps
.deviceFileName
);
924 if (B_TRUE
== bContinue
) {
926 if (0 != opListCount
) {
930 /* begin backup indentation */
931 optionList
= options
;
933 for (opIndex
= 0; optionList
->optval
; optionList
++, opIndex
++) {
934 switch (optionList
->optval
) {
937 compareLUName(optionList
->optarg
, luProps
.name
)) {
939 bFoundOperand
= B_TRUE
;
940 bFoundOption
[opIndex
] = B_TRUE
;
946 MP_GetAssociatedTPGOidList(pLogicalUnitOidList
->oids
[lu
],
948 if (mpstatus
!= MP_STATUS_SUCCESS
) {
949 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
950 getTextString(ERR_NO_ASSOC_TPGS
));
954 /* get target ports */
956 (NULL
!= pTpgOidListArray
) &&
957 (tpg
< pTpgOidListArray
->oidCount
) &&
958 (B_FALSE
== bListIt
); tpg
++) {
960 MP_GetTargetPortOidList(pTpgOidListArray
->oids
[tpg
],
961 &pTportOidListArray
);
962 if (mpstatus
!= MP_STATUS_SUCCESS
) {
963 (void) fprintf(stderr
, "%s: %s\n",
965 getTextString(ERR_NO_ASSOC_TPORTS
));
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
));
976 MP_GetTargetPortProperties(
977 pTportOidListArray
->oids
[j
], &tportProps
);
978 if (mpstatus
!= MP_STATUS_SUCCESS
) {
979 (void) fprintf(stderr
, "%s: %s\n",
981 getTextString(ERR_NO_PROPERTIES
));
987 if (0 == strcmp(optionList
->optarg
,
988 tportProps
.portID
)) {
990 bFoundOperand
= B_TRUE
;
991 bFoundOption
[opIndex
] = B_TRUE
;
993 } /* for each target port */
996 } /* loop through options */
997 /* end back-up indentation */
1005 bFoundOperand
= B_TRUE
;
1007 } /* end bContinue check */
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
)
1016 return (ERROR_CLI_FAILED
);
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
,
1029 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1031 (void) fprintf(stderr
, "\n");
1035 optionList
= options
;
1036 for (opIndex
= 0; optionList
->optval
; optionList
++,
1038 if (B_FALSE
== bFoundOption
[opIndex
]) {
1039 /* LINTED E_SEC_PRINTF_VAR_FMT */
1040 (void) fprintf(stderr
,
1042 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1043 optionList
->optarg
);
1044 (void) fprintf(stderr
, "\n");
1050 } /* end loop through operands */
1051 } /* we have operands and/or options */
1059 * ****************************************************************************
1062 * compare names directly and via devid if no match directly
1064 * cmpString - first string to compare
1065 * deviceProperty - string from properties
1066 * sizeToCompare - size of deviceProperty
1068 * returns B_TRUE if the strings match either directly or via devid
1071 * ****************************************************************************
1074 compareLUName(MP_CHAR
*cmpString
, MP_CHAR
*deviceProperty
)
1077 boolean_t isSame
= B_FALSE
;
1079 ddi_devid_t devid1
= NULL
, devid2
= NULL
;
1081 if (0 == strcmp(cmpString
, deviceProperty
)) {
1084 /* user input didn't match, try via devid */
1086 * I don't see a reason to print the error for
1087 * any of these since they'll get the error at
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
))) {
1098 (devid_compare(devid1
, devid2
))) {
1103 if (NULL
!= devid1
) {
1106 if (NULL
!= devid2
) {
1123 * ****************************************************************************
1125 * listIndivudualLogicalUnit -
1126 * Used by list logical unit cli.
1127 * Displays info about an LU
1129 * luOid - LU to list
1130 * luProps - properties of the LU to list
1132 * ****************************************************************************
1135 listIndividualLogicalUnit(MP_OID luOid
,
1136 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
)
1138 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps
;
1139 MP_OID_LIST
*pPathOidListArray
;
1140 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1141 int numOperationalPaths
, pa
;
1143 (void) printf("\t");
1144 displayArray(luProps
.deviceFileName
, sizeof (luProps
.deviceFileName
));
1145 (void) printf("\n");
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");
1158 (void) printf("\t\t%s %d\n",
1159 getTextString(TEXT_LB_PATH_COUNT
), pPathOidListArray
->oidCount
);
1161 numOperationalPaths
= 0;
1162 for (pa
= 0; pa
< pPathOidListArray
->oidCount
; pa
++) {
1163 (void) memset(&pathProps
, 0,
1164 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES
));
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
));
1174 /* cycle through and check status of each for */
1175 /* operation path count */
1176 if (MP_PATH_STATE_OKAY
== pathProps
.pathState
) {
1177 numOperationalPaths
++;
1181 (void) printf("\t\t%s %d\n",
1182 getTextString(TEXT_LB_OP_PATH_COUNT
), numOperationalPaths
);
1189 * ****************************************************************************
1192 * mpathadm show {logical-unit | LU} <logical-unit name>, ...
1194 * operandLen - number of operands user passed into the cli
1195 * operand - pointer to operand list from user
1197 * ****************************************************************************
1200 showLogicalUnit(int operandLen
, char *operand
[])
1202 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1203 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
1204 MP_PLUGIN_PROPERTIES pluginProps
;
1205 MP_OID luOid
, pluginOid
;
1209 for (op
= 0; op
< operandLen
; op
++) {
1211 (void) printf("\n");
1213 if (B_TRUE
== getLogicalUnitOid(operand
[op
], &luOid
)) {
1214 (void) memset(&luProps
, 0,
1215 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
1217 MP_GetMPLogicalUnitProperties(
1219 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1220 (void) fprintf(stderr
, "%s: %s\n",
1221 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1226 MP_GetAssociatedPluginOid(luOid
, &pluginOid
);
1227 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1228 (void) fprintf(stderr
, "%s: %s\n",
1230 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1235 MP_GetPluginProperties(pluginOid
, &pluginProps
);
1236 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1237 (void) fprintf(stderr
, "%s: %s\n",
1238 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1242 if (showIndividualLogicalUnit(luOid
, luProps
,
1243 pluginProps
) != 0) {
1244 return (ERROR_CLI_FAILED
);
1248 /* LINTED E_SEC_PRINTF_VAR_FMT */
1249 (void) fprintf(stderr
, getTextString(
1250 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1252 (void) printf("\n");
1255 } /* for each operand */
1262 * ****************************************************************************
1264 * showIndivudualLogicalUnit -
1265 * Used by show logical unit cli.
1266 * Displays info about an LU
1268 * luOid - LU to show
1269 * luProps - properties of the LU to show
1270 * pluginProps - propertis of the plugin this LU belongs to
1272 * ****************************************************************************
1275 showIndividualLogicalUnit(MP_OID luOid
,
1276 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
,
1277 MP_PLUGIN_PROPERTIES pluginProps
)
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
;
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
);
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
));
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
));
1318 displayLoadBalanceString(luProps
.currentLoadBalanceType
);
1320 (void) printf("\n");
1322 (void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID
));
1323 if (0xffffffff == luProps
.logicalUnitGroupID
) {
1324 (void) printf("%s\n", getTextString(TEXT_NA
));
1326 (void) printf("0x%x\n", luProps
.logicalUnitGroupID
);
1329 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB
));
1330 if (MP_FALSE
== pluginProps
.autoFailbackSupport
) {
1331 (void) printf("%s\n", getTextString(TEXT_NA
));
1333 (void) printf("%s\n", (MP_TRUE
== luProps
.autoFailbackEnabled
)?
1334 getTextString(TEXT_ON
):getTextString(TEXT_OFF
));
1337 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB
));
1338 if (MP_FALSE
== pluginProps
.autoProbingSupport
) {
1339 (void) printf("%s\n", getTextString(TEXT_NA
));
1341 (void) printf("%s\n", (MP_TRUE
== luProps
.autoProbingEnabled
)?
1342 getTextString(TEXT_ON
):getTextString(TEXT_OFF
));
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");
1357 (void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO
));
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
));
1370 (void) printf("\t\t%s ",
1371 getTextString(TEXT_LB_INIT_PORT_NAME
));
1373 MP_GetInitiatorPortProperties(pathProps
.initiatorPortOid
,
1374 &initProps
)) != MP_STATUS_SUCCESS
) {
1375 (void) printf("%s\n", getTextString(TEXT_UNKNOWN
));
1377 displayArray(initProps
.portID
,
1378 sizeof (initProps
.portID
));
1379 (void) printf("\n");
1382 (void) printf("\t\t%s ",
1383 getTextString(TEXT_LB_TARGET_PORT_NAME
));
1385 MP_GetTargetPortProperties(pathProps
.targetPortOid
,
1386 &tportProps
)) != MP_STATUS_SUCCESS
) {
1387 (void) printf("%s\n", getTextString(TEXT_UNKNOWN
));
1389 displayArray(tportProps
.portID
,
1390 sizeof (tportProps
.portID
));
1391 (void) printf("\n");
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
));
1401 (void) printf("%s\n", getTextString(TEXT_NO
));
1404 (void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE
),
1405 getPathStateStr(pathProps
.pathState
));
1407 (void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED
),
1408 pathProps
.disabled
?getTextString(TEXT_YES
):
1409 getTextString(TEXT_NO
));
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
));
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
));
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
));
1434 /* display tpg info only if is assymetric */
1436 (void) printf("\n");
1438 if (MP_TRUE
== luProps
.asymmetric
) {
1439 (void) printf("\t\t%s %d\n",
1440 getTextString(TEXT_LB_ID
),
1442 (void) printf("\t\t%s %s\n",
1444 TEXT_LB_EXPLICIT_FAILOVER
),
1446 tpgProps
.explicitFailover
)?
1447 getTextString(TEXT_YES
):
1448 getTextString(TEXT_NO
));
1449 (void) printf("\t\t%s %s\n",
1451 TEXT_LB_ACCESS_STATE
),
1453 tpgProps
.accessState
));
1454 /* display label for each tpg. */
1455 (void) printf("\t\t%s\n",
1456 getTextString(TEXT_TPORT_LIST
));
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 */
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",
1475 getTextString(ERR_NO_ASSOC_TPORTS
));
1478 /* begin back-up indentation */
1479 for (tport
= 0; tport
< pTportOidListArray
->oidCount
; tport
++) {
1480 (void) memset(&tportProps
, 0,
1481 sizeof (MP_TARGET_PORT_PROPERTIES
));
1483 MP_GetTargetPortProperties(pTportOidListArray
->oids
[tport
],
1484 &tportProps
)) != MP_STATUS_SUCCESS
) {
1485 (void) fprintf(stderr
, "%s: %s",
1486 cmdName
, getTextString(ERR_NO_PROPERTIES
));
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
);
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
);
1505 /* insert blank line if not the last target port. */
1506 if (!(tport
== (pTportOidListArray
->oidCount
- 1))) {
1507 (void) printf("\n");
1510 } /* for each target port */
1511 /* end back-up indentation */
1513 } /* else got target port props */
1514 } /* else got TPG props */
1515 } /* for each TPG */
1516 } /* else got tpg list */
1524 * ****************************************************************************
1526 * modifyLogicalUnit -
1527 * mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ...
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
1533 * ****************************************************************************
1536 modifyLogicalUnit(int operandLen
, char *operand
[], cmdOptions_t
*options
)
1538 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1540 cmdOptions_t
*optionList
= options
;
1541 char *cmdStr
= getTextString(TEXT_UNKNOWN
);
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
),
1550 (void) printf("\n");
1551 return (ERROR_CLI_FAILED
);
1554 /* we found the lu oid, now change the options requested */
1555 switch (optionList
->optval
) {
1557 /* modify autofailback */
1558 cmdStr
= getTextString(TEXT_AUTO_FAILBACK
);
1559 if (0 == strcasecmp(optionList
->optarg
,
1560 getTextString(TEXT_ON
))) {
1562 MP_EnableAutoFailback(luOid
);
1563 } else if (0 == strcasecmp(optionList
->optarg
,
1564 getTextString(TEXT_OFF
))) {
1566 MP_DisableAutoFailback(luOid
);
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 */
1580 /* modify autoprobing */
1581 cmdStr
= getTextString(TEXT_AUTO_PROBING
);
1582 if (0 == strcasecmp(optionList
->optarg
,
1583 getTextString(TEXT_ON
))) {
1585 MP_EnableAutoProbing(luOid
);
1586 } else if (0 == strcasecmp(optionList
->optarg
,
1587 getTextString(TEXT_OFF
))) {
1589 MP_DisableAutoProbing(luOid
);
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 */
1603 /* modify loadbalance type */
1604 cmdStr
= getTextString(TEXT_LOAD_BALANCE
);
1606 MP_SetLogicalUnitLoadBalanceType(luOid
,
1607 getLbValueFromString(optionList
->optarg
));
1611 if (MP_STATUS_SUCCESS
!= mpstatus
) {
1612 /* LINTED E_SEC_PRINTF_VAR_FMT */
1613 (void) fprintf(stderr
,
1615 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
1616 cmdStr
, getMpStatusStr(mpstatus
));
1617 (void) printf("\n");
1618 return (ERROR_CLI_FAILED
);
1620 } /* for each operand */
1626 * ****************************************************************************
1628 * failoverLogicalUnit -
1629 * mpathadm failover {logical-unit | LU} <logical-unit name>, ...
1631 * operand - pointer to operand list from user
1633 * ****************************************************************************
1636 failoverLogicalUnit(char *operand
[])
1638 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
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
;
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
),
1653 (void) printf("\n");
1654 return (ERROR_CLI_FAILED
);
1657 /* get LUN properties and check to be sure it's asymmetric */
1658 (void) memset(&luProps
, 0,
1659 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
1661 MP_GetMPLogicalUnitProperties(luOid
, &luProps
);
1662 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1663 (void) fprintf(stderr
, "%s: %s\n",
1664 cmdName
, getTextString(ERR_NO_PROPERTIES
));
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
);
1674 /* get TPGs for this LUN */
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
));
1683 /* pick a TPG whose state is active or standby, and change it */
1684 /* to opposite via MP_SetTPGAccessState */
1686 for (tpg
= 0; tpg
< pTpgOidListArray
->oidCount
; tpg
++) {
1687 (void) memset(&tpgProps
, 0,
1688 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES
));
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
);
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
);
1703 /* find one that is standby */
1704 if ((MP_ACCESS_STATE_STANDBY
==
1705 tpgProps
.accessState
) && (B_FALSE
== bFoundIt
)) {
1709 tpgStatePair
.tpgOid
=
1710 pTpgOidListArray
->oids
[tpg
];
1711 tpgStatePair
.desiredState
=
1712 MP_ACCESS_STATE_ACTIVE
;
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");
1723 /* end back-up indentation */
1728 } /* for each tpg */
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
);
1741 * ****************************************************************************
1743 * getLogicalUnitOid -
1744 * Search through all plugins and get the OID for specified logical unit
1746 * luFileName - file name of LU (specified by the user) to find
1747 * pLuOid - OID to return
1749 * ****************************************************************************
1752 getLogicalUnitOid(MP_CHAR
*luFileName
, MP_OID
*pluOid
)
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
;
1763 ddi_devid_t devid1
, devid2
;
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");
1773 pluOid
->objectSequenceNumber
= 0;
1774 pluOid
->objectType
= 0;
1775 pluOid
->ownerId
= 0;
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
));
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
);
1788 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
1790 /* get properties so we can list the name */
1791 (void) memset(&pluginProps
, 0, sizeof (MP_PLUGIN_PROPERTIES
));
1793 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
1794 &pluginProps
)) != MP_STATUS_SUCCESS
) {
1795 (void) fprintf(stderr
, "%s: %s\n",
1796 cmdName
, getTextString(ERR_NO_PROPERTIES
));
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
));
1809 for (lu
= 0; (lu
< pLogicalUnitOidList
->oidCount
) &&
1810 (B_FALSE
== foundIt
); lu
++) {
1812 /* get lu properties so we can check the name */
1813 (void) memset(&luProps
, 0,
1814 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
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
));
1824 if (compareLUName(luFileName
, luProps
.deviceFileName
)
1828 /* user input didn't match, try via devid */
1830 * I don't see a reason to print the error for
1831 * any of these since they'll get the error at
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
))) {
1845 (devid_compare(devid1
, devid2
))) {
1850 if (NULL
!= devid1
) {
1853 if (NULL
!= devid2
) {
1864 if (B_TRUE
== foundIt
) {
1865 pluOid
->objectSequenceNumber
=
1866 pLogicalUnitOidList
->
1867 oids
[lu
].objectSequenceNumber
;
1868 pluOid
->objectType
=
1869 pLogicalUnitOidList
->
1870 oids
[lu
].objectType
;
1872 pLogicalUnitOidList
->oids
[lu
].ownerId
;
1882 * ****************************************************************************
1884 * listInitiatorPort -
1885 * mpathadm list initiator-port [<initiator-port name>, ...]
1887 * operandLen - number of operands user passed into the cli
1888 * operand - pointer to operand list from user
1890 * ****************************************************************************
1893 listInitiatorPort(int operandLen
, char *operand
[])
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
;
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
);
1910 for (ol
= 0; ol
< operandLen
; ol
++) {
1911 foundOp
[ol
] = B_FALSE
;
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
));
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
);
1926 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
1928 MP_GetInitiatorPortOidList(pPluginOidList
->oids
[i
],
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
));
1942 iport
< pInitOidList
->oidCount
; iport
++) {
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
));
1952 /* if no operands listed, */
1953 /* list all we find */
1954 if (0 == operandLen
) {
1958 /* check each operand */
1960 /* the one we want to list? */
1962 ol
< operandLen
; ol
++) {
1976 if (B_TRUE
== bListIt
) {
1978 if (listIndividualInitiatorPort(
1980 return (ERROR_CLI_FAILED
);
1985 } /* for each initiator port */
1986 } /* else found an init port */
1988 } /* for each plugin */
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
),
1996 (void) printf("\n");
2005 * ****************************************************************************
2007 * listIndividualInitiatorPort -
2008 * used by listInitiatorPort to list info for one init port
2010 * initProps - properties of initiator port to list
2012 * ****************************************************************************
2015 listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps
)
2017 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2019 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT
));
2020 displayArray(initProps
.portID
,
2021 sizeof (initProps
.portID
));
2022 (void) printf("\n");
2030 * ****************************************************************************
2032 * showInitiatorPort -
2033 * mpathadm show initiator-port <initiator-port name>, ...
2035 * operandLen - number of operands user passed into the cli
2036 * operand - pointer to operand list from user
2038 * ****************************************************************************
2041 showInitiatorPort(int operandLen
, char *operand
[])
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
;
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
));
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
);
2061 for (op
= 0; op
< operandLen
; op
++) {
2064 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
2067 MP_GetInitiatorPortOidList(pPluginOidList
->oids
[i
],
2069 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2070 /* LINTED E_SEC_PRINTF_VAR_FMT */
2071 (void) fprintf(stderr
,
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
));
2083 iport
< pInitOidList
->oidCount
;
2088 MP_GetInitiatorPortProperties(
2089 pInitOidList
->oids
[iport
],
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 */
2098 if (0 == strcmp(operand
[op
],
2099 initProps
.portID
)) {
2105 if (B_TRUE
== bListIt
) {
2107 showIndividualInitiatorPort(
2109 if (0 != mpstatus
) {
2115 } /* for each initiator port */
2116 } /* else found an init port */
2118 } /* for each plugin */
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
),
2127 (void) printf("\n");
2130 } /* for each operand */
2137 * ****************************************************************************
2139 * showIndividualInitiatorPort -
2140 * used by showInitiatorPort to show info for one init port
2142 * initProps - properties of initiator port to show
2144 * ****************************************************************************
2147 showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps
)
2149 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2151 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT
));
2152 displayArray(initProps
.portID
,
2153 sizeof (initProps
.portID
));
2155 (void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE
));
2156 displayTransportTypeString(initProps
.portType
);
2157 (void) printf("\n");
2159 (void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE
));
2160 displayArray(initProps
.osDeviceFile
,
2161 sizeof (initProps
.osDeviceFile
));
2162 (void) printf("\n");
2169 * ****************************************************************************
2172 * mpathadm enable path -i <initiator-port>
2173 * -t <target-port name> -l <logical-unit name>
2175 * options - pointer to option list from user
2177 * ****************************************************************************
2180 enablePath(cmdOptions_t
*options
)
2182 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2185 cmdOptions_t
*optionList
= options
;
2186 boolean_t bHaveInit
= B_FALSE
, bHaveTarg
= B_FALSE
, bHaveLu
= B_FALSE
;
2188 for (; optionList
->optval
; optionList
++) {
2189 switch (optionList
->optval
) {
2191 /* have init port name */
2195 /* have target port id */
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
);
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
);
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");
2252 * ****************************************************************************
2255 * mpathadm disable path -i <initiator-port>
2256 * -t <target-port name> -l <logical-unit name>
2258 * options - pointer to option list from user
2260 * ****************************************************************************
2263 disablePath(cmdOptions_t
*options
)
2265 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2268 cmdOptions_t
*optionList
= options
;
2269 boolean_t bHaveInit
= B_FALSE
, bHaveTarg
= B_FALSE
,
2272 for (; optionList
->optval
; optionList
++) {
2273 switch (optionList
->optval
) {
2275 /* have init port name */
2279 /* have target port id */
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
);
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
);
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");
2337 * ****************************************************************************
2340 * mpathadm override path {-i <initiator-port>
2341 * -t <target-port name> | -c} <logical-unit name>
2343 * options - pointer to option list from user
2345 * ****************************************************************************
2348 overridePath(cmdOptions_t
*options
)
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
;
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
) {
2361 /* we have a cancel */
2362 bCancelOverride
= B_TRUE
;
2365 /* we have a lun- save it while we're here */
2366 (void) memcpy(pLuDeviceFileName
,
2367 optionList
->optarg
, 256);
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
,
2378 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON
),
2379 getTextString(LU_NOT_FOUND
));
2380 (void) printf("\n");
2381 return (ERROR_CLI_FAILED
);
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
,
2390 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON
),
2391 getMpStatusStr(mpstatus
));
2392 (void) printf("\n");
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
,
2401 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2402 getTextString(LU_NOT_FOUND
));
2403 (void) printf("\n");
2404 return (ERROR_CLI_FAILED
);
2407 if (B_FALSE
== getPathOid(options
, &pathOid
)) {
2408 /* LINTED E_SEC_PRINTF_VAR_FMT */
2409 (void) fprintf(stderr
,
2411 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2412 getTextString(FAILED_TO_FIND_PATH
));
2414 (void) printf("\n");
2415 return (ERROR_CLI_FAILED
);
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
,
2424 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2425 getMpStatusStr(mpstatus
));
2426 (void) printf("\n");
2436 * ****************************************************************************
2439 * Search through all plugins and get the OID for specified path
2441 * operand - pointer to operand list from user
2442 * options - pointer to option list from user
2444 * ****************************************************************************
2447 getPathOid(cmdOptions_t
*options
, MP_OID
*pPathOid
)
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
;
2455 MP_OID_LIST
*pPluginOidList
, *pLogicalUnitOidList
,
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
;
2467 if (NULL
== pPathOid
) {
2471 for (; optionList
->optval
; optionList
++) {
2472 switch (optionList
->optval
) {
2474 /* save init port name */
2475 (void) memcpy(initPortID
,
2476 optionList
->optarg
, 256);
2480 /* save target port id */
2481 (void) memcpy(targetPortID
,
2482 optionList
->optarg
, 256);
2487 (void) memcpy(luDeviceFileName
,
2488 optionList
->optarg
, 256);
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 */
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
));
2510 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
2511 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2512 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
2516 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
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
));
2527 for (lu
= 0; (lu
< pLogicalUnitOidList
->oidCount
) &&
2528 (B_FALSE
== bFoundIt
); lu
++) {
2530 /* get lu properties so we can check the name */
2531 (void) memset(&luProps
, 0,
2532 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
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
));
2541 if (compareLUName(luDeviceFileName
,
2542 luProps
.deviceFileName
) == B_TRUE
) {
2543 /* get paths for this LU and search from here */
2545 MP_GetAssociatedPathOidList(
2546 pLogicalUnitOidList
->oids
[lu
],
2548 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2549 /* LINTED E_SEC_PRINTF_VAR_FMT */
2550 (void) fprintf(stderr
,
2552 ERR_FAILED_TO_FIND_PATH
));
2553 (void) printf("\n");
2558 (pa
< pathOidListArray
->oidCount
) &&
2559 (B_FALSE
== bFoundIt
); pa
++) {
2561 MP_GetPathLogicalUnitProperties
2562 (pathOidListArray
->oids
[pa
],
2564 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2565 (void) fprintf(stderr
,
2566 "%s: %s\n", cmdName
,
2568 ERR_NO_PROPERTIES
));
2573 * get properties of iniator port and
2574 * target port to see if we have the
2578 MP_GetInitiatorPortProperties(
2579 pathProps
.initiatorPortOid
,
2582 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2583 (void) fprintf(stderr
,
2584 "%s: %s\n", cmdName
,
2586 ERR_NO_PROPERTIES
));
2589 if (0 == strcmp(initPortID
, initProps
.portID
)) {
2590 /* lu and init port matches, check target port */
2591 mpstatus
= MP_GetTargetPortProperties(pathProps
.targetPortOid
,
2593 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2594 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2595 getTextString(ERR_NO_PROPERTIES
));
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
;
2608 } /* init port matched */
2610 } /* for each path associated with this lu */
2616 } /* for each plugin */
2623 * ****************************************************************************
2625 * getLbValueFromString
2626 * Gets the MP_LOAD_BALANCE_TYPE specified load balance type string
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.
2632 * ****************************************************************************
2634 MP_LOAD_BALANCE_TYPE
2635 getLbValueFromString(char *lbStr
)
2637 MP_LOAD_BALANCE_TYPE lbVal
= MP_LOAD_BALANCE_TYPE_UNKNOWN
;
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
))) {
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;
2709 } /* end getLbValueFromString */
2713 * ****************************************************************************
2715 * displayLogicalUnitNameTypeString
2716 * Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE
2717 * specified load balance type
2719 * typeVal - load balance type defined in the MPAPI spec
2721 * ****************************************************************************
2724 displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal
)
2731 case MP_LU_NAME_TYPE_UNKNOWN
:
2732 typeString
= getTextString(TEXT_NAME_TYPE_UNKNOWN
);
2734 case MP_LU_NAME_TYPE_VPD83_TYPE1
:
2735 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE1
);
2737 case MP_LU_NAME_TYPE_VPD83_TYPE2
:
2738 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE2
);
2740 case MP_LU_NAME_TYPE_VPD83_TYPE3
:
2741 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE3
);
2743 case MP_LU_NAME_TYPE_DEVICE_SPECIFIC
:
2745 getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC
);
2748 typeString
= getTextString(TEXT_UNKNOWN
);
2752 (void) printf("%s", typeString
);
2755 } /* end displayLogicalUnitNameTypeString */
2758 * ****************************************************************************
2760 * displayLoadBalanceString
2761 * Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE
2762 * specified load balance type
2764 * lbVal - load balance type defined in the MPAPI spec
2766 * ****************************************************************************
2769 displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal
)
2776 case MP_LOAD_BALANCE_TYPE_UNKNOWN
:
2777 lbString
= getTextString(TEXT_LBTYPE_UNKNOWN
);
2779 case MP_LOAD_BALANCE_TYPE_ROUNDROBIN
:
2780 lbString
= getTextString(TEXT_LBTYPE_ROUNDROBIN
);
2782 case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS
:
2783 lbString
= getTextString(TEXT_LBTYPE_LEASTBLOCKS
);
2785 case MP_LOAD_BALANCE_TYPE_LEASTIO
:
2786 lbString
= getTextString(TEXT_LBTYPE_LEASTIO
);
2788 case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT
:
2789 lbString
= getTextString(TEXT_LBTYPE_DEVICEPROD
);
2791 case MP_LOAD_BALANCE_TYPE_LBA_REGION
:
2792 lbString
= getTextString(TEXT_LBTYPE_LBAREGION
);
2794 case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY
:
2795 lbString
= getTextString(TEXT_LBTYPE_FAILOVER_ONLY
);
2797 case (((MP_UINT32
)0x00000001)<<16):
2798 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY1
);
2800 case (((MP_UINT32
)0x00000001)<<17):
2801 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY2
);
2803 case (((MP_UINT32
)0x00000001)<<18):
2804 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY3
);
2806 case (((MP_UINT32
)0x00000001)<<19):
2807 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY4
);
2809 case (((MP_UINT32
)0x00000001)<<20):
2810 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY5
);
2812 case (((MP_UINT32
)0x00000001)<<21):
2813 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY6
);
2815 case (((MP_UINT32
)0x00000001)<<22):
2816 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY7
);
2818 case (((MP_UINT32
)0x00000001)<<23):
2819 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY8
);
2821 case (((MP_UINT32
)0x00000001)<<24):
2822 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY9
);
2824 case (((MP_UINT32
)0x00000001)<<25):
2825 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY10
);
2827 case (((MP_UINT32
)0x00000001)<<26):
2828 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY11
);
2830 case (((MP_UINT32
)0x00000001)<<27):
2831 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY12
);
2833 case (((MP_UINT32
)0x00000001)<<28):
2834 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY13
);
2836 case (((MP_UINT32
)0x00000001)<<29):
2837 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY14
);
2839 case (((MP_UINT32
)0x00000001)<<30):
2840 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY15
);
2842 case (((MP_UINT32
)0x00000001)<<31):
2843 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY16
);
2846 lbString
= getTextString(TEXT_UNKNOWN
);
2850 (void) printf("%s", lbString
);
2853 } /* end displayLoadBalanceString */
2856 * ****************************************************************************
2858 * displayTransportTypeString
2859 * Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE
2860 * specified load balance type
2862 * transportTypeVal - transport type defined in the MPAPI spec
2864 * ****************************************************************************
2867 displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal
)
2871 switch (transportTypeVal
) {
2873 case MP_PORT_TRANSPORT_TYPE_MPNODE
:
2875 getTextString(TEXT_TRANS_PORT_TYPE_MPNODE
);
2877 case MP_PORT_TRANSPORT_TYPE_FC
:
2878 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_FC
);
2880 case MP_PORT_TRANSPORT_TYPE_SPI
:
2881 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_SPI
);
2883 case MP_PORT_TRANSPORT_TYPE_ISCSI
:
2884 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_ISCSI
);
2886 case MP_PORT_TRANSPORT_TYPE_IFB
:
2887 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_IFB
);
2890 ttypeString
= getTextString(TEXT_UNKNOWN
);
2894 (void) printf("%s", ttypeString
);
2896 } /* end displayTransportTypeString */
2900 * ****************************************************************************
2903 * Gets the string description for the specified load balance type value
2905 * mpstatus - MP_STATUS value
2907 * ****************************************************************************
2910 getMpStatusStr(MP_STATUS mpstatus
)
2915 case MP_STATUS_SUCCESS
:
2916 statString
= getTextString(TEXT_MPSTATUS_SUCCESS
);
2918 case MP_STATUS_INVALID_PARAMETER
:
2919 statString
= getTextString(TEXT_MPSTATUS_INV_PARAMETER
);
2921 case MP_STATUS_UNKNOWN_FN
:
2922 statString
= getTextString(TEXT_MPSTATUS_UNKNOWN_FN
);
2924 case MP_STATUS_FAILED
:
2925 statString
= getTextString(TEXT_MPSTATUS_FAILED
);
2927 case MP_STATUS_INSUFFICIENT_MEMORY
:
2928 statString
= getTextString(TEXT_MPSTATUS_INSUFF_MEMORY
);
2930 case MP_STATUS_INVALID_OBJECT_TYPE
:
2931 statString
= getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE
);
2933 case MP_STATUS_UNSUPPORTED
:
2934 statString
= getTextString(TEXT_MPSTATUS_UNSUPPORTED
);
2936 case MP_STATUS_OBJECT_NOT_FOUND
:
2937 statString
= getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND
);
2939 case MP_STATUS_ACCESS_STATE_INVALID
:
2940 statString
= getTextString(TEXT_MPSTATUS_UNSUPPORTED
);
2942 case MP_STATUS_FN_REPLACED
:
2943 statString
= getTextString(TEXT_MPSTATUS_FN_REPLACED
);
2945 case MP_STATUS_PATH_NONOPERATIONAL
:
2946 statString
= getTextString(TEXT_MPSTATUS_PATH_NONOP
);
2948 case MP_STATUS_TRY_AGAIN
:
2949 statString
= getTextString(TEXT_MPSTATUS_TRY_AGAIN
);
2951 case MP_STATUS_NOT_PERMITTED
:
2952 statString
= getTextString(TEXT_MPSTATUS_NOT_PERMITTED
);
2955 statString
= getTextString(TEXT_UNKNOWN
);
2959 return (statString
);
2960 } /* end getMpStatusStr */
2964 * ****************************************************************************
2967 * Gets the string description for the specified path state type value
2969 * pathState - MP_PATH_STATE values
2971 * ****************************************************************************
2974 getPathStateStr(MP_PATH_STATE pathState
)
2978 switch (pathState
) {
2979 case MP_PATH_STATE_OKAY
:
2980 pathString
= getTextString(TEXT_PATH_STATE_OKAY
);
2982 case MP_PATH_STATE_PATH_ERR
:
2983 pathString
= getTextString(TEXT_PATH_STATE_PATH_ERR
);
2985 case MP_PATH_STATE_LU_ERR
:
2986 pathString
= getTextString(TEXT_PATH_STATE_LU_ERR
);
2988 case MP_PATH_STATE_RESERVED
:
2989 pathString
= getTextString(TEXT_PATH_STATE_RESERVED
);
2991 case MP_PATH_STATE_REMOVED
:
2992 pathString
= getTextString(TEXT_PATH_STATE_REMOVED
);
2994 case MP_PATH_STATE_TRANSITIONING
:
2996 getTextString(TEXT_PATH_STATE_TRANSITIONING
);
2998 case MP_PATH_STATE_OPERATIONAL_CLOSED
:
3000 getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED
);
3002 case MP_PATH_STATE_INVALID_CLOSED
:
3004 getTextString(TEXT_PATH_STATE_INVALID_CLOSED
);
3006 case MP_PATH_STATE_OFFLINE_CLOSED
:
3008 getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED
);
3011 pathString
= getTextString(TEXT_UNKNOWN
);
3015 return (pathString
);
3016 } /* end getPathStateStr */
3021 * ****************************************************************************
3024 * Gets the string description for the specified access state type value
3026 * accessState - MP_ACCESS_STATE_TYPE values
3028 * ****************************************************************************
3031 getAccessStateStr(MP_ACCESS_STATE_TYPE accessState
)
3035 switch (accessState
) {
3036 case MP_ACCESS_STATE_ACTIVE_OPTIMIZED
:
3038 getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED
);
3040 case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED
:
3043 TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED
);
3045 case MP_ACCESS_STATE_STANDBY
:
3047 getTextString(TEXT_ACCESS_STATE_STANDBY
);
3049 case MP_ACCESS_STATE_UNAVAILABLE
:
3051 getTextString(TEXT_ACCESS_STATE_UNAVAILABLE
);
3053 case MP_ACCESS_STATE_TRANSITIONING
:
3055 getTextString(TEXT_ACCESS_STATE_TRANSITIONING
);
3057 case MP_ACCESS_STATE_ACTIVE
:
3058 accessString
= getTextString(TEXT_ACCESS_STATE_ACTIVE
);
3061 accessString
= getTextString(TEXT_UNKNOWN
);
3064 return (accessString
);
3065 } /* end getAccessStateStr */
3069 * ****************************************************************************
3072 * Print out the specified array.
3074 * arrayToDisplay - array to display
3075 * arraySize - size of array to display
3077 * ****************************************************************************
3080 displayArray(MP_CHAR
*arrayToDisplay
, int arraySize
)
3084 for (i
= 0; i
< arraySize
; i
++) {
3085 if ('\0' != arrayToDisplay
[i
]) {
3086 (void) fprintf(stdout
, "%c", arrayToDisplay
[i
]);
3094 * ****************************************************************************
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.
3100 * arrayToDisplay - array to display
3101 * arraySize - size of array to display
3103 * ****************************************************************************
3106 getStringArray(MP_CHAR
*arrayToDisplay
, int arraySize
)
3112 newStr
= malloc(((sizeof (MP_CHAR
)) * arraySize
) + 1);
3113 if (NULL
== newStr
) {
3114 (void) fprintf(stdout
, "%s\n",
3115 getTextString(ERR_MEMORY_ALLOCATION
));
3118 for (i
= 0; i
< arraySize
; i
++) {
3119 newStr
[i
] = arrayToDisplay
[i
];
3121 newStr
[arraySize
] = '\0';
3129 * ****************************************************************************
3132 * Print out the specified wide character array as a string,
3133 * adding the null termination
3135 * arrayToDisplay - array to display
3136 * arraySize - size of array to display
3138 * ****************************************************************************
3141 displayWideArray(MP_WCHAR
*arrayToDisplay
, int arraySize
)
3144 int numChars
= arraySize
/4;
3146 for (i
= 0; i
< numChars
; i
++) {
3147 if (L
'\0' != arrayToDisplay
[i
]) {
3148 (void) fprintf(stdout
, "%wc", (int)arrayToDisplay
[i
]);
3155 * ****************************************************************************
3158 * Used by cmdparse for list clis
3160 * ****************************************************************************
3164 listFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3171 ret
= listMpathSupport(operandLen
, operand
);
3174 ret
= listLogicalUnit(operandLen
, operand
, options
);
3176 case INITIATOR_PORT
:
3177 ret
= listInitiatorPort(operandLen
, operand
);
3180 (void) fprintf(stderr
, "%s: %s\n",
3181 cmdName
, getTextString(TEXT_UNKNOWN_OBJECT
));
3191 * ****************************************************************************
3194 * used bycmdparse for show clis
3196 * ****************************************************************************
3200 showFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3207 ret
= showMpathSupport(operandLen
, operand
);
3210 ret
= showLogicalUnit(operandLen
, operand
);
3212 case INITIATOR_PORT
:
3213 ret
= showInitiatorPort(operandLen
, operand
);
3225 * ****************************************************************************
3228 * Used by cmdparse for midify clis
3231 * ****************************************************************************
3235 modifyFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3242 ret
= modifyMpathSupport(operandLen
, operand
, options
);
3245 ret
= modifyLogicalUnit(operandLen
, operand
, options
);
3258 * ****************************************************************************
3261 * Used by cmdpars for enable clis
3263 * ****************************************************************************
3267 enableFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3274 ret
= enablePath(options
);
3286 * ****************************************************************************
3289 * Used by cmdpars for disable clis
3291 * ****************************************************************************
3295 disableFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3302 ret
= disablePath(options
);
3314 * ****************************************************************************
3317 * Used by cmdpars for failover clis
3319 * ****************************************************************************
3323 failoverFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3330 ret
= failoverLogicalUnit(operand
);
3342 * ****************************************************************************
3345 * Used by cmdpars for override clis
3347 * ****************************************************************************
3351 overrideFunc(int operandLen
, char *operand
[],
3352 int object
, cmdOptions_t
*options
,
3359 ret
= overridePath(options
);
3372 * *************************************************************************
3376 * *************************************************************************
3379 main(int argc
, char *argv
[])
3381 synTables_t synTables
;
3382 char versionString
[VERSION_STRING_MAX_LEN
];
3385 void *subcommandArgs
= NULL
;
3387 /* set global command name */
3388 cmdName
= getExecBasename(argv
[0]);
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];
3399 ret
= cmdParse(argc
, argv
, /* SUB_COMMAND_ISSUED, */ synTables
,
3400 subcommandArgs
, &funcRet
);
3402 (void) fprintf(stdout
, "%s %s(1M)\n",
3403 getTextString(TEXT_MORE_INFO
), cmdName
);
3404 return (ERROR_CLI_FAILED
);
3405 } else if (ret
== -1) {
3411 (void) fprintf(stderr
, "%s: %s\n",
3412 argv
[0], getTextString(TEXT_UNABLE_TO_COMPLETE
));