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.
27 * mpathadm.c : MP API CLI program
35 #include "mpathadm_text.h"
38 #include <sys/types.h>
45 /* helper functions */
46 static char *getExecBasename(char *);
48 /* object functions per subcommand */
49 static int listFunc(int, char **, int, cmdOptions_t
*, void *);
50 static int showFunc(int, char **, int, cmdOptions_t
*, void *);
51 static int modifyFunc(int, char **, int, cmdOptions_t
*, void *);
52 static int enableFunc(int, char **, int, cmdOptions_t
*, void *);
53 static int disableFunc(int, char **, int, cmdOptions_t
*, void *);
54 static int failoverFunc(int, char **, int, cmdOptions_t
*, void *);
55 static int overrideFunc(int, char **, int, cmdOptions_t
*, void *);
57 #define VERSION_STRING_MAX_LEN 10
59 #define OPTIONSTRING_NAME "name"
60 #define OPTIONSTRING_TPNAME "target-port name"
61 #define OPTIONSTRING_ONOFF "on/off"
62 #define OPTIONSTRING_LBTYPE "loadbalance type"
63 #define OPTIONSTRING_IPORT "initiator-port name"
64 #define OPTIONSTRING_LUNIT "logical-unit name"
65 #define OPTIONSTRING_CANCEL "cancel"
66 #define OPTIONSTRING_VALUE "value"
69 * Version number: (copied from iscsiadm)
70 * MAJOR - This should only change when there is an incompatible change made
71 * to the interfaces or the output.
73 * MINOR - This should change whenever there is a new command or new feature
74 * with no incompatible change.
76 #define VERSION_STRING_MAJOR "1"
77 #define VERSION_STRING_MINOR "0"
85 * ****************************************************************************
87 * getExecBasename - copied from iscsiadm code
90 * execFullName - exec name of program (argv[0])
93 * command name portion of execFullName
95 * ****************************************************************************
98 getExecBasename(char *execFullname
)
100 char *lastSlash
, *execBasename
;
102 /* guard against '/' at end of command invocation */
104 lastSlash
= strrchr(execFullname
, '/');
105 if (lastSlash
== NULL
) {
106 execBasename
= execFullname
;
109 execBasename
= lastSlash
+ 1;
110 if (*execBasename
== '\0') {
117 return (execBasename
);
122 * Add new options here
125 /* tables set up based on cmdparse instructions */
126 optionTbl_t longOptions
[] = {
127 {"inqname", required_arg
, 'n', OPTIONSTRING_NAME
},
128 {"target-port", required_arg
, 't', OPTIONSTRING_TPNAME
},
129 {"autofailback", required_arg
, 'a', OPTIONSTRING_ONOFF
},
130 {"autoprobe", required_arg
, 'p', OPTIONSTRING_ONOFF
},
131 {"loadbalance", required_arg
, 'b', OPTIONSTRING_LBTYPE
},
132 {"initiator-port", required_arg
, 'i', OPTIONSTRING_IPORT
},
133 {"logical-unit", required_arg
, 'l', OPTIONSTRING_LUNIT
},
134 {"cancel", no_arg
, 'c', OPTIONSTRING_CANCEL
},
135 {"vendor-id", required_arg
, 'd', OPTIONSTRING_VALUE
},
141 * Add new subcommands here
143 subcommand_t subcommands
[] = {
144 {"list", LIST
, listFunc
},
145 {"show", SHOW
, showFunc
},
146 {"modify", MODIFY
, modifyFunc
},
147 {"enable", ENABLE
, enableFunc
},
148 {"disable", DISABLE
, disableFunc
},
149 {"failover", FAILOVER
, failoverFunc
},
150 {"override", OVERRIDE
, overrideFunc
},
157 object_t objects
[] = {
158 {"mpath-support", MPATH_SUPPORT
},
159 {"logical-unit", LOGICAL_UNIT
},
160 {"LU", LOGICAL_UNIT
},
161 {"initiator-port", INITIATOR_PORT
},
167 * Rules for subcommands and objects
171 * reqOpCmd -> subcommands that must have an operand
172 * optOpCmd -> subcommands that may have an operand
173 * noOpCmd -> subcommands that will have no operand
174 * invCmd -> subcommands that are invalid
175 * multOpCmd -> subcommands that can accept multiple operands
176 * operandDefinition -> Usage definition for the operand of this object
178 objectRules_t objectRules
[] = {
179 {MPATH_SUPPORT
, SHOW
|MODIFY
|ADD
, LIST
|REMOVE
, 0,
180 ENABLE
|DISABLE
|FAILOVER
|OVERRIDE
, LIST
|SHOW
|MODIFY
,
181 "mpath-support name"},
182 {INITIATOR_PORT
, SHOW
, LIST
, 0,
183 MODIFY
|ENABLE
|DISABLE
|FAILOVER
|OVERRIDE
|ADD
|REMOVE
, LIST
|SHOW
,
184 "initiator-port name"},
185 {LOGICAL_UNIT
, SHOW
|MODIFY
|FAILOVER
, LIST
, 0,
186 ENABLE
|DISABLE
|OVERRIDE
|ADD
|REMOVE
, LIST
|SHOW
|MODIFY
,
187 "logical-unit name"},
188 {PATH
, 0, 0, ENABLE
|DISABLE
|OVERRIDE
,
189 SHOW
|LIST
|MODIFY
|FAILOVER
|ADD
|REMOVE
, 0,
190 "initiator-port name"},
191 {0, 0, 0, 0, 0, NULL
}
195 * list of objects, subcommands, valid short options, required flag and
196 * exclusive option string
198 * If it's not here, there are no options for that object.
200 optionRules_t optionRules
[] = {
201 {LOGICAL_UNIT
, LIST
, "nt", B_FALSE
, NULL
},
202 {LOGICAL_UNIT
, MODIFY
, "apb", B_TRUE
, NULL
},
203 {MPATH_SUPPORT
, MODIFY
, "apb", B_TRUE
, NULL
},
204 {MPATH_SUPPORT
, ADD
, "d", B_TRUE
, NULL
},
205 {MPATH_SUPPORT
, REMOVE
, "d", B_TRUE
, NULL
},
206 {PATH
, ENABLE
, "itl", B_TRUE
, NULL
},
207 {PATH
, DISABLE
, "itl", B_TRUE
, NULL
},
208 {PATH
, OVERRIDE
, "itlc", B_TRUE
, NULL
},
214 * ****************************************************************************
216 * listMpathSupport - mpathadm list mpath-support
218 * operandLen - number of operands user passed into the cli
219 * operand - pointer to operand list from user
221 * ****************************************************************************
224 listMpathSupport(int operandLen
, char *operand
[])
226 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
227 MP_PLUGIN_PROPERTIES pluginProps
;
228 MP_OID_LIST
*pPluginOidList
;
229 boolean_t shown
= B_FALSE
;
230 /* number of plugins listed */
233 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
234 != MP_STATUS_SUCCESS
) {
235 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
236 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
239 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
240 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
241 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
242 return (ERROR_CLI_FAILED
);
246 /* loop through operands first */
247 for (op
= 0; (op
< operandLen
) |
248 ((0 == operandLen
) && (B_FALSE
== shown
)); op
++) {
250 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
252 (void) memset(&pluginProps
, 0,
253 sizeof (MP_PLUGIN_PROPERTIES
));
255 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
257 if (mpstatus
!= MP_STATUS_SUCCESS
) {
258 (void) fprintf(stderr
, "%s: %s\n",
259 cmdName
, getTextString(ERR_NO_PROPERTIES
));
261 if (0 == operandLen
) {
262 /* if no operands, list them all */
263 (void) printf("%s %s\n",
265 TEXT_LB_MPATH_SUPPORT
),
266 pluginProps
.fileName
);
268 /* if there is an operand... */
269 /* ... compare and display if match */
272 pluginProps
.fileName
)) {
273 (void) printf("%s %s\n",
275 TEXT_LB_MPATH_SUPPORT
),
276 pluginProps
.fileName
);
278 /* begin back-up indentation */
279 /* LINTED E_SEC_PRINTF_VAR_FMT */
280 (void) fprintf(stderr
, getTextString(
281 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME
),
283 /* end back-up indentation */
296 * ****************************************************************************
298 * showMpathSupport - mpathadm show mpath-support <mpath-support name>, ...
300 * operandLen - number of operands user passed into the cli
301 * operand - pointer to operand list from user
303 * ****************************************************************************
306 showMpathSupport(int operandLen
, char *operand
[])
308 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
309 MP_PLUGIN_PROPERTIES pluginProps
;
310 MP_OID_LIST
*pPluginOidList
;
311 MP_OID_LIST
*deviceOidListArray
;
312 MP_DEVICE_PRODUCT_PROPERTIES devProps
;
313 boolean_t bListIt
= B_FALSE
;
315 MP_LOAD_BALANCE_TYPE lb
;
318 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
)) !=
320 (void) fprintf(stderr
, "%s: %s\n",
321 cmdName
, getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
324 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
325 (void) fprintf(stderr
, "%s: %s\n",
326 cmdName
, getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
327 return (ERROR_CLI_FAILED
);
330 for (op
= 0; op
< operandLen
; op
++) {
333 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
335 (void) memset(&pluginProps
, 0,
336 sizeof (MP_PLUGIN_PROPERTIES
));
338 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
340 if (MP_STATUS_SUCCESS
!= mpstatus
) {
341 (void) fprintf(stderr
, "%s: %s\n",
342 cmdName
, getTextString(ERR_NO_PROPERTIES
));
346 if (0 == operandLen
) {
347 /* if no operand, list it */
350 /* ... compare and display if match */
353 pluginProps
.fileName
)) {
358 if (B_TRUE
!= bListIt
) {
362 (void) printf("%s %s\n",
363 getTextString(TEXT_LB_MPATH_SUPPORT
),
364 pluginProps
.fileName
);
366 /* display the info for this plugin */
367 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR
));
368 displayWideArray(pluginProps
.vendor
,
369 sizeof (pluginProps
.vendor
));
370 (void) printf("\n\t%s ",
371 getTextString(TEXT_LB_DRIVER_NAME
));
372 displayArray(pluginProps
.driverName
,
373 sizeof (pluginProps
.driverName
));
374 (void) printf("\n\t%s ",
375 getTextString(TEXT_LB_DEFAULT_LB
));
376 /* don't ignore load balance type none. */
377 if (pluginProps
.defaultloadBalanceType
== 0) {
379 getTextString(TEXT_LBTYPE_NONE
));
381 displayLoadBalanceString(
382 pluginProps
.defaultloadBalanceType
);
387 (void) printf("\t%s \n",
388 getTextString(TEXT_LB_SUPPORTED_LB
));
389 /* check each bit, display string if found set */
390 if (pluginProps
.supportedLoadBalanceTypes
== 0) {
391 (void) printf("\t\t%s\n",
392 getTextString(TEXT_LBTYPE_NONE
));
396 if (0 != (lb
& pluginProps
.
397 supportedLoadBalanceTypes
)) {
398 (void) printf("\t\t");
399 displayLoadBalanceString(lb
&
401 supportedLoadBalanceTypes
);
405 } while (lb
< 0x80000000);
408 (void) printf("\t%s %s\n",
409 getTextString(TEXT_LB_ALLOWS_ACT_TPG
),
410 (MP_TRUE
== pluginProps
.canSetTPGAccess
)?
411 getTextString(TEXT_YES
):getTextString(TEXT_NO
));
412 (void) printf("\t%s %s\n",
413 getTextString(TEXT_LB_ALLOWS_PATH_OV
),
414 (MP_TRUE
== pluginProps
.canOverridePaths
)?
415 getTextString(TEXT_YES
):getTextString(TEXT_NO
));
416 (void) printf("\t%s %d\n",
417 getTextString(TEXT_LB_SUPP_AUTO_FB
),
418 pluginProps
.autoFailbackSupport
);
419 if ((MP_AUTOFAILBACK_SUPPORT_PLUGIN
==
420 pluginProps
.autoFailbackSupport
) |
421 (MP_AUTOFAILBACK_SUPPORT_PLUGINANDMPLU
422 == pluginProps
.autoFailbackSupport
)) {
423 (void) printf("\t%s %s\n",
424 getTextString(TEXT_LB_AUTO_FB
),
425 pluginProps
.pluginAutoFailbackEnabled
?\
426 getTextString(TEXT_ON
):
427 getTextString(TEXT_OFF
));
428 (void) printf("\t%s %d/%d\n",
429 getTextString(TEXT_LB_FB_POLLING_RATE
),
430 pluginProps
.currentFailbackPollingRate
,
431 pluginProps
.failbackPollingRateMax
);
433 (void) printf("\t%s %s\n",
434 getTextString(TEXT_LB_AUTO_FB
),
435 getTextString(TEXT_NA
));
436 (void) printf("\t%s %s/%s\n",
437 getTextString(TEXT_LB_FB_POLLING_RATE
),
438 getTextString(TEXT_NA
),
439 getTextString(TEXT_NA
));
441 (void) printf("\t%s %d\n",
442 getTextString(TEXT_LB_SUPP_AUTO_P
),
443 pluginProps
.autoProbingSupport
);
444 if ((MP_AUTOPROBING_SUPPORT_PLUGIN
==
445 pluginProps
.autoProbingSupport
) |
446 (MP_AUTOPROBING_SUPPORT_PLUGIN
==
447 pluginProps
.autoProbingSupport
)) {
448 (void) printf("\t%s %s\n",
449 getTextString(TEXT_LB_AUTO_PROB
),
451 pluginProps
.pluginAutoProbingEnabled
)?\
452 getTextString(TEXT_YES
):
453 getTextString(TEXT_NO
));
454 (void) printf("\t%s %d/%d\n",
455 getTextString(TEXT_LB_PR_POLLING_RATE
),
456 pluginProps
.currentProbingPollingRate
,
457 pluginProps
.probingPollingRateMax
);
459 (void) printf("\t%s %s\n",
460 getTextString(TEXT_LB_AUTO_PROB
),
461 getTextString(TEXT_NA
));
462 (void) printf("\t%s %s/%s\n",
463 getTextString(TEXT_LB_PR_POLLING_RATE
),
464 getTextString(TEXT_NA
),
465 getTextString(TEXT_NA
));
469 (void) printf("\t%s\n",
470 getTextString(TEXT_LB_SUPP_DEVICES
));
474 pluginProps
.onlySupportsSpecifiedProducts
) {
475 /* LINTED E_SEC_PRINTF_VAR_FMT */
476 (void) printf(getTextString(TEXT_ANY_DEVICE
));
478 /* if only supports specific products, */
479 /* get device product properties supported */
481 mpstatus
= MP_GetDeviceProductOidList(\
482 pPluginOidList
->oids
[i
],
483 &deviceOidListArray
);
484 if (mpstatus
!= MP_STATUS_SUCCESS
) {
485 (void) fprintf(stderr
, "%s: %s\n",
486 cmdName
, getTextString(
487 ERR_NO_SUPP_DEVICE_INFO
));
488 /* can't get any more info, */
489 /* so we're done with this one */
493 for (j
= 0; j
< deviceOidListArray
->oidCount
;
495 /* begin backup indentation */
496 (void) memset(&devProps
, 0,
497 sizeof (MP_DEVICE_PRODUCT_PROPERTIES
));
498 /* end backup indentation */
500 MP_GetDeviceProductProperties(\
501 deviceOidListArray
->oids
[j
],
502 &devProps
)) == MP_STATUS_SUCCESS
) {
504 (void) printf("\t\t%s ",
507 displayArray(devProps
.vendor
,
508 sizeof (devProps
.vendor
));
509 (void) printf("\n\t\t%s ",
512 displayArray(devProps
.product
,
513 sizeof (devProps
.product
));
514 (void) printf("\n\t\t%s ",
517 displayArray(devProps
.revision
,
518 sizeof (devProps
.revision
));
520 (void) printf("\n\t\t%s\n",
522 TEXT_LB_SUPPORTED_LB
));
523 /* begin back-up indentation */
524 if (devProps
.supportedLoadBalanceTypes
== 0) {
525 (void) printf("\t\t\t%s\n",
526 getTextString(TEXT_LBTYPE_NONE
));
531 devProps
.supportedLoadBalanceTypes
)) {
532 (void) printf("\t\t\t");
533 displayLoadBalanceString(lb
&
534 devProps
.supportedLoadBalanceTypes
);
538 } while (lb
< 0x80000000);
540 /* end back-up indentation */
544 (void) fprintf(stderr
,
547 ERR_NO_SUPP_DEVICE_INFO
));
550 } /* if only supports specified devices */
552 } /* for each plugin */
554 if (B_FALSE
== bListIt
) {
555 /* LINTED E_SEC_PRINTF_VAR_FMT */
556 (void) fprintf(stderr
, getTextString(
557 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME
),
563 } /* for each operand */
571 * ****************************************************************************
573 * modifyMpathSupport -
574 * mpathadm modify mpath-support [options] <mpath-support name>, ...
576 * operandLen - number of operands user passed into the cli
577 * operand - pointer to operand list from user
578 * options - pointer to option list from user
580 * ****************************************************************************
583 modifyMpathSupport(int operandLen
, char *operand
[], cmdOptions_t
*options
)
585 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
586 MP_PLUGIN_PROPERTIES pluginProps
;
587 MP_OID_LIST
*pPluginOidList
;
588 boolean_t bFoundIt
= B_FALSE
;
590 cmdOptions_t
*optionList
= options
;
591 char *cmdStr
= getTextString(TEXT_UNKNOWN
);
594 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
595 != MP_STATUS_SUCCESS
) {
596 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
597 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
600 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
601 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
602 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
603 return (ERROR_CLI_FAILED
);
606 for (op
= 0; op
< operandLen
; op
++) {
609 (i
< pPluginOidList
->oidCount
) && (B_TRUE
!= bFoundIt
);
612 (void) memset(&pluginProps
, 0,
613 sizeof (MP_PLUGIN_PROPERTIES
));
615 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
616 &pluginProps
)) == MP_STATUS_SUCCESS
) {
618 if (0 == strcmp(operand
[op
],
619 pluginProps
.fileName
)) {
621 pluginOid
= pPluginOidList
->oids
[i
];
624 (void) fprintf(stderr
, "%s: %s\n",
625 cmdName
, getTextString(ERR_NO_PROPERTIES
));
628 if (B_FALSE
== bFoundIt
) {
632 /* begin back-up indentation */
633 /* we found the plugin oid */
634 /* now change the options requested */
635 switch (optionList
->optval
) {
637 /* modify autofailback */
638 cmdStr
= getTextString(TEXT_AUTO_FAILBACK
);
639 if (0 == strcasecmp(optionList
->optarg
,
640 getTextString(TEXT_ON
))) {
642 MP_EnableAutoFailback(pluginOid
);
644 strcasecmp(optionList
->optarg
,
645 getTextString(TEXT_OFF
))) {
647 MP_DisableAutoFailback(pluginOid
);
649 /* LINTED E_SEC_PRINTF_VAR_FMT */
650 (void) fprintf(stderr
, getTextString(
651 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
653 getTextString(TEXT_ILLEGAL_ARGUMENT
));
655 return (ERROR_CLI_FAILED
);
659 /* modify autoprobing */
660 cmdStr
= getTextString(TEXT_AUTO_PROBING
);
661 if (0 == strcasecmp(optionList
->optarg
,
662 getTextString(TEXT_ON
))) {
664 MP_EnableAutoProbing(pluginOid
);
666 strcasecmp(optionList
->optarg
,
667 getTextString(TEXT_OFF
))) {
669 MP_DisableAutoProbing(pluginOid
);
671 /* LINTED E_SEC_PRINTF_VAR_FMT */
672 (void) fprintf(stderr
, getTextString(
673 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
675 getTextString(TEXT_ILLEGAL_ARGUMENT
));
677 return (ERROR_CLI_FAILED
);
681 /* modify loadbalance type */
682 cmdStr
= getTextString(TEXT_LOAD_BALANCE
);
683 /* user of the cli sends text string, we need the int */
684 /* value to pass to the mpapi */
685 lbValue
= getLbValueFromString(optionList
->optarg
);
687 MP_SetPluginLoadBalanceType(pluginOid
,
692 if (MP_STATUS_SUCCESS
!= mpstatus
) {
693 /* LINTED E_SEC_PRINTF_VAR_FMT */
694 (void) fprintf(stderr
,
696 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
697 cmdStr
, getMpStatusStr(mpstatus
));
701 /* end back-up indentation */
703 } /* for each plugin */
705 if (B_FALSE
== bFoundIt
) {
706 /* LINTED E_SEC_PRINTF_VAR_FMT */
707 (void) fprintf(stderr
,
709 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
711 getTextString(TEXT_MPATH_SUPPORT_NOT_FOUND
));
713 return (ERROR_CLI_FAILED
);
716 } /* for each operand */
723 * ****************************************************************************
726 * mpathadm list {logical-unit | LU} [options] [<logical-unit name>, ...]
728 * operandLen - number of operands user passed into the cli
729 * operand - pointer to operand list from user
730 * options - pointer to option list from user
732 * ****************************************************************************
735 listLogicalUnit(int operandLen
, char *operand
[], cmdOptions_t
*options
)
737 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
738 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
739 MP_PLUGIN_PROPERTIES pluginProps
;
740 MP_TARGET_PORT_PROPERTIES tportProps
;
741 MP_OID_LIST
*pPluginOidList
, *pLogicalUnitOidList
,
742 *pTpgOidListArray
, *pTportOidListArray
;
743 boolean_t bListIt
= B_FALSE
, bFoundOperand
= B_FALSE
,
744 *bFoundOption
, bContinue
= B_FALSE
;
746 cmdOptions_t
*optionList
= options
;
747 int opListCount
= 0, i
= 0, lu
= 0, tpg
= 0, opoffset
= 0, j
= 0,
748 opStart
= 0, opEnd
= 0, opIndex
;
750 /* count number of options */
751 for (; optionList
->optval
; optionList
++) {
755 bFoundOption
= malloc((sizeof (boolean_t
)) * opListCount
);
756 if (NULL
== bFoundOption
) {
757 (void) fprintf(stdout
, "%s\n",
758 getTextString(ERR_MEMORY_ALLOCATION
));
759 return (ERROR_CLI_FAILED
);
762 /* list to keep track of multiple options */
763 optionList
= options
;
764 for (opIndex
= 0; opIndex
< opListCount
; opIndex
++) {
765 bFoundOption
[opIndex
] = B_FALSE
;
768 optionList
= options
;
770 /* if no operands or options, list everything we find */
771 if ((0 == operandLen
) && (0 == opListCount
)) {
772 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
773 != MP_STATUS_SUCCESS
) {
774 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
775 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
778 if ((NULL
== pPluginOidList
) ||
779 (pPluginOidList
->oidCount
< 1)) {
780 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
781 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
782 return (ERROR_CLI_FAILED
);
785 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
786 /* get properties so we can list the name */
787 (void) memset(&pluginProps
, 0,
788 sizeof (MP_PLUGIN_PROPERTIES
));
790 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
791 &pluginProps
)) != MP_STATUS_SUCCESS
) {
792 (void) fprintf(stderr
, "%s: %s\n",
793 cmdName
, getTextString(ERR_NO_PROPERTIES
));
797 /* attempt to find this logical unit */
798 mpstatus
= MP_GetMultipathLus(pPluginOidList
->oids
[i
],
799 &pLogicalUnitOidList
);
800 if (mpstatus
!= MP_STATUS_SUCCESS
) {
801 (void) fprintf(stderr
, "%s: %s\n",
802 cmdName
, getTextString(ERR_NO_LU_LIST
));
806 for (lu
= 0; lu
< pLogicalUnitOidList
->oidCount
; lu
++) {
807 /* begin backup indentation */
808 /* get lu properties so we can check the name */
809 (void) memset(&luProps
, 0,
810 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
811 /* end backup indentation */
813 MP_GetMPLogicalUnitProperties(
814 pLogicalUnitOidList
->oids
[lu
],
816 if (mpstatus
!= MP_STATUS_SUCCESS
) {
817 (void) fprintf(stderr
, "%s: %s\n",
819 getTextString(ERR_NO_PROPERTIES
));
823 luOid
= pLogicalUnitOidList
->oids
[lu
];
824 if (listIndividualLogicalUnit(luOid
, luProps
)
826 return (ERROR_CLI_FAILED
);
829 } /* for each plugin */
830 } else { /* we have operands and/or options */
832 /* check if we have operands */
833 if (0 == operandLen
) {
843 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
844 != MP_STATUS_SUCCESS
) {
845 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
846 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
849 if ((NULL
== pPluginOidList
) ||
850 (pPluginOidList
->oidCount
< 1)) {
851 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
852 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
853 return (ERROR_CLI_FAILED
);
856 for (opoffset
= opStart
; opoffset
< opEnd
; opoffset
++) {
857 /* loop through operands */
858 bFoundOperand
= B_FALSE
;
860 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
863 * loop through plugin, and get properties
864 * so we can list the name
866 (void) memset(&pluginProps
, 0,
867 sizeof (MP_PLUGIN_PROPERTIES
));
869 MP_GetPluginProperties(
870 pPluginOidList
->oids
[i
], &pluginProps
))
871 != MP_STATUS_SUCCESS
) {
872 (void) fprintf(stderr
, "%s: %s\n",
874 getTextString(ERR_NO_PROPERTIES
));
878 /* attempt to find this logical unit */
880 MP_GetMultipathLus(pPluginOidList
->oids
[i
],
881 &pLogicalUnitOidList
);
882 if (mpstatus
!= MP_STATUS_SUCCESS
) {
883 (void) fprintf(stderr
, "%s: %s\n",
885 getTextString(ERR_NO_LU_LIST
));
890 (lu
< pLogicalUnitOidList
->oidCount
);
893 /* begin backup indentation */
894 /* get lu props & check the name */
895 (void) memset(&luProps
, 0,
896 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
897 /* end backup indentation */
899 MP_GetMPLogicalUnitProperties(
900 pLogicalUnitOidList
->oids
[lu
],
902 if (mpstatus
!= MP_STATUS_SUCCESS
) {
903 (void) fprintf(stderr
,
911 * compare operand - is it a match?
916 if (operandLen
> 0) {
920 luProps
.deviceFileName
);
923 if (B_TRUE
== bContinue
) {
925 if (0 != opListCount
) {
929 /* begin backup indentation */
930 optionList
= options
;
932 for (opIndex
= 0; optionList
->optval
; optionList
++, opIndex
++) {
933 switch (optionList
->optval
) {
936 compareLUName(optionList
->optarg
, luProps
.name
)) {
938 bFoundOperand
= B_TRUE
;
939 bFoundOption
[opIndex
] = B_TRUE
;
945 MP_GetAssociatedTPGOidList(pLogicalUnitOidList
->oids
[lu
],
947 if (mpstatus
!= MP_STATUS_SUCCESS
) {
948 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
949 getTextString(ERR_NO_ASSOC_TPGS
));
953 /* get target ports */
955 (NULL
!= pTpgOidListArray
) &&
956 (tpg
< pTpgOidListArray
->oidCount
) &&
957 (B_FALSE
== bListIt
); tpg
++) {
959 MP_GetTargetPortOidList(pTpgOidListArray
->oids
[tpg
],
960 &pTportOidListArray
);
961 if (mpstatus
!= MP_STATUS_SUCCESS
) {
962 (void) fprintf(stderr
, "%s: %s\n",
964 getTextString(ERR_NO_ASSOC_TPORTS
));
968 /* get target port properties for the name */
969 for (j
= 0; (NULL
!= pTportOidListArray
) &&
970 (j
< pTportOidListArray
->oidCount
) &&
971 (B_FALSE
== bListIt
); j
++) {
972 (void) memset(&tportProps
, 0,
973 sizeof (MP_TARGET_PORT_PROPERTIES
));
975 MP_GetTargetPortProperties(
976 pTportOidListArray
->oids
[j
], &tportProps
);
977 if (mpstatus
!= MP_STATUS_SUCCESS
) {
978 (void) fprintf(stderr
, "%s: %s\n",
980 getTextString(ERR_NO_PROPERTIES
));
986 if (0 == strcmp(optionList
->optarg
,
987 tportProps
.portID
)) {
989 bFoundOperand
= B_TRUE
;
990 bFoundOption
[opIndex
] = B_TRUE
;
992 } /* for each target port */
995 } /* loop through options */
996 /* end back-up indentation */
1004 bFoundOperand
= B_TRUE
;
1006 } /* end bContinue check */
1009 (void) printf("%s %s\n",
1010 getTextString(TEXT_LB_MPATH_SUPPORT
),
1011 pluginProps
.fileName
);
1012 luOid
= pLogicalUnitOidList
->oids
[lu
];
1013 if (listIndividualLogicalUnit(luOid
, luProps
)
1015 return (ERROR_CLI_FAILED
);
1021 } /* end plugin loop */
1022 if ((0 == opListCount
) && (0 != operandLen
)) {
1023 if (B_FALSE
== bFoundOperand
) {
1024 /* option/operand combo not found */
1025 /* LINTED E_SEC_PRINTF_VAR_FMT */
1026 (void) fprintf(stderr
,
1028 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1030 (void) fprintf(stderr
, "\n");
1034 optionList
= options
;
1035 for (opIndex
= 0; optionList
->optval
; optionList
++,
1037 if (B_FALSE
== bFoundOption
[opIndex
]) {
1038 /* LINTED E_SEC_PRINTF_VAR_FMT */
1039 (void) fprintf(stderr
,
1041 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1042 optionList
->optarg
);
1043 (void) fprintf(stderr
, "\n");
1049 } /* end loop through operands */
1050 } /* we have operands and/or options */
1058 * ****************************************************************************
1061 * compare names directly and via devid if no match directly
1063 * cmpString - first string to compare
1064 * deviceProperty - string from properties
1065 * sizeToCompare - size of deviceProperty
1067 * returns B_TRUE if the strings match either directly or via devid
1070 * ****************************************************************************
1073 compareLUName(MP_CHAR
*cmpString
, MP_CHAR
*deviceProperty
)
1076 boolean_t isSame
= B_FALSE
;
1078 ddi_devid_t devid1
= NULL
, devid2
= NULL
;
1080 if (0 == strcmp(cmpString
, deviceProperty
)) {
1083 /* user input didn't match, try via devid */
1085 * I don't see a reason to print the error for
1086 * any of these since they'll get the error at
1091 if (((fd1
= open(cmpString
, O_RDONLY
|O_NDELAY
)) >= 0) &&
1092 ((fd2
= open(deviceProperty
, O_RDONLY
|O_NDELAY
)) >= 0) &&
1093 (devid_get(fd1
, &devid1
) == 0) &&
1094 (devid_get(fd2
, &devid2
) == 0) &&
1095 ((NULL
!= devid1
) && (NULL
!= devid2
))) {
1097 (devid_compare(devid1
, devid2
))) {
1102 if (NULL
!= devid1
) {
1105 if (NULL
!= devid2
) {
1122 * ****************************************************************************
1124 * listIndivudualLogicalUnit -
1125 * Used by list logical unit cli.
1126 * Displays info about an LU
1128 * luOid - LU to list
1129 * luProps - properties of he LU to list
1131 * ****************************************************************************
1134 listIndividualLogicalUnit(MP_OID luOid
,
1135 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
)
1137 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps
;
1138 MP_OID_LIST
*pPathOidListArray
;
1139 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1140 int numOperationalPaths
, pa
;
1142 (void) printf("\t");
1143 displayArray(luProps
.deviceFileName
, sizeof (luProps
.deviceFileName
));
1144 (void) printf("\n");
1146 mpstatus
= MP_GetAssociatedPathOidList(luOid
,
1147 &pPathOidListArray
);
1148 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1149 /* LINTED E_SEC_PRINTF_VAR_FMT */
1150 (void) fprintf(stderr
,
1151 getTextString(ERR_NO_LU_PATH_INFO_WITH_MISSING_LU_STR
),
1152 getStringArray(luProps
.deviceFileName
,
1153 sizeof (luProps
.deviceFileName
)));
1154 (void) fprintf(stderr
, "\n");
1157 (void) printf("\t\t%s %d\n",
1158 getTextString(TEXT_LB_PATH_COUNT
), pPathOidListArray
->oidCount
);
1160 numOperationalPaths
= 0;
1161 for (pa
= 0; pa
< pPathOidListArray
->oidCount
; pa
++) {
1162 (void) memset(&pathProps
, 0,
1163 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES
));
1165 MP_GetPathLogicalUnitProperties(
1166 pPathOidListArray
->oids
[pa
], &pathProps
);
1167 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1168 (void) fprintf(stderr
, "%s: %s\n",
1169 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1173 /* cycle through and check status of each for */
1174 /* operation path count */
1175 if (MP_PATH_STATE_OKAY
== pathProps
.pathState
) {
1176 numOperationalPaths
++;
1180 (void) printf("\t\t%s %d\n",
1181 getTextString(TEXT_LB_OP_PATH_COUNT
), numOperationalPaths
);
1188 * ****************************************************************************
1191 * mpathadm show {logical-unit | LU} <logical-unit name>, ...
1193 * operandLen - number of operands user passed into the cli
1194 * operand - pointer to operand list from user
1196 * ****************************************************************************
1199 showLogicalUnit(int operandLen
, char *operand
[])
1201 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1202 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
1203 MP_PLUGIN_PROPERTIES pluginProps
;
1204 MP_OID luOid
, pluginOid
;
1208 for (op
= 0; op
< operandLen
; op
++) {
1210 (void) printf("\n");
1212 if (B_TRUE
== getLogicalUnitOid(operand
[op
], &luOid
)) {
1213 (void) memset(&luProps
, 0,
1214 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
1216 MP_GetMPLogicalUnitProperties(
1218 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1219 (void) fprintf(stderr
, "%s: %s\n",
1220 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1225 MP_GetAssociatedPluginOid(luOid
, &pluginOid
);
1226 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1227 (void) fprintf(stderr
, "%s: %s\n",
1229 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1234 MP_GetPluginProperties(pluginOid
, &pluginProps
);
1235 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1236 (void) fprintf(stderr
, "%s: %s\n",
1237 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1241 if (showIndividualLogicalUnit(luOid
, luProps
,
1242 pluginProps
) != 0) {
1243 return (ERROR_CLI_FAILED
);
1247 /* LINTED E_SEC_PRINTF_VAR_FMT */
1248 (void) fprintf(stderr
, getTextString(
1249 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1251 (void) printf("\n");
1254 } /* for each operand */
1261 * ****************************************************************************
1263 * showIndivudualLogicalUnit -
1264 * Used by show logical unit cli.
1265 * Displays info about an LU
1267 * luOid - LU to show
1268 * luProps - properties of he LU to show
1269 * pluginProps - propertis of the plugin this LU belongs to
1271 * ****************************************************************************
1274 showIndividualLogicalUnit(MP_OID luOid
,
1275 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
,
1276 MP_PLUGIN_PROPERTIES pluginProps
)
1278 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps
;
1279 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps
;
1280 MP_TARGET_PORT_PROPERTIES tportProps
;
1281 MP_INITIATOR_PORT_PROPERTIES initProps
;
1282 MP_OID_LIST
*pPathOidListArray
, *pTPGOidListArray
,
1283 *pTportOidListArray
;
1284 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1285 boolean_t showTportLabel
= B_TRUE
;
1289 (void) printf("%s ", getTextString(TEXT_LB_LOGICAL_UNIT
));
1290 displayArray(luProps
.deviceFileName
, sizeof (luProps
.deviceFileName
));
1291 (void) printf("\n");
1292 (void) printf("\t%s %s\n", getTextString(TEXT_LB_MPATH_SUPPORT
),
1293 pluginProps
.fileName
);
1295 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR
));
1296 displayArray(luProps
.vendor
,
1297 sizeof (luProps
.vendor
));
1298 (void) printf("\n\t%s ", getTextString(TEXT_LB_PRODUCT
));
1299 displayArray(luProps
.product
,
1300 sizeof (luProps
.product
));
1301 (void) printf("\n\t%s ", getTextString(TEXT_LB_REVISION
));
1302 displayArray(luProps
.revision
,
1303 sizeof (luProps
.revision
));
1304 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME_TYPE
));
1305 displayLogicalUnitNameTypeString(luProps
.nameType
);
1306 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME
));
1307 displayArray(luProps
.name
, sizeof (luProps
.name
));
1308 (void) printf("\n\t%s %s\n", getTextString(TEXT_LB_ASYMMETRIC
),
1309 (MP_TRUE
== luProps
.asymmetric
)?
1310 getTextString(TEXT_YES
):getTextString(TEXT_NO
));
1312 (void) printf("\t%s ", getTextString(TEXT_LB_CURR_LOAD_BALANCE
));
1313 /* don't ignore load balance type none. */
1314 if (luProps
.currentLoadBalanceType
== 0) {
1315 (void) printf("%s", getTextString(TEXT_LBTYPE_NONE
));
1317 displayLoadBalanceString(luProps
.currentLoadBalanceType
);
1319 (void) printf("\n");
1321 (void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID
));
1322 if (0xffffffff == luProps
.logicalUnitGroupID
) {
1323 (void) printf("%s\n", getTextString(TEXT_NA
));
1325 (void) printf("0x%x\n", luProps
.logicalUnitGroupID
);
1328 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB
));
1329 if (MP_FALSE
== pluginProps
.autoFailbackSupport
) {
1330 (void) printf("%s\n", getTextString(TEXT_NA
));
1332 (void) printf("%s\n", (MP_TRUE
== luProps
.autoFailbackEnabled
)?
1333 getTextString(TEXT_ON
):getTextString(TEXT_OFF
));
1336 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB
));
1337 if (MP_FALSE
== pluginProps
.autoProbingSupport
) {
1338 (void) printf("%s\n", getTextString(TEXT_NA
));
1340 (void) printf("%s\n", (MP_TRUE
== luProps
.autoProbingEnabled
)?
1341 getTextString(TEXT_ON
):getTextString(TEXT_OFF
));
1346 mpstatus
= MP_GetAssociatedPathOidList(luOid
, &pPathOidListArray
);
1347 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1348 (void) fprintf(stderr
, "%s: %s", cmdName
,
1349 getTextString(ERR_NO_LU_PATH_INFO
));
1350 displayArray(luProps
.deviceFileName
,
1351 sizeof (luProps
.deviceFileName
));
1352 (void) fprintf(stderr
, "\n");
1356 (void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO
));
1358 for (pa
= 0; pa
< pPathOidListArray
->oidCount
; pa
++) {
1359 (void) memset(&pathProps
, 0,
1360 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES
));
1361 mpstatus
= MP_GetPathLogicalUnitProperties(
1362 pPathOidListArray
->oids
[pa
], &pathProps
);
1363 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1364 (void) fprintf(stderr
, "%s: %s\n",
1365 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1369 (void) printf("\t\t%s ",
1370 getTextString(TEXT_LB_INIT_PORT_NAME
));
1372 MP_GetInitiatorPortProperties(pathProps
.initiatorPortOid
,
1373 &initProps
)) != MP_STATUS_SUCCESS
) {
1374 (void) printf("%s\n", getTextString(TEXT_UNKNOWN
));
1376 displayArray(initProps
.portID
,
1377 sizeof (initProps
.portID
));
1378 (void) printf("\n");
1381 (void) printf("\t\t%s ",
1382 getTextString(TEXT_LB_TARGET_PORT_NAME
));
1384 MP_GetTargetPortProperties(pathProps
.targetPortOid
,
1385 &tportProps
)) != MP_STATUS_SUCCESS
) {
1386 (void) printf("%s\n", getTextString(TEXT_UNKNOWN
));
1388 displayArray(tportProps
.portID
,
1389 sizeof (tportProps
.portID
));
1390 (void) printf("\n");
1393 (void) printf("\t\t%s ", getTextString(TEXT_LB_OVERRIDE_PATH
));
1394 if (MP_FALSE
== pluginProps
.canOverridePaths
) {
1395 (void) printf("%s\n", getTextString(TEXT_NA
));
1396 } else if (luProps
.overridePath
.objectSequenceNumber
==
1397 pPathOidListArray
->oids
[pa
].objectSequenceNumber
) {
1398 (void) printf("%s\n", getTextString(TEXT_YES
));
1400 (void) printf("%s\n", getTextString(TEXT_NO
));
1403 (void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE
),
1404 getPathStateStr(pathProps
.pathState
));
1406 (void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED
),
1407 pathProps
.disabled
?getTextString(TEXT_YES
):
1408 getTextString(TEXT_NO
));
1413 mpstatus
= MP_GetAssociatedTPGOidList(luOid
, &pTPGOidListArray
);
1414 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1415 (void) fprintf(stderr
, "%s: %s", cmdName
,
1416 getTextString(ERR_NO_ASSOC_TPGS
));
1419 /* display tpg info only if is assymetric */
1420 if (MP_TRUE
== luProps
.asymmetric
) {
1421 (void) printf("\t%s \n", getTextString(TEXT_LB_TPG_INFO
));
1424 for (tpg
= 0; tpg
< pTPGOidListArray
->oidCount
; tpg
++) {
1425 (void) memset(&tpgProps
, 0,
1426 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES
));
1427 mpstatus
= MP_GetTargetPortGroupProperties(
1428 pTPGOidListArray
->oids
[tpg
], &tpgProps
);
1429 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1430 (void) fprintf(stderr
, "%s: %s",
1431 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1433 /* display tpg info only if is assymetric */
1435 (void) printf("\n");
1437 if (MP_TRUE
== luProps
.asymmetric
) {
1438 (void) printf("\t\t%s %d\n",
1439 getTextString(TEXT_LB_ID
),
1441 (void) printf("\t\t%s %s\n",
1443 TEXT_LB_EXPLICIT_FAILOVER
),
1445 tpgProps
.explicitFailover
)?
1446 getTextString(TEXT_YES
):
1447 getTextString(TEXT_NO
));
1448 (void) printf("\t\t%s %s\n",
1450 TEXT_LB_ACCESS_STATE
),
1452 tpgProps
.accessState
));
1453 /* display label for each tpg. */
1454 (void) printf("\t\t%s\n",
1455 getTextString(TEXT_TPORT_LIST
));
1457 /* display label once for symmetric. */
1458 if (B_TRUE
== showTportLabel
) {
1459 /* begin back-up indentation */
1460 (void) printf("\t%s\n",
1461 getTextString(TEXT_TPORT_LIST
));
1462 showTportLabel
= B_FALSE
;
1463 /* end back-up indentation */
1467 /* get target port info */
1468 mpstatus
= MP_GetTargetPortOidList(
1469 pTPGOidListArray
->oids
[tpg
],
1470 &pTportOidListArray
);
1471 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1472 (void) fprintf(stderr
, "%s: %s",
1474 getTextString(ERR_NO_ASSOC_TPORTS
));
1477 /* begin back-up indentation */
1478 for (tport
= 0; tport
< pTportOidListArray
->oidCount
; tport
++) {
1479 (void) memset(&tportProps
, 0,
1480 sizeof (MP_TARGET_PORT_PROPERTIES
));
1482 MP_GetTargetPortProperties(pTportOidListArray
->oids
[tport
],
1483 &tportProps
)) != MP_STATUS_SUCCESS
) {
1484 (void) fprintf(stderr
, "%s: %s",
1485 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1487 if (MP_TRUE
== luProps
.asymmetric
) {
1488 (void) printf("\t\t\t%s ",
1489 getTextString(TEXT_LB_NAME
));
1490 displayArray(tportProps
.portID
,
1491 sizeof (tportProps
.portID
));
1492 (void) printf("\n\t\t\t%s %d\n",
1493 getTextString(TEXT_LB_RELATIVE_ID
),
1494 tportProps
.relativePortID
);
1496 (void) printf("\t\t%s ",
1497 getTextString(TEXT_LB_NAME
));
1498 displayArray(tportProps
.portID
,
1499 sizeof (tportProps
.portID
));
1500 (void) printf("\n\t\t%s %d\n",
1501 getTextString(TEXT_LB_RELATIVE_ID
),
1502 tportProps
.relativePortID
);
1504 /* insert blank line if not the last target port. */
1505 if (!(tport
== (pTportOidListArray
->oidCount
- 1))) {
1506 (void) printf("\n");
1509 } /* for each target port */
1510 /* end back-up indentation */
1512 } /* else got target port props */
1513 } /* else got TPG props */
1514 } /* for each TPG */
1515 } /* else got tpg list */
1523 * ****************************************************************************
1525 * modifyLogicalUnit -
1526 * mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ...
1528 * operandLen - number of operands user passed into the cli
1529 * operand - pointer to operand list from user
1530 * options - pointer to option list from user
1532 * ****************************************************************************
1535 modifyLogicalUnit(int operandLen
, char *operand
[], cmdOptions_t
*options
)
1537 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1539 cmdOptions_t
*optionList
= options
;
1540 char *cmdStr
= getTextString(TEXT_UNKNOWN
);
1543 for (op
= 0; op
< operandLen
; op
++) {
1544 if (B_TRUE
!= getLogicalUnitOid(operand
[op
], &luOid
)) {
1545 /* LINTED E_SEC_PRINTF_VAR_FMT */
1546 (void) fprintf(stderr
,
1547 getTextString(ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1549 (void) printf("\n");
1550 return (ERROR_CLI_FAILED
);
1553 /* we found the lu oid, now change the options requested */
1554 switch (optionList
->optval
) {
1556 /* modify autofailback */
1557 cmdStr
= getTextString(TEXT_AUTO_FAILBACK
);
1558 if (0 == strcasecmp(optionList
->optarg
,
1559 getTextString(TEXT_ON
))) {
1561 MP_EnableAutoFailback(luOid
);
1562 } else if (0 == strcasecmp(optionList
->optarg
,
1563 getTextString(TEXT_OFF
))) {
1565 MP_DisableAutoFailback(luOid
);
1567 /* begin back-up indentation */
1568 /* LINTED E_SEC_PRINTF_VAR_FMT */
1569 (void) fprintf(stderr
, getTextString(
1570 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
1571 cmdStr
, getTextString(
1572 TEXT_ILLEGAL_ARGUMENT
));
1573 (void) printf("\n");
1574 return (ERROR_CLI_FAILED
);
1575 /* start back-up indentation */
1579 /* modify autoprobing */
1580 cmdStr
= getTextString(TEXT_AUTO_PROBING
);
1581 if (0 == strcasecmp(optionList
->optarg
,
1582 getTextString(TEXT_ON
))) {
1584 MP_EnableAutoProbing(luOid
);
1585 } else if (0 == strcasecmp(optionList
->optarg
,
1586 getTextString(TEXT_OFF
))) {
1588 MP_DisableAutoProbing(luOid
);
1590 /* begin back-up indentation */
1591 /* LINTED E_SEC_PRINTF_VAR_FMT */
1592 (void) fprintf(stderr
, getTextString(
1593 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
1594 cmdStr
, getTextString(
1595 TEXT_ILLEGAL_ARGUMENT
));
1596 (void) printf("\n");
1597 return (ERROR_CLI_FAILED
);
1598 /* end back-up indentation */
1602 /* modify loadbalance type */
1603 cmdStr
= getTextString(TEXT_LOAD_BALANCE
);
1605 MP_SetLogicalUnitLoadBalanceType(luOid
,
1606 getLbValueFromString(optionList
->optarg
));
1610 if (MP_STATUS_SUCCESS
!= mpstatus
) {
1611 /* LINTED E_SEC_PRINTF_VAR_FMT */
1612 (void) fprintf(stderr
,
1614 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON
),
1615 cmdStr
, getMpStatusStr(mpstatus
));
1616 (void) printf("\n");
1617 return (ERROR_CLI_FAILED
);
1619 } /* for each operand */
1625 * ****************************************************************************
1627 * failoverLogicalUnit -
1628 * mpathadm failover {logical-unit | LU} <logical-unit name>, ...
1630 * operand - pointer to operand list from user
1632 * ****************************************************************************
1635 failoverLogicalUnit(char *operand
[])
1637 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1639 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
1640 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps
;
1641 MP_OID_LIST
*pTpgOidListArray
;
1642 boolean_t bFoundIt
= B_FALSE
;
1643 MP_TPG_STATE_PAIR tpgStatePair
;
1647 if (B_TRUE
!= getLogicalUnitOid(operand
[0], &luOid
)) {
1648 /* LINTED E_SEC_PRINTF_VAR_FMT */
1649 (void) fprintf(stderr
, getTextString(
1650 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR
),
1652 (void) printf("\n");
1653 return (ERROR_CLI_FAILED
);
1656 /* get LUN properties and check to be sure it's asymmetric */
1657 (void) memset(&luProps
, 0,
1658 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
1660 MP_GetMPLogicalUnitProperties(luOid
, &luProps
);
1661 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1662 (void) fprintf(stderr
, "%s: %s\n",
1663 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1667 if (MP_TRUE
!= luProps
.asymmetric
) {
1668 (void) fprintf(stderr
, "%s: %s\n",
1669 cmdName
, getTextString(ERR_LU_NOT_ASYMMETRIC
));
1670 return (ERROR_CLI_FAILED
);
1673 /* get TPGs for this LUN */
1675 MP_GetAssociatedTPGOidList(luOid
, &pTpgOidListArray
);
1676 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1677 (void) fprintf(stderr
, "%s: %s\n",
1678 cmdName
, getTextString(ERR_NO_ASSOC_TPGS
));
1682 /* pick a TPG whose state is active or standby, and change it */
1683 /* to opposite via MP_SetTPGAccessState */
1685 for (tpg
= 0; tpg
< pTpgOidListArray
->oidCount
; tpg
++) {
1686 (void) memset(&tpgProps
, 0,
1687 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES
));
1689 MP_GetTargetPortGroupProperties(
1690 pTpgOidListArray
->oids
[tpg
], &tpgProps
);
1691 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1692 (void) fprintf(stderr
, "%s: %s\n",
1693 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1694 return (ERROR_CLI_FAILED
);
1696 if (MP_FALSE
== tpgProps
.explicitFailover
) {
1697 (void) fprintf(stderr
, "%s: %s\n",
1698 cmdName
, getTextString(ERR_NO_FAILOVER_ALLOWED
));
1699 return (ERROR_CLI_FAILED
);
1702 /* find one that is standby */
1703 if ((MP_ACCESS_STATE_STANDBY
==
1704 tpgProps
.accessState
) && (B_FALSE
== bFoundIt
)) {
1708 tpgStatePair
.tpgOid
=
1709 pTpgOidListArray
->oids
[tpg
];
1710 tpgStatePair
.desiredState
=
1711 MP_ACCESS_STATE_ACTIVE
;
1713 MP_SetTPGAccess(luOid
, 1, &tpgStatePair
);
1714 if (MP_STATUS_SUCCESS
!= mpstatus
) {
1715 /* begin back-up indentation */
1716 /* LINTED E_SEC_PRINTF_VAR_FMT */
1717 (void) fprintf(stderr
, getTextString(
1718 ERR_FAILED_TO_FAILOVER_WITH_REASON
),
1719 getMpStatusStr(mpstatus
));
1720 (void) printf("\n");
1722 /* end back-up indentation */
1727 } /* for each tpg */
1729 if (B_FALSE
== bFoundIt
) {
1730 (void) fprintf(stderr
, "%s: %s\n",
1731 cmdName
, getTextString(ERR_LU_ACCESS_STATE_UNCHANGED
));
1732 return (ERROR_CLI_FAILED
);
1740 * ****************************************************************************
1742 * getLogicalUnitOid -
1743 * Search through all plugins and get the OID for specified logical unit
1745 * luFileName - file name of LU (specified by the user) to find
1746 * pLuOid - OID to return
1748 * ****************************************************************************
1751 getLogicalUnitOid(MP_CHAR
*luFileName
, MP_OID
*pluOid
)
1753 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1754 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
1755 MP_PLUGIN_PROPERTIES pluginProps
;
1756 MP_OID_LIST
*pPluginOidList
, *pLogicalUnitOidList
;
1757 boolean_t foundIt
= B_FALSE
;
1762 ddi_devid_t devid1
, devid2
;
1764 if (NULL
== pluOid
) {
1765 /* print some kind of error msg here - should never happen */
1766 /* LINTED E_SEC_PRINTF_VAR_FMT */
1767 (void) fprintf(stderr
, getTextString(ERR_MEMORY_ALLOCATION
));
1768 (void) printf("\n");
1772 pluOid
->objectSequenceNumber
= 0;
1773 pluOid
->objectType
= 0;
1774 pluOid
->ownerId
= 0;
1776 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
1777 != MP_STATUS_SUCCESS
) {
1778 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1779 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1782 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
1783 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1784 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1785 return (ERROR_CLI_FAILED
);
1787 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
1789 /* get properties so we can list the name */
1790 (void) memset(&pluginProps
, 0, sizeof (MP_PLUGIN_PROPERTIES
));
1792 MP_GetPluginProperties(pPluginOidList
->oids
[i
],
1793 &pluginProps
)) != MP_STATUS_SUCCESS
) {
1794 (void) fprintf(stderr
, "%s: %s\n",
1795 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1799 /* attempt to find this logical unit */
1800 mpstatus
= MP_GetMultipathLus(pPluginOidList
->oids
[i
],
1801 &pLogicalUnitOidList
);
1802 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1803 (void) fprintf(stderr
, "%s: %s\n",
1804 cmdName
, getTextString(ERR_NO_LU_LIST
));
1808 for (lu
= 0; (lu
< pLogicalUnitOidList
->oidCount
) &&
1809 (B_FALSE
== foundIt
); lu
++) {
1811 /* get lu properties so we can check the name */
1812 (void) memset(&luProps
, 0,
1813 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
1815 MP_GetMPLogicalUnitProperties(
1816 pLogicalUnitOidList
->oids
[lu
], &luProps
);
1817 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1818 (void) fprintf(stderr
, "%s: %s\n",
1819 cmdName
, getTextString(ERR_NO_PROPERTIES
));
1823 if (compareLUName(luFileName
, luProps
.deviceFileName
)
1827 /* user input didn't match, try via devid */
1829 * I don't see a reason to print the error for
1830 * any of these since they'll get the error at
1835 devid1
= devid2
= NULL
;
1836 if (((fd1
= open(luFileName
,
1837 O_RDONLY
|O_NDELAY
)) >= 0) &&
1838 ((fd2
= open(luProps
.deviceFileName
,
1839 O_RDONLY
|O_NDELAY
)) >= 0) &&
1840 (devid_get(fd1
, &devid1
) == 0) &&
1841 (devid_get(fd2
, &devid2
) == 0) &&
1842 ((NULL
!= devid1
) && (NULL
!= devid2
))) {
1844 (devid_compare(devid1
, devid2
))) {
1849 if (NULL
!= devid1
) {
1852 if (NULL
!= devid2
) {
1863 if (B_TRUE
== foundIt
) {
1864 pluOid
->objectSequenceNumber
=
1865 pLogicalUnitOidList
->
1866 oids
[lu
].objectSequenceNumber
;
1867 pluOid
->objectType
=
1868 pLogicalUnitOidList
->
1869 oids
[lu
].objectType
;
1871 pLogicalUnitOidList
->oids
[lu
].ownerId
;
1881 * ****************************************************************************
1883 * listInitiatorPort -
1884 * mpathadm list initiator-port [<initiator-port name>, ...]
1886 * operandLen - number of operands user passed into the cli
1887 * operand - pointer to operand list from user
1889 * ****************************************************************************
1892 listInitiatorPort(int operandLen
, char *operand
[])
1894 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
1895 MP_INITIATOR_PORT_PROPERTIES initProps
;
1896 MP_OID_LIST
*pPluginOidList
, *pInitOidList
;
1897 boolean_t bListIt
= B_FALSE
;
1902 foundOp
= malloc((sizeof (boolean_t
)) * operandLen
);
1903 if (NULL
== foundOp
) {
1904 (void) fprintf(stdout
, "%s\n",
1905 getTextString(ERR_MEMORY_ALLOCATION
));
1906 return (ERROR_CLI_FAILED
);
1909 for (ol
= 0; ol
< operandLen
; ol
++) {
1910 foundOp
[ol
] = B_FALSE
;
1913 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
1914 != MP_STATUS_SUCCESS
) {
1915 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1916 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1919 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
1920 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1921 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
1922 return (ERROR_CLI_FAILED
);
1925 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
1927 MP_GetInitiatorPortOidList(pPluginOidList
->oids
[i
],
1929 if (mpstatus
!= MP_STATUS_SUCCESS
) {
1930 /* LINTED E_SEC_PRINTF_VAR_FMT */
1931 (void) fprintf(stderr
,
1932 getTextString(ERR_NO_INIT_PORT_LIST_WITH_REASON
),
1933 getMpStatusStr(mpstatus
));
1934 (void) printf("\n");
1935 } else if ((NULL
== pInitOidList
) ||
1936 (pInitOidList
->oidCount
< 1)) {
1937 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1938 getTextString(ERR_NO_INIT_PORTS
));
1941 iport
< pInitOidList
->oidCount
; iport
++) {
1944 MP_GetInitiatorPortProperties(
1945 pInitOidList
->oids
[iport
],
1946 &initProps
)) != MP_STATUS_SUCCESS
) {
1947 (void) fprintf(stderr
,
1948 "%s: %s\n", cmdName
,
1949 getTextString(ERR_NO_PROPERTIES
));
1951 /* if no operands listed, */
1952 /* list all we find */
1953 if (0 == operandLen
) {
1957 /* check each operand */
1959 /* the one we want to list? */
1961 ol
< operandLen
; ol
++) {
1975 if (B_TRUE
== bListIt
) {
1977 if (listIndividualInitiatorPort(
1979 return (ERROR_CLI_FAILED
);
1984 } /* for each initiator port */
1985 } /* else found an init port */
1987 } /* for each plugin */
1989 for (ol
= 0; ol
< operandLen
; ol
++) {
1990 if (B_FALSE
== foundOp
[ol
]) {
1991 /* LINTED E_SEC_PRINTF_VAR_FMT */
1992 (void) fprintf(stderr
, getTextString(
1993 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR
),
1995 (void) printf("\n");
2004 * ****************************************************************************
2006 * listIndividualInitiatorPort -
2007 * used by listInitiatorPort to list info for one init port
2009 * initProps - properties of initiator port to list
2011 * ****************************************************************************
2014 listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps
)
2016 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2018 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT
));
2019 displayArray(initProps
.portID
,
2020 sizeof (initProps
.portID
));
2021 (void) printf("\n");
2029 * ****************************************************************************
2031 * showInitiatorPort -
2032 * mpathadm show initiator-port <initiator-port name>, ...
2034 * operandLen - number of operands user passed into the cli
2035 * operand - pointer to operand list from user
2037 * ****************************************************************************
2040 showInitiatorPort(int operandLen
, char *operand
[])
2042 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2043 MP_INITIATOR_PORT_PROPERTIES initProps
;
2044 MP_OID_LIST
*pPluginOidList
, *pInitOidList
;
2045 boolean_t bListIt
= B_FALSE
, bFoundIt
= B_FALSE
;
2048 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
2049 != MP_STATUS_SUCCESS
) {
2050 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2051 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
2054 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
2055 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2056 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
2057 return (ERROR_CLI_FAILED
);
2060 for (op
= 0; op
< operandLen
; op
++) {
2063 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
2066 MP_GetInitiatorPortOidList(pPluginOidList
->oids
[i
],
2068 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2069 /* LINTED E_SEC_PRINTF_VAR_FMT */
2070 (void) fprintf(stderr
,
2072 ERR_NO_INIT_PORT_LIST_WITH_REASON
),
2073 getMpStatusStr(mpstatus
));
2074 (void) printf("\n");
2075 } else if ((NULL
== pInitOidList
) ||
2076 (pInitOidList
->oidCount
< 1)) {
2077 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2078 getTextString(ERR_NO_INIT_PORTS
));
2082 iport
< pInitOidList
->oidCount
;
2087 MP_GetInitiatorPortProperties(
2088 pInitOidList
->oids
[iport
],
2090 != MP_STATUS_SUCCESS
) {
2091 /* begin back-up indentation */
2092 (void) fprintf(stderr
,
2093 "%s: %s\n", cmdName
,
2094 getTextString(ERR_NO_PROPERTIES
));
2095 /* end back-up indentation */
2097 if (0 == strcmp(operand
[op
],
2098 initProps
.portID
)) {
2104 if (B_TRUE
== bListIt
) {
2106 showIndividualInitiatorPort(
2108 if (0 != mpstatus
) {
2114 } /* for each initiator port */
2115 } /* else found an init port */
2117 } /* for each plugin */
2119 if (B_FALSE
== bFoundIt
) {
2120 /* need temp string here since we need to fill in a */
2121 /* name in the error string */
2122 /* LINTED E_SEC_PRINTF_VAR_FMT */
2123 (void) fprintf(stderr
, getTextString(
2124 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR
),
2126 (void) printf("\n");
2129 } /* for each operand */
2136 * ****************************************************************************
2138 * showIndividualInitiatorPort -
2139 * used by showInitiatorPort to show info for one init port
2141 * initProps - properties of initiator port to show
2143 * ****************************************************************************
2146 showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps
)
2148 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2150 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT
));
2151 displayArray(initProps
.portID
,
2152 sizeof (initProps
.portID
));
2154 (void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE
));
2155 displayTransportTypeString(initProps
.portType
);
2156 (void) printf("\n");
2158 (void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE
));
2159 displayArray(initProps
.osDeviceFile
,
2160 sizeof (initProps
.osDeviceFile
));
2161 (void) printf("\n");
2168 * ****************************************************************************
2171 * mpathadm enable path -i <initiator-port>
2172 * -t <target-port name> -l <logical-unit name>
2174 * options - pointer to option list from user
2176 * ****************************************************************************
2179 enablePath(cmdOptions_t
*options
)
2181 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2184 cmdOptions_t
*optionList
= options
;
2185 boolean_t bHaveInit
= B_FALSE
, bHaveTarg
= B_FALSE
, bHaveLu
= B_FALSE
;
2187 for (; optionList
->optval
; optionList
++) {
2188 switch (optionList
->optval
) {
2190 /* have init port name */
2194 /* have target port id */
2203 if (B_FALSE
== bHaveInit
) {
2204 /* LINTED E_SEC_PRINTF_VAR_FMT */
2205 (void) fprintf(stderr
,
2206 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON
),
2207 getTextString(MISSING_INIT_PORT_NAME
));
2208 (void) printf("\n");
2209 return (ERROR_CLI_FAILED
);
2210 } else if (B_FALSE
== bHaveTarg
) {
2211 /* LINTED E_SEC_PRINTF_VAR_FMT */
2212 (void) fprintf(stderr
,
2213 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON
),
2214 getTextString(MISSING_TARGET_PORT_NAME
));
2215 (void) printf("\n");
2216 return (ERROR_CLI_FAILED
);
2217 } else if (B_FALSE
== bHaveLu
) {
2218 /* LINTED E_SEC_PRINTF_VAR_FMT */
2219 (void) fprintf(stderr
,
2220 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON
),
2221 getTextString(MISSING_LU_NAME
));
2222 (void) printf("\n");
2223 return (ERROR_CLI_FAILED
);
2226 if (B_FALSE
== getPathOid(options
, &pathOid
)) {
2227 /* LINTED E_SEC_PRINTF_VAR_FMT */
2228 (void) fprintf(stderr
,
2229 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON
),
2230 getTextString(FAILED_TO_FIND_PATH
));
2231 (void) printf("\n");
2232 return (ERROR_CLI_FAILED
);
2235 /* found the path, attempt to enable it */
2236 mpstatus
= MP_EnablePath(pathOid
);
2237 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2238 /* LINTED E_SEC_PRINTF_VAR_FMT */
2239 (void) fprintf(stderr
,
2240 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON
),
2241 getMpStatusStr(mpstatus
));
2242 (void) printf("\n");
2251 * ****************************************************************************
2254 * mpathadm disable path -i <initiator-port>
2255 * -t <target-port name> -l <logical-unit name>
2257 * options - pointer to option list from user
2259 * ****************************************************************************
2262 disablePath(cmdOptions_t
*options
)
2264 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2267 cmdOptions_t
*optionList
= options
;
2268 boolean_t bHaveInit
= B_FALSE
, bHaveTarg
= B_FALSE
,
2271 for (; optionList
->optval
; optionList
++) {
2272 switch (optionList
->optval
) {
2274 /* have init port name */
2278 /* have target port id */
2287 if (B_FALSE
== bHaveInit
) {
2288 /* LINTED E_SEC_PRINTF_VAR_FMT */
2289 (void) fprintf(stderr
,
2290 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON
),
2291 getTextString(MISSING_INIT_PORT_NAME
));
2292 (void) printf("\n");
2293 return (ERROR_CLI_FAILED
);
2294 } else if (B_FALSE
== bHaveTarg
) {
2295 /* LINTED E_SEC_PRINTF_VAR_FMT */
2296 (void) fprintf(stderr
,
2297 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON
),
2298 getTextString(MISSING_TARGET_PORT_NAME
));
2299 (void) printf("\n");
2300 return (ERROR_CLI_FAILED
);
2301 } else if (B_FALSE
== bHaveLu
) {
2302 /* LINTED E_SEC_PRINTF_VAR_FMT */
2303 (void) fprintf(stderr
,
2304 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON
),
2305 getTextString(MISSING_LU_NAME
));
2306 (void) printf("\n");
2307 return (ERROR_CLI_FAILED
);
2310 if (B_FALSE
== getPathOid(options
, &pathOid
)) {
2311 /* LINTED E_SEC_PRINTF_VAR_FMT */
2312 (void) fprintf(stderr
,
2313 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON
),
2314 getTextString(FAILED_TO_FIND_PATH
));
2315 (void) printf("\n");
2316 return (ERROR_CLI_FAILED
);
2319 /* found the path, attempt to enable it */
2320 mpstatus
= MP_DisablePath(pathOid
);
2321 if (MP_STATUS_SUCCESS
!= mpstatus
) {
2322 /* LINTED E_SEC_PRINTF_VAR_FMT */
2323 (void) fprintf(stderr
, getTextString(
2324 ERR_FAILED_TO_DISABLE_PATH_WITH_REASON
),
2325 getMpStatusStr(mpstatus
));
2326 (void) printf("\n");
2336 * ****************************************************************************
2339 * mpathadm override path {-i <initiator-port>
2340 * -t <target-port name> | -c} <logical-unit name>
2342 * options - pointer to option list from user
2344 * ****************************************************************************
2347 overridePath(cmdOptions_t
*options
)
2349 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2350 MP_OID pathOid
, luOid
;
2351 boolean_t bCancelOverride
= B_FALSE
;
2352 MP_CHAR pLuDeviceFileName
[256];
2353 cmdOptions_t
*optionList
= options
;
2355 /* First check to see if we have the cancel option, */
2356 /* May as well save off the lun while we're at it */
2357 for (; optionList
->optval
; optionList
++) {
2358 switch (optionList
->optval
) {
2360 /* we have a cancel */
2361 bCancelOverride
= B_TRUE
;
2364 /* we have a lun- save it while we're here */
2365 (void) memcpy(pLuDeviceFileName
,
2366 optionList
->optarg
, 256);
2371 if (B_TRUE
== bCancelOverride
) {
2372 /* if we have the cancel option, */
2373 if (getLogicalUnitOid(pLuDeviceFileName
, &luOid
) == B_FALSE
) {
2374 /* LINTED E_SEC_PRINTF_VAR_FMT */
2375 (void) fprintf(stderr
,
2377 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON
),
2378 getTextString(LU_NOT_FOUND
));
2379 (void) printf("\n");
2380 return (ERROR_CLI_FAILED
);
2383 /* cancel the override path for the specified LU */
2384 mpstatus
= MP_CancelOverridePath(luOid
);
2385 if (MP_STATUS_SUCCESS
!= mpstatus
) {
2386 /* LINTED E_SEC_PRINTF_VAR_FMT */
2387 (void) fprintf(stderr
,
2389 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON
),
2390 getMpStatusStr(mpstatus
));
2391 (void) printf("\n");
2395 /* must be wanting to override the path */
2396 if (getLogicalUnitOid(pLuDeviceFileName
, &luOid
) == B_FALSE
) {
2397 /* LINTED E_SEC_PRINTF_VAR_FMT */
2398 (void) fprintf(stderr
,
2400 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2401 getTextString(LU_NOT_FOUND
));
2402 (void) printf("\n");
2403 return (ERROR_CLI_FAILED
);
2406 if (B_FALSE
== getPathOid(options
, &pathOid
)) {
2407 /* LINTED E_SEC_PRINTF_VAR_FMT */
2408 (void) fprintf(stderr
,
2410 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2411 getTextString(FAILED_TO_FIND_PATH
));
2413 (void) printf("\n");
2414 return (ERROR_CLI_FAILED
);
2417 /* attempt to set the override path */
2418 mpstatus
= MP_SetOverridePath(luOid
, pathOid
);
2419 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2420 /* LINTED E_SEC_PRINTF_VAR_FMT */
2421 (void) fprintf(stderr
,
2423 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON
),
2424 getMpStatusStr(mpstatus
));
2425 (void) printf("\n");
2435 * ****************************************************************************
2438 * Search through all plugins and get the OID for specified path
2440 * operand - pointer to operand list from user
2441 * options - pointer to option list from user
2443 * ****************************************************************************
2446 getPathOid(cmdOptions_t
*options
, MP_OID
*pPathOid
)
2448 MP_STATUS mpstatus
= MP_STATUS_SUCCESS
;
2449 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps
;
2450 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps
;
2451 MP_INITIATOR_PORT_PROPERTIES initProps
;
2452 MP_TARGET_PORT_PROPERTIES targProps
;
2454 MP_OID_LIST
*pPluginOidList
, *pLogicalUnitOidList
,
2457 boolean_t bFoundIt
= B_FALSE
;
2458 MP_CHAR initPortID
[256];
2459 MP_CHAR targetPortID
[256];
2460 MP_CHAR luDeviceFileName
[256];
2461 boolean_t bHaveTarg
= B_FALSE
, bHaveLu
= B_FALSE
,
2462 bHaveInit
= B_FALSE
;
2463 cmdOptions_t
*optionList
= options
;
2466 if (NULL
== pPathOid
) {
2470 for (; optionList
->optval
; optionList
++) {
2471 switch (optionList
->optval
) {
2473 /* save init port name */
2474 (void) memcpy(initPortID
,
2475 optionList
->optarg
, 256);
2479 /* save target port id */
2480 (void) memcpy(targetPortID
,
2481 optionList
->optarg
, 256);
2486 (void) memcpy(luDeviceFileName
,
2487 optionList
->optarg
, 256);
2494 if ((B_FALSE
== bHaveInit
) ||
2495 (B_FALSE
== bHaveTarg
) ||
2496 (B_FALSE
== bHaveLu
)) {
2497 /* if we don't have all three pieces, we can't find the path */
2502 /* get the plugin ist */
2503 if ((mpstatus
= MP_GetPluginOidList(&pPluginOidList
))
2504 != MP_STATUS_SUCCESS
) {
2505 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2506 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
2509 if ((NULL
== pPluginOidList
) || (pPluginOidList
->oidCount
< 1)) {
2510 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2511 getTextString(ERR_NO_MPATH_SUPPORT_LIST
));
2515 for (i
= 0; i
< pPluginOidList
->oidCount
; i
++) {
2517 /* get Logical Unit list */
2518 mpstatus
= MP_GetMultipathLus(pPluginOidList
->oids
[i
],
2519 &pLogicalUnitOidList
);
2520 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2521 (void) fprintf(stderr
, "%s: %s\n",
2522 cmdName
, getTextString(ERR_NO_LU_LIST
));
2526 for (lu
= 0; (lu
< pLogicalUnitOidList
->oidCount
) &&
2527 (B_FALSE
== bFoundIt
); lu
++) {
2529 /* get lu properties so we can check the name */
2530 (void) memset(&luProps
, 0,
2531 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
2533 MP_GetMPLogicalUnitProperties(
2534 pLogicalUnitOidList
->oids
[lu
], &luProps
);
2535 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2536 (void) fprintf(stderr
, "%s: %s\n",
2537 cmdName
, getTextString(ERR_NO_PROPERTIES
));
2540 if (compareLUName(luDeviceFileName
,
2541 luProps
.deviceFileName
) == B_TRUE
) {
2542 /* get paths for this LU and search from here */
2544 MP_GetAssociatedPathOidList(
2545 pLogicalUnitOidList
->oids
[lu
],
2547 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2548 /* LINTED E_SEC_PRINTF_VAR_FMT */
2549 (void) fprintf(stderr
,
2551 ERR_FAILED_TO_FIND_PATH
));
2552 (void) printf("\n");
2557 (pa
< pathOidListArray
->oidCount
) &&
2558 (B_FALSE
== bFoundIt
); pa
++) {
2560 MP_GetPathLogicalUnitProperties
2561 (pathOidListArray
->oids
[pa
],
2563 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2564 (void) fprintf(stderr
,
2565 "%s: %s\n", cmdName
,
2567 ERR_NO_PROPERTIES
));
2572 * get properties of iniator port and
2573 * target port to see if we have the
2577 MP_GetInitiatorPortProperties(
2578 pathProps
.initiatorPortOid
,
2581 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2582 (void) fprintf(stderr
,
2583 "%s: %s\n", cmdName
,
2585 ERR_NO_PROPERTIES
));
2588 if (0 == strcmp(initPortID
, initProps
.portID
)) {
2589 /* lu and init port matches, check target port */
2590 mpstatus
= MP_GetTargetPortProperties(pathProps
.targetPortOid
,
2592 if (mpstatus
!= MP_STATUS_SUCCESS
) {
2593 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
2594 getTextString(ERR_NO_PROPERTIES
));
2598 if (0 == strcmp(targetPortID
, targProps
.portID
)) {
2599 /* we found our path */
2600 pPathOid
->objectSequenceNumber
=
2601 pathOidListArray
->oids
[pa
].objectSequenceNumber
;
2602 pPathOid
->objectType
=
2603 pathOidListArray
->oids
[pa
].objectType
;
2604 pPathOid
->ownerId
= pathOidListArray
->oids
[pa
].ownerId
;
2607 } /* init port matched */
2609 } /* for each path associated with this lu */
2615 } /* for each plugin */
2622 * ****************************************************************************
2624 * getLbValueFromString
2625 * Gets the MP_LOAD_BALANCE_TYPE specified load balance type string
2627 * lbStr - load balance string defined in the .h file
2628 * This is what users will be required to feed into the
2629 * modify lu command.
2631 * ****************************************************************************
2633 MP_LOAD_BALANCE_TYPE
2634 getLbValueFromString(char *lbStr
)
2636 MP_LOAD_BALANCE_TYPE lbVal
= MP_LOAD_BALANCE_TYPE_UNKNOWN
;
2638 if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_ROUNDROBIN
))) {
2639 lbVal
= MP_LOAD_BALANCE_TYPE_ROUNDROBIN
;
2640 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_LEASTBLOCKS
))) {
2641 lbVal
= MP_LOAD_BALANCE_TYPE_LEASTBLOCKS
;
2642 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_LEASTIO
))) {
2643 lbVal
= MP_LOAD_BALANCE_TYPE_LEASTIO
;
2644 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_DEVICEPROD
))) {
2645 lbVal
= MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT
;
2646 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_LBAREGION
))) {
2647 lbVal
= MP_LOAD_BALANCE_TYPE_LBA_REGION
;
2648 } else if (0 == strcmp(lbStr
,
2649 getTextString(TEXT_LBTYPE_FAILOVER_ONLY
))) {
2650 lbVal
= MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY
;
2651 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_UNKNOWN
))) {
2652 lbVal
= MP_LOAD_BALANCE_TYPE_UNKNOWN
;
2653 } else if (0 == strcmp(lbStr
, getTextString(TEXT_LBTYPE_NONE
))) {
2655 } else if (0 == strcmp(lbStr
,
2656 getTextString(TEXT_LBTYPE_PROPRIETARY1
))) {
2657 lbVal
= ((MP_UINT32
)0x00000001)<<16;
2658 } else if (0 == strcmp(lbStr
,
2659 getTextString(TEXT_LBTYPE_PROPRIETARY2
))) {
2660 lbVal
= ((MP_UINT32
)0x00000001)<<17;
2661 } else if (0 == strcmp(lbStr
,
2662 getTextString(TEXT_LBTYPE_PROPRIETARY3
))) {
2663 lbVal
= ((MP_UINT32
)0x00000001)<<18;
2664 } else if (0 == strcmp(lbStr
,
2665 getTextString(TEXT_LBTYPE_PROPRIETARY4
))) {
2666 lbVal
= ((MP_UINT32
)0x00000001)<<19;
2667 } else if (0 == strcmp(lbStr
,
2668 getTextString(TEXT_LBTYPE_PROPRIETARY5
))) {
2669 lbVal
= ((MP_UINT32
)0x00000001)<<20;
2670 } else if (0 == strcmp(lbStr
,
2671 getTextString(TEXT_LBTYPE_PROPRIETARY6
))) {
2672 lbVal
= ((MP_UINT32
)0x00000001)<<21;
2673 } else if (0 == strcmp(lbStr
,
2674 getTextString(TEXT_LBTYPE_PROPRIETARY7
))) {
2675 lbVal
= ((MP_UINT32
)0x00000001)<<22;
2676 } else if (0 == strcmp(lbStr
,
2677 getTextString(TEXT_LBTYPE_PROPRIETARY8
))) {
2678 lbVal
= ((MP_UINT32
)0x00000001)<<23;
2679 } else if (0 == strcmp(lbStr
,
2680 getTextString(TEXT_LBTYPE_PROPRIETARY9
))) {
2681 lbVal
= ((MP_UINT32
)0x00000001)<<24;
2682 } else if (0 == strcmp(lbStr
,
2683 getTextString(TEXT_LBTYPE_PROPRIETARY10
))) {
2684 lbVal
= ((MP_UINT32
)0x00000001)<<25;
2685 } else if (0 == strcmp(lbStr
,
2686 getTextString(TEXT_LBTYPE_PROPRIETARY11
))) {
2687 lbVal
= ((MP_UINT32
)0x00000001)<<26;
2688 } else if (0 == strcmp(lbStr
,
2689 getTextString(TEXT_LBTYPE_PROPRIETARY12
))) {
2690 lbVal
= ((MP_UINT32
)0x00000001)<<27;
2691 } else if (0 == strcmp(lbStr
,
2692 getTextString(TEXT_LBTYPE_PROPRIETARY13
))) {
2693 lbVal
= ((MP_UINT32
)0x00000001)<<28;
2694 } else if (0 == strcmp(lbStr
,
2695 getTextString(TEXT_LBTYPE_PROPRIETARY14
))) {
2696 lbVal
= ((MP_UINT32
)0x00000001)<<29;
2697 } else if (0 == strcmp(lbStr
,
2698 getTextString(TEXT_LBTYPE_PROPRIETARY15
))) {
2699 lbVal
= ((MP_UINT32
)0x00000001)<<30;
2700 } else if (0 == strcmp(lbStr
,
2701 getTextString(TEXT_LBTYPE_PROPRIETARY16
))) {
2702 lbVal
= ((MP_UINT32
)0x00000001)<<31;
2708 } /* end getLbValueFromString */
2712 * ****************************************************************************
2714 * displayLogicalUnitNameTypeString
2715 * Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE
2716 * specified load balance type
2718 * typeVal - load balance type defined in the MPAPI spec
2720 * ****************************************************************************
2723 displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal
)
2730 case MP_LU_NAME_TYPE_UNKNOWN
:
2731 typeString
= getTextString(TEXT_NAME_TYPE_UNKNOWN
);
2733 case MP_LU_NAME_TYPE_VPD83_TYPE1
:
2734 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE1
);
2736 case MP_LU_NAME_TYPE_VPD83_TYPE2
:
2737 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE2
);
2739 case MP_LU_NAME_TYPE_VPD83_TYPE3
:
2740 typeString
= getTextString(TEXT_NAME_TYPE_VPD83_TYPE3
);
2742 case MP_LU_NAME_TYPE_DEVICE_SPECIFIC
:
2744 getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC
);
2747 typeString
= getTextString(TEXT_UNKNOWN
);
2751 (void) printf("%s", typeString
);
2754 } /* end displayLogicalUnitNameTypeString */
2757 * ****************************************************************************
2759 * displayLoadBalanceString
2760 * Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE
2761 * specified load balance type
2763 * lbVal - load balance type defined in the MPAPI spec
2765 * ****************************************************************************
2768 displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal
)
2775 case MP_LOAD_BALANCE_TYPE_UNKNOWN
:
2776 lbString
= getTextString(TEXT_LBTYPE_UNKNOWN
);
2778 case MP_LOAD_BALANCE_TYPE_ROUNDROBIN
:
2779 lbString
= getTextString(TEXT_LBTYPE_ROUNDROBIN
);
2781 case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS
:
2782 lbString
= getTextString(TEXT_LBTYPE_LEASTBLOCKS
);
2784 case MP_LOAD_BALANCE_TYPE_LEASTIO
:
2785 lbString
= getTextString(TEXT_LBTYPE_LEASTIO
);
2787 case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT
:
2788 lbString
= getTextString(TEXT_LBTYPE_DEVICEPROD
);
2790 case MP_LOAD_BALANCE_TYPE_LBA_REGION
:
2791 lbString
= getTextString(TEXT_LBTYPE_LBAREGION
);
2793 case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY
:
2794 lbString
= getTextString(TEXT_LBTYPE_FAILOVER_ONLY
);
2796 case (((MP_UINT32
)0x00000001)<<16):
2797 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY1
);
2799 case (((MP_UINT32
)0x00000001)<<17):
2800 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY2
);
2802 case (((MP_UINT32
)0x00000001)<<18):
2803 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY3
);
2805 case (((MP_UINT32
)0x00000001)<<19):
2806 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY4
);
2808 case (((MP_UINT32
)0x00000001)<<20):
2809 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY5
);
2811 case (((MP_UINT32
)0x00000001)<<21):
2812 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY6
);
2814 case (((MP_UINT32
)0x00000001)<<22):
2815 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY7
);
2817 case (((MP_UINT32
)0x00000001)<<23):
2818 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY8
);
2820 case (((MP_UINT32
)0x00000001)<<24):
2821 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY9
);
2823 case (((MP_UINT32
)0x00000001)<<25):
2824 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY10
);
2826 case (((MP_UINT32
)0x00000001)<<26):
2827 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY11
);
2829 case (((MP_UINT32
)0x00000001)<<27):
2830 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY12
);
2832 case (((MP_UINT32
)0x00000001)<<28):
2833 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY13
);
2835 case (((MP_UINT32
)0x00000001)<<29):
2836 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY14
);
2838 case (((MP_UINT32
)0x00000001)<<30):
2839 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY15
);
2841 case (((MP_UINT32
)0x00000001)<<31):
2842 lbString
= getTextString(TEXT_LBTYPE_PROPRIETARY16
);
2845 lbString
= getTextString(TEXT_UNKNOWN
);
2849 (void) printf("%s", lbString
);
2852 } /* end displayLoadBalanceString */
2855 * ****************************************************************************
2857 * displayTransportTypeString
2858 * Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE
2859 * specified load balance type
2861 * transportTypeVal - transport type defined in the MPAPI spec
2863 * ****************************************************************************
2866 displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal
)
2870 switch (transportTypeVal
) {
2872 case MP_PORT_TRANSPORT_TYPE_MPNODE
:
2874 getTextString(TEXT_TRANS_PORT_TYPE_MPNODE
);
2876 case MP_PORT_TRANSPORT_TYPE_FC
:
2877 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_FC
);
2879 case MP_PORT_TRANSPORT_TYPE_SPI
:
2880 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_SPI
);
2882 case MP_PORT_TRANSPORT_TYPE_ISCSI
:
2883 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_ISCSI
);
2885 case MP_PORT_TRANSPORT_TYPE_IFB
:
2886 ttypeString
= getTextString(TEXT_TRANS_PORT_TYPE_IFB
);
2889 ttypeString
= getTextString(TEXT_UNKNOWN
);
2893 (void) printf("%s", ttypeString
);
2895 } /* end displayTransportTypeString */
2899 * ****************************************************************************
2902 * Gets the string description for the specified load balance type value
2904 * mpstatus - MP_STATUS value
2906 * ****************************************************************************
2909 getMpStatusStr(MP_STATUS mpstatus
)
2914 case MP_STATUS_SUCCESS
:
2915 statString
= getTextString(TEXT_MPSTATUS_SUCCESS
);
2917 case MP_STATUS_INVALID_PARAMETER
:
2918 statString
= getTextString(TEXT_MPSTATUS_INV_PARAMETER
);
2920 case MP_STATUS_UNKNOWN_FN
:
2921 statString
= getTextString(TEXT_MPSTATUS_UNKNOWN_FN
);
2923 case MP_STATUS_FAILED
:
2924 statString
= getTextString(TEXT_MPSTATUS_FAILED
);
2926 case MP_STATUS_INSUFFICIENT_MEMORY
:
2927 statString
= getTextString(TEXT_MPSTATUS_INSUFF_MEMORY
);
2929 case MP_STATUS_INVALID_OBJECT_TYPE
:
2930 statString
= getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE
);
2932 case MP_STATUS_UNSUPPORTED
:
2933 statString
= getTextString(TEXT_MPSTATUS_UNSUPPORTED
);
2935 case MP_STATUS_OBJECT_NOT_FOUND
:
2936 statString
= getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND
);
2938 case MP_STATUS_ACCESS_STATE_INVALID
:
2939 statString
= getTextString(TEXT_MPSTATUS_UNSUPPORTED
);
2941 case MP_STATUS_FN_REPLACED
:
2942 statString
= getTextString(TEXT_MPSTATUS_FN_REPLACED
);
2944 case MP_STATUS_PATH_NONOPERATIONAL
:
2945 statString
= getTextString(TEXT_MPSTATUS_PATH_NONOP
);
2947 case MP_STATUS_TRY_AGAIN
:
2948 statString
= getTextString(TEXT_MPSTATUS_TRY_AGAIN
);
2950 case MP_STATUS_NOT_PERMITTED
:
2951 statString
= getTextString(TEXT_MPSTATUS_NOT_PERMITTED
);
2954 statString
= getTextString(TEXT_UNKNOWN
);
2958 return (statString
);
2959 } /* end getMpStatusStr */
2963 * ****************************************************************************
2966 * Gets the string description for the specified path state type value
2968 * pathState - MP_PATH_STATE values
2970 * ****************************************************************************
2973 getPathStateStr(MP_PATH_STATE pathState
)
2977 switch (pathState
) {
2978 case MP_PATH_STATE_OKAY
:
2979 pathString
= getTextString(TEXT_PATH_STATE_OKAY
);
2981 case MP_PATH_STATE_PATH_ERR
:
2982 pathString
= getTextString(TEXT_PATH_STATE_PATH_ERR
);
2984 case MP_PATH_STATE_LU_ERR
:
2985 pathString
= getTextString(TEXT_PATH_STATE_LU_ERR
);
2987 case MP_PATH_STATE_RESERVED
:
2988 pathString
= getTextString(TEXT_PATH_STATE_RESERVED
);
2990 case MP_PATH_STATE_REMOVED
:
2991 pathString
= getTextString(TEXT_PATH_STATE_REMOVED
);
2993 case MP_PATH_STATE_TRANSITIONING
:
2995 getTextString(TEXT_PATH_STATE_TRANSITIONING
);
2997 case MP_PATH_STATE_OPERATIONAL_CLOSED
:
2999 getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED
);
3001 case MP_PATH_STATE_INVALID_CLOSED
:
3003 getTextString(TEXT_PATH_STATE_INVALID_CLOSED
);
3005 case MP_PATH_STATE_OFFLINE_CLOSED
:
3007 getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED
);
3010 pathString
= getTextString(TEXT_UNKNOWN
);
3014 return (pathString
);
3015 } /* end getPathStateStr */
3020 * ****************************************************************************
3023 * Gets the string description for the specified access state type value
3025 * accessState - MP_ACCESS_STATE_TYPE values
3027 * ****************************************************************************
3030 getAccessStateStr(MP_ACCESS_STATE_TYPE accessState
)
3034 switch (accessState
) {
3035 case MP_ACCESS_STATE_ACTIVE_OPTIMIZED
:
3037 getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED
);
3039 case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED
:
3042 TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED
);
3044 case MP_ACCESS_STATE_STANDBY
:
3046 getTextString(TEXT_ACCESS_STATE_STANDBY
);
3048 case MP_ACCESS_STATE_UNAVAILABLE
:
3050 getTextString(TEXT_ACCESS_STATE_UNAVAILABLE
);
3052 case MP_ACCESS_STATE_TRANSITIONING
:
3054 getTextString(TEXT_ACCESS_STATE_TRANSITIONING
);
3056 case MP_ACCESS_STATE_ACTIVE
:
3057 accessString
= getTextString(TEXT_ACCESS_STATE_ACTIVE
);
3060 accessString
= getTextString(TEXT_UNKNOWN
);
3063 return (accessString
);
3064 } /* end getAccessStateStr */
3068 * ****************************************************************************
3071 * Print out the specified array.
3073 * arrayToDisplay - array to display
3074 * arraySize - size of array to display
3076 * ****************************************************************************
3079 displayArray(MP_CHAR
*arrayToDisplay
, int arraySize
)
3083 for (i
= 0; i
< arraySize
; i
++) {
3084 if ('\0' != arrayToDisplay
[i
]) {
3085 (void) fprintf(stdout
, "%c", arrayToDisplay
[i
]);
3093 * ****************************************************************************
3096 * Return a null terminated array for the specified array as a string,
3097 * This is used for inputting into the %s in formatted strings.
3099 * arrayToDisplay - array to display
3100 * arraySize - size of array to display
3102 * ****************************************************************************
3105 getStringArray(MP_CHAR
*arrayToDisplay
, int arraySize
)
3111 newStr
= malloc(((sizeof (MP_CHAR
)) * arraySize
) + 1);
3112 if (NULL
== newStr
) {
3113 (void) fprintf(stdout
, "%s\n",
3114 getTextString(ERR_MEMORY_ALLOCATION
));
3117 for (i
= 0; i
< arraySize
; i
++) {
3118 newStr
[i
] = arrayToDisplay
[i
];
3120 newStr
[arraySize
] = '\0';
3128 * ****************************************************************************
3131 * Print out the specified wide character array as a string,
3132 * adding the null termination
3134 * arrayToDisplay - array to display
3135 * arraySize - size of array to display
3137 * ****************************************************************************
3140 displayWideArray(MP_WCHAR
*arrayToDisplay
, int arraySize
)
3143 int numChars
= arraySize
/4;
3145 for (i
= 0; i
< numChars
; i
++) {
3146 if (L
'\0' != arrayToDisplay
[i
]) {
3147 (void) fprintf(stdout
, "%wc", (int)arrayToDisplay
[i
]);
3154 * ****************************************************************************
3157 * Used by cmdparse for list clis
3159 * ****************************************************************************
3163 listFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3170 ret
= listMpathSupport(operandLen
, operand
);
3173 ret
= listLogicalUnit(operandLen
, operand
, options
);
3175 case INITIATOR_PORT
:
3176 ret
= listInitiatorPort(operandLen
, operand
);
3179 (void) fprintf(stderr
, "%s: %s\n",
3180 cmdName
, getTextString(TEXT_UNKNOWN_OBJECT
));
3190 * ****************************************************************************
3193 * used bycmdparse for show clis
3195 * ****************************************************************************
3199 showFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3206 ret
= showMpathSupport(operandLen
, operand
);
3209 ret
= showLogicalUnit(operandLen
, operand
);
3211 case INITIATOR_PORT
:
3212 ret
= showInitiatorPort(operandLen
, operand
);
3224 * ****************************************************************************
3227 * Used by cmdparse for midify clis
3230 * ****************************************************************************
3234 modifyFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3241 ret
= modifyMpathSupport(operandLen
, operand
, options
);
3244 ret
= modifyLogicalUnit(operandLen
, operand
, options
);
3257 * ****************************************************************************
3260 * Used by cmdpars for enable clis
3262 * ****************************************************************************
3266 enableFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3273 ret
= enablePath(options
);
3285 * ****************************************************************************
3288 * Used by cmdpars for disable clis
3290 * ****************************************************************************
3294 disableFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3301 ret
= disablePath(options
);
3313 * ****************************************************************************
3316 * Used by cmdpars for failover clis
3318 * ****************************************************************************
3322 failoverFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
3329 ret
= failoverLogicalUnit(operand
);
3341 * ****************************************************************************
3344 * Used by cmdpars for override clis
3346 * ****************************************************************************
3350 overrideFunc(int operandLen
, char *operand
[],
3351 int object
, cmdOptions_t
*options
,
3358 ret
= overridePath(options
);
3371 * *************************************************************************
3375 * *************************************************************************
3378 main(int argc
, char *argv
[])
3380 synTables_t synTables
;
3381 char versionString
[VERSION_STRING_MAX_LEN
];
3384 void *subcommandArgs
= NULL
;
3386 /* set global command name */
3387 cmdName
= getExecBasename(argv
[0]);
3389 (void) sprintf(versionString
, "%2s.%2s",
3390 VERSION_STRING_MAJOR
, VERSION_STRING_MINOR
);
3391 synTables
.versionString
= versionString
;
3392 synTables
.longOptionTbl
= &longOptions
[0];
3393 synTables
.subcommandTbl
= &subcommands
[0];
3394 synTables
.objectTbl
= &objects
[0];
3395 synTables
.objectRulesTbl
= &objectRules
[0];
3396 synTables
.optionRulesTbl
= &optionRules
[0];
3398 ret
= cmdParse(argc
, argv
, /* SUB_COMMAND_ISSUED, */ synTables
,
3399 subcommandArgs
, &funcRet
);
3401 (void) fprintf(stdout
, "%s %s(1M)\n",
3402 getTextString(TEXT_MORE_INFO
), cmdName
);
3403 return (ERROR_CLI_FAILED
);
3404 } else if (ret
== -1) {
3410 (void) fprintf(stderr
, "%s: %s\n",
3411 argv
[0], getTextString(TEXT_UNABLE_TO_COMPLETE
));