mpathadm.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* mpathadm.c : MP API CLI program
*
*/
#include <libintl.h>
#include <mpapi.h>
#include "cmdparse.h"
#include "mpathadm_text.h"
#include "mpathadm.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <devid.h>
#include <fcntl.h>
/* helper functions */
static char *getExecBasename(char *);
/* object functions per subcommand */
static int listFunc(int, char **, int, cmdOptions_t *, void *);
static int showFunc(int, char **, int, cmdOptions_t *, void *);
static int modifyFunc(int, char **, int, cmdOptions_t *, void *);
static int enableFunc(int, char **, int, cmdOptions_t *, void *);
static int disableFunc(int, char **, int, cmdOptions_t *, void *);
static int failoverFunc(int, char **, int, cmdOptions_t *, void *);
static int overrideFunc(int, char **, int, cmdOptions_t *, void *);
#define VERSION_STRING_MAX_LEN 10
#define OPTIONSTRING_NAME "name"
#define OPTIONSTRING_TPNAME "target-port name"
#define OPTIONSTRING_ONOFF "on/off"
#define OPTIONSTRING_LBTYPE "loadbalance type"
#define OPTIONSTRING_IPORT "initiator-port name"
#define OPTIONSTRING_LUNIT "logical-unit name"
#define OPTIONSTRING_CANCEL "cancel"
#define OPTIONSTRING_VALUE "value"
/*
* Version number: (copied from iscsiadm)
* MAJOR - This should only change when there is an incompatible change made
* to the interfaces or the output.
*
* MINOR - This should change whenever there is a new command or new feature
* with no incompatible change.
*/
#define VERSION_STRING_MAJOR "1"
#define VERSION_STRING_MINOR "0"
/* globals */
static char *cmdName;
/*
* ****************************************************************************
*
* getExecBasename - copied from iscsiadm code
*
* input:
* execFullName - exec name of program (argv[0])
*
* Returns:
* command name portion of execFullName
*
* ****************************************************************************
*/
static char *
getExecBasename(char *execFullname)
{
char *lastSlash, *execBasename;
/* guard against '/' at end of command invocation */
for (;;) {
lastSlash = strrchr(execFullname, '/');
if (lastSlash == NULL) {
execBasename = execFullname;
break;
} else {
execBasename = lastSlash + 1;
if (*execBasename == '\0') {
*lastSlash = '\0';
continue;
}
break;
}
}
return (execBasename);
}
/*
* Add new options here
*/
/* tables set up based on cmdparse instructions */
optionTbl_t longOptions[] = {
{"inqname", required_arg, 'n', OPTIONSTRING_NAME},
{"target-port", required_arg, 't', OPTIONSTRING_TPNAME},
{"autofailback", required_arg, 'a', OPTIONSTRING_ONOFF},
{"autoprobe", required_arg, 'p', OPTIONSTRING_ONOFF},
{"loadbalance", required_arg, 'b', OPTIONSTRING_LBTYPE},
{"initiator-port", required_arg, 'i', OPTIONSTRING_IPORT},
{"logical-unit", required_arg, 'l', OPTIONSTRING_LUNIT},
{"cancel", no_arg, 'c', OPTIONSTRING_CANCEL},
{"vendor-id", required_arg, 'd', OPTIONSTRING_VALUE},
{NULL, 0, 0, 0}
};
/*
* Add new subcommands here
*/
subcommand_t subcommands[] = {
{"list", LIST, listFunc},
{"show", SHOW, showFunc},
{"modify", MODIFY, modifyFunc},
{"enable", ENABLE, enableFunc},
{"disable", DISABLE, disableFunc},
{"failover", FAILOVER, failoverFunc},
{"override", OVERRIDE, overrideFunc},
{NULL, 0, NULL}
};
/*
* Add objects here
*/
object_t objects[] = {
{"mpath-support", MPATH_SUPPORT},
{"logical-unit", LOGICAL_UNIT},
{"LU", LOGICAL_UNIT},
{"initiator-port", INITIATOR_PORT},
{"path", PATH},
{NULL, 0}
};
/*
* Rules for subcommands and objects
*
* command
*
* reqOpCmd -> subcommands that must have an operand
* optOpCmd -> subcommands that may have an operand
* noOpCmd -> subcommands that will have no operand
* invCmd -> subcommands that are invalid
* multOpCmd -> subcommands that can accept multiple operands
* operandDefinition -> Usage definition for the operand of this object
*/
objectRules_t objectRules[] = {
{MPATH_SUPPORT, SHOW|MODIFY|ADD, LIST|REMOVE, 0,
ENABLE|DISABLE|FAILOVER|OVERRIDE, LIST|SHOW|MODIFY,
"mpath-support name"},
{INITIATOR_PORT, SHOW, LIST, 0,
MODIFY|ENABLE|DISABLE|FAILOVER|OVERRIDE|ADD|REMOVE, LIST|SHOW,
"initiator-port name"},
{LOGICAL_UNIT, SHOW|MODIFY|FAILOVER, LIST, 0,
ENABLE|DISABLE|OVERRIDE|ADD|REMOVE, LIST|SHOW|MODIFY,
"logical-unit name"},
{PATH, 0, 0, ENABLE|DISABLE|OVERRIDE,
SHOW|LIST|MODIFY|FAILOVER|ADD|REMOVE, 0,
"initiator-port name"},
{0, 0, 0, 0, 0, NULL}
};
/*
* list of objects, subcommands, valid short options, required flag and
* exclusive option string
*
* If it's not here, there are no options for that object.
*/
optionRules_t optionRules[] = {
{LOGICAL_UNIT, LIST, "nt", B_FALSE, NULL},
{LOGICAL_UNIT, MODIFY, "apb", B_TRUE, NULL},
{MPATH_SUPPORT, MODIFY, "apb", B_TRUE, NULL},
{MPATH_SUPPORT, ADD, "d", B_TRUE, NULL},
{MPATH_SUPPORT, REMOVE, "d", B_TRUE, NULL},
{PATH, ENABLE, "itl", B_TRUE, NULL},
{PATH, DISABLE, "itl", B_TRUE, NULL},
{PATH, OVERRIDE, "itlc", B_TRUE, NULL},
{0, 0, 0, 0, 0}
};
/*
* ****************************************************************************
*
* listMpathSupport - mpathadm list mpath-support
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
listMpathSupport(int operandLen, char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_PLUGIN_PROPERTIES pluginProps;
MP_OID_LIST *pPluginOidList;
boolean_t shown = B_FALSE;
/* number of plugins listed */
int i,
op;
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
/* loop through operands first */
for (op = 0; (op < operandLen) |
((0 == operandLen) && (B_FALSE == shown)); op++) {
shown = B_TRUE;
for (i = 0; i < pPluginOidList->oidCount; i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
mpstatus =
MP_GetPluginProperties(pPluginOidList->oids[i],
&pluginProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
} else {
if (0 == operandLen) {
/* if no operands, list them all */
(void) printf("%s %s\n",
getTextString(
TEXT_LB_MPATH_SUPPORT),
pluginProps.fileName);
} else {
/* if there is an operand... */
/* ... compare and display if match */
if (0 ==
strcmp(operand[op],
pluginProps.fileName)) {
(void) printf("%s %s\n",
getTextString(
TEXT_LB_MPATH_SUPPORT),
pluginProps.fileName);
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME),
operand[op]);
(void) printf("\n");
}
}
}
}
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* showMpathSupport - mpathadm show mpath-support <mpath-support name>, ...
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
showMpathSupport(int operandLen, char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_PLUGIN_PROPERTIES pluginProps;
MP_OID_LIST *pPluginOidList;
MP_OID_LIST *deviceOidListArray;
MP_DEVICE_PRODUCT_PROPERTIES devProps;
boolean_t bListIt = B_FALSE;
int op,
i,
j;
MP_LOAD_BALANCE_TYPE lb;
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) !=
MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (op = 0; op < operandLen; op++) {
bListIt = B_FALSE;
for (i = 0; i < pPluginOidList->oidCount; i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
mpstatus =
MP_GetPluginProperties(pPluginOidList->oids[i],
&pluginProps);
if (MP_STATUS_SUCCESS != mpstatus) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
if (0 == operandLen) {
/* if no operand, list it */
bListIt = B_TRUE;
} else {
/* ... compare and display if match */
if (0 ==
strcmp(operand[op],
pluginProps.fileName)) {
bListIt = B_TRUE;
}
}
if (B_TRUE != bListIt) {
break;
}
(void) printf("%s %s\n",
getTextString(TEXT_LB_MPATH_SUPPORT),
pluginProps.fileName);
/* display the info for this plugin */
(void) printf("\t%s ", getTextString(TEXT_LB_VENDOR));
displayWideArray(pluginProps.vendor,
sizeof (pluginProps.vendor));
(void) printf("\n\t%s ",
getTextString(TEXT_LB_DRIVER_NAME));
displayArray(pluginProps.driverName,
sizeof (pluginProps.driverName));
(void) printf("\n\t%s ",
getTextString(TEXT_LB_DEFAULT_LB));
/* don't ignore load balance type none. */
if (pluginProps.defaultloadBalanceType == 0) {
(void) printf("%s",
getTextString(TEXT_LBTYPE_NONE));
} else {
displayLoadBalanceString(
pluginProps.defaultloadBalanceType);
}
(void) printf("\n");
(void) printf("\t%s \n",
getTextString(TEXT_LB_SUPPORTED_LB));
/* check each bit, display string if found set */
if (pluginProps.supportedLoadBalanceTypes == 0) {
(void) printf("\t\t%s\n",
getTextString(TEXT_LBTYPE_NONE));
} else {
lb = 1;
do {
if (0 != (lb &
pluginProps.supportedLoadBalanceTypes)) {
(void) printf("\t\t");
displayLoadBalanceString(lb &
pluginProps.supportedLoadBalanceTypes);
(void) printf("\n");
}
lb = lb<<1;
} while (lb < 0x80000000);
}
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_ALLOWS_ACT_TPG),
(MP_TRUE == pluginProps.canSetTPGAccess)?
getTextString(TEXT_YES):getTextString(TEXT_NO));
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_ALLOWS_PATH_OV),
(MP_TRUE == pluginProps.canOverridePaths)?
getTextString(TEXT_YES):getTextString(TEXT_NO));
(void) printf("\t%s %d\n",
getTextString(TEXT_LB_SUPP_AUTO_FB),
pluginProps.autoFailbackSupport);
if ((MP_AUTOFAILBACK_SUPPORT_PLUGIN ==
pluginProps.autoFailbackSupport) |
(MP_AUTOFAILBACK_SUPPORT_PLUGINANDMPLU
== pluginProps.autoFailbackSupport)) {
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_AUTO_FB),
pluginProps.pluginAutoFailbackEnabled?\
getTextString(TEXT_ON):
getTextString(TEXT_OFF));
(void) printf("\t%s %d/%d\n",
getTextString(TEXT_LB_FB_POLLING_RATE),
pluginProps.currentFailbackPollingRate,
pluginProps.failbackPollingRateMax);
} else {
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_AUTO_FB),
getTextString(TEXT_NA));
(void) printf("\t%s %s/%s\n",
getTextString(TEXT_LB_FB_POLLING_RATE),
getTextString(TEXT_NA),
getTextString(TEXT_NA));
}
(void) printf("\t%s %d\n",
getTextString(TEXT_LB_SUPP_AUTO_P),
pluginProps.autoProbingSupport);
if ((MP_AUTOPROBING_SUPPORT_PLUGIN ==
pluginProps.autoProbingSupport) |
(MP_AUTOPROBING_SUPPORT_PLUGIN ==
pluginProps.autoProbingSupport)) {
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_AUTO_PROB),
(MP_TRUE ==
pluginProps.pluginAutoProbingEnabled)?\
getTextString(TEXT_YES):
getTextString(TEXT_NO));
(void) printf("\t%s %d/%d\n",
getTextString(TEXT_LB_PR_POLLING_RATE),
pluginProps.currentProbingPollingRate,
pluginProps.probingPollingRateMax);
} else {
(void) printf("\t%s %s\n",
getTextString(TEXT_LB_AUTO_PROB),
getTextString(TEXT_NA));
(void) printf("\t%s %s/%s\n",
getTextString(TEXT_LB_PR_POLLING_RATE),
getTextString(TEXT_NA),
getTextString(TEXT_NA));
}
(void) printf("\t%s\n",
getTextString(TEXT_LB_SUPP_DEVICES));
if (MP_TRUE !=
pluginProps.onlySupportsSpecifiedProducts) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf(getTextString(TEXT_ANY_DEVICE));
} else {
/* if only supports specific products, */
/* get device product properties supported */
mpstatus = MP_GetDeviceProductOidList(\
pPluginOidList->oids[i],
&deviceOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(
ERR_NO_SUPP_DEVICE_INFO));
/* can't get any more info, */
/* so we're done with this one */
break;
}
for (j = 0; j < deviceOidListArray->oidCount;
j++) {
(void) memset(&devProps, 0,
sizeof (MP_DEVICE_PRODUCT_PROPERTIES));
if ((mpstatus =
MP_GetDeviceProductProperties(\
deviceOidListArray->oids[j],
&devProps)) == MP_STATUS_SUCCESS) {
(void) printf("\t\t%s ",
getTextString(
TEXT_LB_VENDOR));
displayArray(devProps.vendor,
sizeof (devProps.vendor));
(void) printf("\n\t\t%s ",
getTextString(
TEXT_LB_PRODUCT));
displayArray(devProps.product,
sizeof (devProps.product));
(void) printf("\n\t\t%s ",
getTextString(
TEXT_LB_REVISION));
displayArray(devProps.revision,
sizeof (devProps.revision));
(void) printf("\n\t\t%s\n",
getTextString(
TEXT_LB_SUPPORTED_LB));
if (devProps.supportedLoadBalanceTypes == 0) {
(void) printf("\t\t\t%s\n",
getTextString(TEXT_LBTYPE_NONE));
} else {
lb = 1;
do {
if (0 != (lb &
devProps.supportedLoadBalanceTypes)) {
(void) printf("\t\t\t");
displayLoadBalanceString(lb &
devProps.supportedLoadBalanceTypes);
(void) printf("\n");
}
lb = lb<<1;
} while (lb < 0x80000000);
}
(void) printf("\n");
} else {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(
ERR_NO_SUPP_DEVICE_INFO));
}
} /* for j */
} /* if only supports specified devices */
} /* for each plugin */
if (B_FALSE == bListIt) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME),
operand[op]);
(void) printf("\n");
}
} /* for each operand */
return (mpstatus);
}
/*
* ****************************************************************************
*
* modifyMpathSupport -
* mpathadm modify mpath-support [options] <mpath-support name>, ...
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
modifyMpathSupport(int operandLen, char *operand[], cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_PLUGIN_PROPERTIES pluginProps;
MP_OID_LIST *pPluginOidList;
boolean_t bFoundIt = B_FALSE;
MP_OID pluginOid;
cmdOptions_t *optionList = options;
char *cmdStr =
getTextString(
TEXT_UNKNOWN);
int op,
i,
lbValue;
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (op = 0; op < operandLen; op++) {
bFoundIt = B_FALSE;
for (i = 0;
(i < pPluginOidList->oidCount) && (B_TRUE != bFoundIt);
i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
if ((mpstatus =
MP_GetPluginProperties(pPluginOidList->oids[i],
&pluginProps)) == MP_STATUS_SUCCESS) {
if (0 == strcmp(operand[op],
pluginProps.fileName)) {
bFoundIt = B_TRUE;
pluginOid = pPluginOidList->oids[i];
}
} else {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
}
if (B_FALSE == bFoundIt) {
break;
}
/* begin back-up indentation */
/* we found the plugin oid */
/* now change the options requested */
switch (optionList->optval) {
case 'a':
/* modify autofailback */
cmdStr = getTextString(TEXT_AUTO_FAILBACK);
if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_ON))) {
mpstatus =
MP_EnableAutoFailback(pluginOid);
} else if (0 ==
strcasecmp(optionList->optarg,
getTextString(TEXT_OFF))) {
mpstatus =
MP_DisableAutoFailback(pluginOid);
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr,
getTextString(TEXT_ILLEGAL_ARGUMENT));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'p':
/* modify autoprobing */
cmdStr = getTextString(TEXT_AUTO_PROBING);
if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_ON))) {
mpstatus =
MP_EnableAutoProbing(pluginOid);
} else if (0 ==
strcasecmp(optionList->optarg,
getTextString(TEXT_OFF))) {
mpstatus =
MP_DisableAutoProbing(pluginOid);
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr,
getTextString(TEXT_ILLEGAL_ARGUMENT));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'b':
/* modify loadbalance type */
cmdStr = getTextString(TEXT_LOAD_BALANCE);
/* user of the cli sends text string, we need the int */
/* value to pass to the mpapi */
lbValue = getLbValueFromString(optionList->optarg);
mpstatus =
MP_SetPluginLoadBalanceType(pluginOid,
lbValue);
break;
} /* switch */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr, getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
/* end back-up indentation */
} /* for each plugin */
if (B_FALSE == bFoundIt) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr,
getTextString(TEXT_MPATH_SUPPORT_NOT_FOUND));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
} /* for each operand */
return (mpstatus);
}
/*
* ****************************************************************************
*
* listLogicalUnit -
* mpathadm list {logical-unit | LU} [options] [<logical-unit name>, ...]
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
listLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
MP_PLUGIN_PROPERTIES pluginProps;
MP_TARGET_PORT_PROPERTIES tportProps;
MP_OID_LIST *pPluginOidList,
*pLogicalUnitOidList,
*pTpgOidListArray,
*pTportOidListArray;
boolean_t bListIt = B_FALSE,
bFoundOperand = B_FALSE,
*bFoundOption,
bContinue = B_FALSE;
MP_OID luOid;
cmdOptions_t *optionList = options;
int opListCount = 0,
i = 0,
lu = 0,
tpg = 0,
opoffset = 0,
j = 0,
opStart = 0,
opEnd = 0,
opIndex;
/* count number of options */
for (; optionList->optval; optionList++) {
opListCount++;
}
bFoundOption = malloc((sizeof (boolean_t)) * opListCount);
if (NULL == bFoundOption) {
(void) fprintf(stdout, "%s\n",
getTextString(ERR_MEMORY_ALLOCATION));
return (ERROR_CLI_FAILED);
}
/* list to keep track of multiple options */
optionList = options;
for (opIndex = 0; opIndex < opListCount; opIndex++) {
bFoundOption[opIndex] = B_FALSE;
}
optionList = options;
/* if no operands or options, list everything we find */
if ((0 == operandLen) && (0 == opListCount)) {
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) ||
(pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
/* get properties so we can list the name */
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
if ((mpstatus =
MP_GetPluginProperties(pPluginOidList->oids[i],
&pluginProps)) != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
/* attempt to find this logical unit */
mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
&pLogicalUnitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_LU_LIST));
return (mpstatus);
}
for (lu = 0; lu < pLogicalUnitOidList->oidCount; lu++) {
/* get lu properties so we can check the name */
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(
pLogicalUnitOidList->oids[lu],
&luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
luOid = pLogicalUnitOidList->oids[lu];
if (listIndividualLogicalUnit(luOid, luProps)
!= 0) {
return (ERROR_CLI_FAILED);
}
} /* for each LU */
} /* for each plugin */
} else { /* we have operands and/or options */
/* check if we have operands */
if (0 == operandLen) {
/* no operands */
opStart = -1;
opEnd = 0;
} else {
/* operands */
opStart = 0;
opEnd = operandLen;
}
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) ||
(pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (opoffset = opStart; opoffset < opEnd; opoffset++) {
/* loop through operands */
bFoundOperand = B_FALSE;
for (i = 0; i < pPluginOidList->oidCount; i++) {
/*
* loop through plugin, and get properties
* so we can list the name
*/
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
if ((mpstatus =
MP_GetPluginProperties(
pPluginOidList->oids[i], &pluginProps))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
/* attempt to find this logical unit */
mpstatus =
MP_GetMultipathLus(pPluginOidList->oids[i],
&pLogicalUnitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_LU_LIST));
return (mpstatus);
}
for (lu = 0;
(lu < pLogicalUnitOidList->oidCount);
lu++) {
bListIt = B_FALSE;
/* get lu props & check the name */
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(
pLogicalUnitOidList->oids[lu],
&luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(
ERR_NO_PROPERTIES));
return (mpstatus);
}
/*
* compare operand - is it a match?
* If so, continue
*/
bContinue = B_TRUE;
if (operandLen > 0) {
bContinue =
compareLUName(
operand[opoffset],
luProps.deviceFileName);
}
if (B_TRUE == bContinue) {
if (0 != opListCount) {
/* check options */
/* begin backup indentation */
optionList = options;
for (opIndex = 0; optionList->optval; optionList++, opIndex++) {
switch (optionList->optval) {
case 'n':
if (B_TRUE ==
compareLUName(optionList->optarg, luProps.name)) {
bListIt = B_TRUE;
bFoundOperand = B_TRUE;
bFoundOption[opIndex] = B_TRUE;
}
break;
case 't':
/* get TPG list */
mpstatus =
MP_GetAssociatedTPGOidList(pLogicalUnitOidList->oids[lu],
&pTpgOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_ASSOC_TPGS));
return (mpstatus);
}
/* get target ports */
for (tpg = 0;
(NULL != pTpgOidListArray) &&
(tpg < pTpgOidListArray->oidCount) &&
(B_FALSE == bListIt); tpg++) {
mpstatus =
MP_GetTargetPortOidList(pTpgOidListArray->oids[tpg],
&pTportOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_ASSOC_TPORTS));
return (mpstatus);
}
/* get target port properties for the name */
for (j = 0; (NULL != pTportOidListArray) &&
(j < pTportOidListArray->oidCount) &&
(B_FALSE == bListIt); j++) {
(void) memset(&tportProps, 0,
sizeof (MP_TARGET_PORT_PROPERTIES));
mpstatus =
MP_GetTargetPortProperties(
pTportOidListArray->oids[j], &tportProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
/* check the name */
if (0 == strcmp(optionList->optarg,
tportProps.portID)) {
bListIt = B_TRUE;
bFoundOperand = B_TRUE;
bFoundOption[opIndex] = B_TRUE;
}
} /* for each target port */
} /* for each tpg */
} /* end switch */
} /* loop through options */
/* end back-up indentation */
} else {
/*
* if no options,
* listit
*/
bListIt = B_TRUE;
bFoundOperand = B_TRUE;
}
} /* end bContinue check */
if (bListIt) {
(void) printf("%s %s\n",
getTextString(TEXT_LB_MPATH_SUPPORT),
pluginProps.fileName);
luOid = pLogicalUnitOidList->oids[lu];
if (listIndividualLogicalUnit(luOid, luProps)
!= 0) {
return (ERROR_CLI_FAILED);
}
}
} /* end LU loop */
} /* end plugin loop */
if ((0 == opListCount) && (0 != operandLen)) {
if (B_FALSE == bFoundOperand) {
/* option/operand combo not found */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
operand[opoffset]);
(void) fprintf(stderr, "\n");
}
}
optionList = options;
for (opIndex = 0; optionList->optval; optionList++,
opIndex++) {
if (B_FALSE == bFoundOption[opIndex]) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
optionList->optarg);
(void) fprintf(stderr, "\n");
}
}
} /* end loop through operands */
} /* we have operands and/or options */
return (mpstatus);
}
/*
* ****************************************************************************
*
* compareLUName -
* compare names directly and via devid if no match directly
*
* cmpString - first string to compare
* deviceProperty - string from properties
* sizeToCompare - size of deviceProperty
*
* returns B_TRUE if the strings match either directly or via devid
* B_FALSE otherwise
*
* ****************************************************************************
*/
boolean_t
compareLUName(MP_CHAR *cmpString, MP_CHAR *deviceProperty)
{
boolean_t isSame = B_FALSE;
int fd1, fd2;
ddi_devid_t devid1 = NULL, devid2 = NULL;
if (0 == strcmp(cmpString, deviceProperty)) {
isSame = B_TRUE;
} else {
/* user input didn't match, try via devid */
/*
* I don't see a reason to print the error for
* any of these since they'll get the error at
* the end anyway
*/
if (((fd1 = open(cmpString, O_RDONLY|O_NDELAY)) >= 0) &&
((fd2 = open(deviceProperty, O_RDONLY|O_NDELAY)) >= 0) &&
(devid_get(fd1, &devid1) == 0) &&
(devid_get(fd2, &devid2) == 0) &&
((NULL != devid1) && (NULL != devid2))) {
if (0 ==
(devid_compare(devid1, devid2))) {
isSame = B_TRUE;
}
}
if (NULL != devid1) {
devid_free(devid1);
}
if (NULL != devid2) {
devid_free(devid2);
}
} /* compare */
return (isSame);
}
/*
* ****************************************************************************
*
* listIndivudualLogicalUnit -
* Used by list logical unit cli.
* Displays info about an LU
*
* luOid - LU to list
* luProps - properties of he LU to list
*
* ****************************************************************************
*/
int
listIndividualLogicalUnit(MP_OID luOid,
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps)
{
MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
MP_OID_LIST *pPathOidListArray;
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
int numOperationalPaths,
pa;
(void) printf("\t");
displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName));
(void) printf("\n");
mpstatus = MP_GetAssociatedPathOidList(luOid,
&pPathOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_NO_LU_PATH_INFO_WITH_MISSING_LU_STR),
getStringArray(luProps.deviceFileName,
sizeof (luProps.deviceFileName)));
(void) fprintf(stderr, "\n");
return (mpstatus);
}
(void) printf("\t\t%s %d\n",
getTextString(TEXT_LB_PATH_COUNT), pPathOidListArray->oidCount);
numOperationalPaths = 0;
for (pa = 0; pa < pPathOidListArray->oidCount; pa++) {
(void) memset(&pathProps, 0,
sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetPathLogicalUnitProperties(
pPathOidListArray->oids[pa], &pathProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
/* cycle through and check status of each for */
/* operation path count */
if (MP_PATH_STATE_OKAY == pathProps.pathState) {
numOperationalPaths++;
}
}
(void) printf("\t\t%s %d\n",
getTextString(TEXT_LB_OP_PATH_COUNT), numOperationalPaths);
return (mpstatus);
}
/*
* ****************************************************************************
*
* showLogicalUnit -
* mpathadm show {logical-unit | LU} <logical-unit name>, ...
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
showLogicalUnit(int operandLen, char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
MP_PLUGIN_PROPERTIES pluginProps;
MP_OID luOid,
pluginOid;
int op;
for (op = 0; op < operandLen; op++) {
if (op > 0) {
(void) printf("\n");
}
if (B_TRUE == getLogicalUnitOid(operand[op], &luOid)) {
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(
luOid, &luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
mpstatus =
MP_GetAssociatedPluginOid(luOid, &pluginOid);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
mpstatus =
MP_GetPluginProperties(pluginOid, &pluginProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
if (showIndividualLogicalUnit(luOid, luProps,
pluginProps) != 0) {
return (ERROR_CLI_FAILED);
}
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
operand[op]);
(void) printf("\n");
}
} /* for each operand */
return (mpstatus);
}
/*
* ****************************************************************************
*
* showIndivudualLogicalUnit -
* Used by show logical unit cli.
* Displays info about an LU
*
* luOid - LU to show
* luProps - properties of he LU to show
* pluginProps - propertis of the plugin this LU belongs to
*
* ****************************************************************************
*/
int
showIndividualLogicalUnit(MP_OID luOid,
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps,
MP_PLUGIN_PROPERTIES pluginProps)
{
MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
MP_TARGET_PORT_GROUP_PROPERTIES tpgProps;
MP_TARGET_PORT_PROPERTIES tportProps;
MP_INITIATOR_PORT_PROPERTIES initProps;
MP_OID_LIST *pPathOidListArray,
*pTPGOidListArray,
*pTportOidListArray;
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
boolean_t showTportLabel = B_TRUE;
int pa,
tpg,
tport;
(void) printf("%s ", getTextString(TEXT_LB_LOGICAL_UNIT));
displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName));
(void) printf("\n");
(void) printf("\t%s %s\n", getTextString(TEXT_LB_MPATH_SUPPORT),
pluginProps.fileName);
(void) printf("\t%s ", getTextString(TEXT_LB_VENDOR));
displayArray(luProps.vendor,
sizeof (luProps.vendor));
(void) printf("\n\t%s ", getTextString(TEXT_LB_PRODUCT));
displayArray(luProps.product,
sizeof (luProps.product));
(void) printf("\n\t%s ", getTextString(TEXT_LB_REVISION));
displayArray(luProps.revision,
sizeof (luProps.revision));
(void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME_TYPE));
displayLogicalUnitNameTypeString(luProps.nameType);
(void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME));
displayArray(luProps.name, sizeof (luProps.name));
(void) printf("\n\t%s %s\n", getTextString(TEXT_LB_ASYMMETRIC),
(MP_TRUE == luProps.asymmetric)?
getTextString(TEXT_YES):getTextString(TEXT_NO));
(void) printf("\t%s ", getTextString(TEXT_LB_CURR_LOAD_BALANCE));
/* don't ignore load balance type none. */
if (luProps.currentLoadBalanceType == 0) {
(void) printf("%s", getTextString(TEXT_LBTYPE_NONE));
} else {
displayLoadBalanceString(luProps.currentLoadBalanceType);
}
(void) printf("\n");
(void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID));
if (0xffffffff == luProps.logicalUnitGroupID) {
(void) printf("%s\n", getTextString(TEXT_NA));
} else {
(void) printf("0x%x\n", luProps.logicalUnitGroupID);
}
(void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB));
if (MP_FALSE == pluginProps.autoFailbackSupport) {
(void) printf("%s\n", getTextString(TEXT_NA));
} else {
(void) printf("%s\n", (MP_TRUE == luProps.autoFailbackEnabled)?
getTextString(TEXT_ON):getTextString(TEXT_OFF));
}
(void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB));
if (MP_FALSE == pluginProps.autoProbingSupport) {
(void) printf("%s\n", getTextString(TEXT_NA));
} else {
(void) printf("%s\n", (MP_TRUE == luProps.autoProbingEnabled)?
getTextString(TEXT_ON):getTextString(TEXT_OFF));
}
/* get path info */
mpstatus = MP_GetAssociatedPathOidList(luOid, &pPathOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s", cmdName,
getTextString(ERR_NO_LU_PATH_INFO));
displayArray(luProps.deviceFileName,
sizeof (luProps.deviceFileName));
(void) fprintf(stderr, "\n");
return (mpstatus);
}
(void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO));
for (pa = 0; pa < pPathOidListArray->oidCount; pa++) {
(void) memset(&pathProps, 0,
sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
mpstatus = MP_GetPathLogicalUnitProperties(
pPathOidListArray->oids[pa], &pathProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
(void) printf("\t\t%s ",
getTextString(TEXT_LB_INIT_PORT_NAME));
if ((mpstatus =
MP_GetInitiatorPortProperties(pathProps.initiatorPortOid,
&initProps)) != MP_STATUS_SUCCESS) {
(void) printf("%s\n", getTextString(TEXT_UNKNOWN));
} else {
displayArray(initProps.portID,
sizeof (initProps.portID));
(void) printf("\n");
}
(void) printf("\t\t%s ",
getTextString(TEXT_LB_TARGET_PORT_NAME));
if ((mpstatus =
MP_GetTargetPortProperties(pathProps.targetPortOid,
&tportProps)) != MP_STATUS_SUCCESS) {
(void) printf("%s\n", getTextString(TEXT_UNKNOWN));
} else {
displayArray(tportProps.portID,
sizeof (tportProps.portID));
(void) printf("\n");
}
(void) printf("\t\t%s ", getTextString(TEXT_LB_OVERRIDE_PATH));
if (MP_FALSE == pluginProps.canOverridePaths) {
(void) printf("%s\n", getTextString(TEXT_NA));
} else if (luProps.overridePath.objectSequenceNumber ==
pPathOidListArray->oids[pa].objectSequenceNumber) {
(void) printf("%s\n", getTextString(TEXT_YES));
} else {
(void) printf("%s\n", getTextString(TEXT_NO));
}
(void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE),
getPathStateStr(pathProps.pathState));
(void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED),
pathProps.disabled?getTextString(TEXT_YES):
getTextString(TEXT_NO));
}
/* get tpg info */
mpstatus = MP_GetAssociatedTPGOidList(luOid, &pTPGOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s", cmdName,
getTextString(ERR_NO_ASSOC_TPGS));
} else {
/* display tpg info only if is assymetric */
if (MP_TRUE == luProps.asymmetric) {
(void) printf("\t%s \n", getTextString(TEXT_LB_TPG_INFO));
}
for (tpg = 0; tpg < pTPGOidListArray->oidCount; tpg++) {
(void) memset(&tpgProps, 0,
sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
mpstatus = MP_GetTargetPortGroupProperties(
pTPGOidListArray->oids[tpg], &tpgProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s",
cmdName, getTextString(ERR_NO_PROPERTIES));
} else {
/* display tpg info only if is assymetric */
if (tpg > 0) {
(void) printf("\n");
}
if (MP_TRUE == luProps.asymmetric) {
(void) printf("\t\t%s %d\n",
getTextString(TEXT_LB_ID),
tpgProps.tpgID);
(void) printf("\t\t%s %s\n",
getTextString(
TEXT_LB_EXPLICIT_FAILOVER),
(MP_TRUE ==
tpgProps.explicitFailover)?
getTextString(TEXT_YES):
getTextString(TEXT_NO));
(void) printf("\t\t%s %s\n",
getTextString(
TEXT_LB_ACCESS_STATE),
getAccessStateStr(
tpgProps.accessState));
/* display label for each tpg. */
(void) printf("\t\t%s\n",
getTextString(TEXT_TPORT_LIST));
} else {
/* display label once for symmetric. */
if (B_TRUE == showTportLabel) {
(void) printf("\t%s\n",
getTextString(TEXT_TPORT_LIST));
showTportLabel = B_FALSE;
}
}
/* get target port info */
mpstatus = MP_GetTargetPortOidList(
pTPGOidListArray->oids[tpg],
&pTportOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s",
cmdName,
getTextString(ERR_NO_ASSOC_TPORTS));
} else {
/* begin back-up indentation */
for (tport = 0; tport < pTportOidListArray->oidCount; tport++) {
(void) memset(&tportProps, 0,
sizeof (MP_TARGET_PORT_PROPERTIES));
if ((mpstatus =
MP_GetTargetPortProperties(pTportOidListArray->oids[tport],
&tportProps)) != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s",
cmdName, getTextString(ERR_NO_PROPERTIES));
} else {
if (MP_TRUE == luProps.asymmetric) {
(void) printf("\t\t\t%s ",
getTextString(TEXT_LB_NAME));
displayArray(tportProps.portID,
sizeof (tportProps.portID));
(void) printf("\n\t\t\t%s %d\n",
getTextString(TEXT_LB_RELATIVE_ID),
tportProps.relativePortID);
} else {
(void) printf("\t\t%s ",
getTextString(TEXT_LB_NAME));
displayArray(tportProps.portID,
sizeof (tportProps.portID));
(void) printf("\n\t\t%s %d\n",
getTextString(TEXT_LB_RELATIVE_ID),
tportProps.relativePortID);
}
/* insert blank line if not the last target port. */
if (!(tport == (pTportOidListArray->oidCount - 1))) {
(void) printf("\n");
}
}
} /* for each target port */
/* end back-up indentation */
} /* else got target port props */
} /* else got TPG props */
} /* for each TPG */
} /* else got tpg list */
return (mpstatus);
}
/*
* ****************************************************************************
*
* modifyLogicalUnit -
* mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ...
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
modifyLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_OID luOid;
cmdOptions_t *optionList = options;
char *cmdStr =
getTextString(
TEXT_UNKNOWN);
int op;
for (op = 0; op < operandLen; op++) {
if (B_TRUE != getLogicalUnitOid(operand[op], &luOid)) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
operand[op]);
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* we found the lu oid, now change the options requested */
switch (optionList->optval) {
case 'a':
/* modify autofailback */
cmdStr = getTextString(TEXT_AUTO_FAILBACK);
if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_ON))) {
mpstatus =
MP_EnableAutoFailback(luOid);
} else if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_OFF))) {
mpstatus =
MP_DisableAutoFailback(luOid);
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr,
getTextString(
TEXT_ILLEGAL_ARGUMENT));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'p':
/* modify autoprobing */
cmdStr = getTextString(TEXT_AUTO_PROBING);
if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_ON))) {
mpstatus =
MP_EnableAutoProbing(luOid);
} else if (0 == strcasecmp(optionList->optarg,
getTextString(TEXT_OFF))) {
mpstatus =
MP_DisableAutoProbing(luOid);
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr,
getTextString(
TEXT_ILLEGAL_ARGUMENT));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'b':
/* modify loadbalance type */
cmdStr = getTextString(TEXT_LOAD_BALANCE);
mpstatus =
MP_SetLogicalUnitLoadBalanceType(luOid,
getLbValueFromString(optionList->optarg));
break;
} /* switch */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
cmdStr, getMpStatusStr(mpstatus));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
} /* for each operand */
return (mpstatus);
}
/*
* ****************************************************************************
*
* failoverLogicalUnit -
* mpathadm failover {logical-unit | LU} <logical-unit name>, ...
*
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
failoverLogicalUnit(char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_OID luOid;
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
MP_TARGET_PORT_GROUP_PROPERTIES tpgProps;
MP_OID_LIST *pTpgOidListArray;
boolean_t bFoundIt = B_FALSE;
MP_TPG_STATE_PAIR tpgStatePair;
int tpg;
if (B_TRUE != getLogicalUnitOid(operand[0], &luOid)) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
operand[0]);
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* get LUN properties and check to be sure it's asymmetric */
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(luOid, &luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (mpstatus);
}
if (MP_TRUE != luProps.asymmetric) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_LU_NOT_ASYMMETRIC));
return (ERROR_CLI_FAILED);
}
/* get TPGs for this LUN */
mpstatus =
MP_GetAssociatedTPGOidList(luOid, &pTpgOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_ASSOC_TPGS));
return (mpstatus);
}
/* pick a TPG whose state is active or standby, and change it */
/* to opposite via MP_SetTPGAccessState */
bFoundIt = B_FALSE;
for (tpg = 0; tpg < pTpgOidListArray->oidCount; tpg++) {
(void) memset(&tpgProps, 0,
sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
mpstatus =
MP_GetTargetPortGroupProperties(
pTpgOidListArray->oids[tpg], &tpgProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (ERROR_CLI_FAILED);
}
if (MP_FALSE == tpgProps.explicitFailover) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_FAILOVER_ALLOWED));
return (ERROR_CLI_FAILED);
}
/* find one that is standby */
if ((MP_ACCESS_STATE_STANDBY ==
tpgProps.accessState) && (B_FALSE == bFoundIt)) {
bFoundIt = B_TRUE;
tpgStatePair.tpgOid =
pTpgOidListArray->oids[tpg];
tpgStatePair.desiredState =
MP_ACCESS_STATE_ACTIVE;
mpstatus =
MP_SetTPGAccess(luOid, 1, &tpgStatePair);
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_FAILOVER_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
}
} /* for each tpg */
if (B_FALSE == bFoundIt) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_LU_ACCESS_STATE_UNCHANGED));
return (ERROR_CLI_FAILED);
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* getLogicalUnitOid -
* Search through all plugins and get the OID for specified logical unit
*
* luFileName - file name of LU (specified by the user) to find
* pLuOid - OID to return
*
* ****************************************************************************
*/
boolean_t
getLogicalUnitOid(MP_CHAR *luFileName, MP_OID *pluOid)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
MP_PLUGIN_PROPERTIES pluginProps;
MP_OID_LIST *pPluginOidList,
*pLogicalUnitOidList;
boolean_t foundIt = B_FALSE;
int i,
lu;
int fd1, fd2;
ddi_devid_t devid1 = NULL, devid2 = NULL;
if (NULL == pluOid) {
/* print some kind of error msg here - should never happen */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(ERR_MEMORY_ALLOCATION));
(void) printf("\n");
return (B_FALSE);
}
pluOid->objectSequenceNumber = 0;
pluOid->objectType = 0;
pluOid->ownerId = 0;
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (B_FALSE);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
/* get properties so we can list the name */
(void) memset(&pluginProps, 0, sizeof (MP_PLUGIN_PROPERTIES));
if ((mpstatus =
MP_GetPluginProperties(pPluginOidList->oids[i],
&pluginProps)) != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (B_FALSE);
}
/* attempt to find this logical unit */
mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
&pLogicalUnitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_LU_LIST));
return (B_FALSE);
}
for (lu = 0; (lu < pLogicalUnitOidList->oidCount) &&
(B_FALSE == foundIt); lu++) {
/* get lu properties so we can check the name */
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(
pLogicalUnitOidList->oids[lu], &luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (B_FALSE);
}
if (0 == strcmp(luFileName, luProps.deviceFileName)) {
foundIt = B_TRUE;
} else {
/* user input didn't match, try via devid */
/*
* I don't see a reason to print the error for
* any of these since they'll get the error at
* the end anyway
*/
if (((fd1 = open(luFileName,
O_RDONLY|O_NDELAY)) >= 0) &&
((fd2 = open(luProps.deviceFileName,
O_RDONLY|O_NDELAY)) >= 0) &&
(devid_get(fd1, &devid1) == 0) &&
(devid_get(fd2, &devid2) == 0) &&
((NULL != devid1) && (NULL != devid2))) {
if (0 ==
(devid_compare(devid1, devid2))) {
foundIt = B_TRUE;
}
}
if (NULL != devid1) {
devid_free(devid1);
}
if (NULL != devid2) {
devid_free(devid2);
}
}
if (B_TRUE == foundIt) {
pluOid->objectSequenceNumber =
pLogicalUnitOidList->
oids[lu].objectSequenceNumber;
pluOid->objectType =
pLogicalUnitOidList->
oids[lu].objectType;
pluOid->ownerId =
pLogicalUnitOidList->oids[lu].ownerId;
}
}
}
return (foundIt);
}
/*
* ****************************************************************************
*
* listInitiatorPort -
* mpathadm list initiator-port [<initiator-port name>, ...]
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
listInitiatorPort(int operandLen, char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_INITIATOR_PORT_PROPERTIES initProps;
MP_OID_LIST *pPluginOidList,
*pInitOidList;
boolean_t bListIt = B_FALSE;
boolean_t *foundOp;
int ol,
i,
iport;
foundOp = malloc((sizeof (boolean_t)) * operandLen);
if (NULL == foundOp) {
(void) fprintf(stdout, "%s\n",
getTextString(ERR_MEMORY_ALLOCATION));
return (ERROR_CLI_FAILED);
}
for (ol = 0; ol < operandLen; ol++) {
foundOp[ol] = B_FALSE;
}
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
mpstatus =
MP_GetInitiatorPortOidList(pPluginOidList->oids[i],
&pInitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_NO_INIT_PORT_LIST_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
} else if ((NULL == pInitOidList) ||
(pInitOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_INIT_PORTS));
} else {
for (iport = 0;
iport < pInitOidList->oidCount; iport ++) {
bListIt = B_FALSE;
if ((mpstatus =
MP_GetInitiatorPortProperties(
pInitOidList->oids[iport],
&initProps)) != MP_STATUS_SUCCESS) {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(ERR_NO_PROPERTIES));
} else {
/* if no operands listed, */
/* list all we find */
if (0 == operandLen) {
bListIt = B_TRUE;
} else {
/* check each operand */
/* Is it */
/* the one we want to list? */
for (ol = 0;
ol < operandLen; ol++) {
if (0 ==
strcmp(operand[ol],
initProps.
portID)) {
bListIt =
B_TRUE;
foundOp[ol] =
B_TRUE;
}
}
}
}
if (B_TRUE == bListIt) {
if (listIndividualInitiatorPort(
initProps) != 0) {
return (ERROR_CLI_FAILED);
}
} /* list It */
} /* for each initiator port */
} /* else found an init port */
} /* for each plugin */
for (ol = 0; ol < operandLen; ol++) {
if (B_FALSE == foundOp[ol]) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR),
operand[ol]);
(void) printf("\n");
}
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* listIndividualInitiatorPort -
* used by listInitiatorPort to list info for one init port
*
* initProps - properties of initiator port to list
*
* ****************************************************************************
*/
int
listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
(void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT));
displayArray(initProps.portID,
sizeof (initProps.portID));
(void) printf("\n");
return (mpstatus);
}
/*
* ****************************************************************************
*
* showInitiatorPort -
* mpathadm show initiator-port <initiator-port name>, ...
*
* operandLen - number of operands user passed into the cli
* operand - pointer to operand list from user
*
* ****************************************************************************
*/
int
showInitiatorPort(int operandLen, char *operand[])
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_INITIATOR_PORT_PROPERTIES initProps;
MP_OID_LIST *pPluginOidList,
*pInitOidList;
boolean_t bListIt = B_FALSE,
bFoundIt = B_FALSE;
int op,
i,
iport;
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (mpstatus);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (ERROR_CLI_FAILED);
}
for (op = 0; op < operandLen; op++) {
bFoundIt = B_FALSE;
for (i = 0; i < pPluginOidList->oidCount; i++) {
mpstatus =
MP_GetInitiatorPortOidList(pPluginOidList->oids[i],
&pInitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_NO_INIT_PORT_LIST_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
} else if ((NULL == pInitOidList) ||
(pInitOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_INIT_PORTS));
} else {
for (iport = 0;
iport < pInitOidList->oidCount;
iport ++) {
bListIt = B_FALSE;
if ((mpstatus =
MP_GetInitiatorPortProperties(
pInitOidList->oids[iport],
&initProps))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(ERR_NO_PROPERTIES));
} else {
if (0 == strcmp(operand[op],
initProps.portID)) {
bListIt = B_TRUE;
bFoundIt = B_TRUE;
}
}
if (B_TRUE == bListIt) {
mpstatus =
showIndividualInitiatorPort(
initProps);
if (0 != mpstatus) {
return (mpstatus);
}
} /* list It */
} /* for each initiator port */
} /* else found an init port */
} /* for each plugin */
if (B_FALSE == bFoundIt) {
/* need temp string here since we need to fill in a */
/* name in the error string */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR),
operand[op]);
(void) printf("\n");
}
} /* for each operand */
return (mpstatus);
}
/*
* ****************************************************************************
*
* showIndividualInitiatorPort -
* used by showInitiatorPort to show info for one init port
*
* initProps - properties of initiator port to show
*
* ****************************************************************************
*/
int
showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
(void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT));
displayArray(initProps.portID,
sizeof (initProps.portID));
(void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE));
displayTransportTypeString(initProps.portType);
(void) printf("\n");
(void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE));
displayArray(initProps.osDeviceFile,
sizeof (initProps.osDeviceFile));
(void) printf("\n");
return (mpstatus);
}
/*
* ****************************************************************************
*
* enablePath -
* mpathadm enable path -i <initiator-port>
* -t <target-port name> -l <logical-unit name>
*
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
enablePath(cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_OID pathOid;
cmdOptions_t *optionList = options;
boolean_t bHaveInit = B_FALSE,
bHaveTarg = B_FALSE,
bHaveLu = B_FALSE;
for (; optionList->optval; optionList++) {
switch (optionList->optval) {
case 'i':
/* have init port name */
bHaveInit = B_TRUE;
break;
case 't':
/* have target port id */
bHaveTarg = B_TRUE;
break;
case 'l':
/* have LU name */
bHaveLu = B_TRUE;
break;
}
}
if (B_FALSE == bHaveInit) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
getTextString(MISSING_INIT_PORT_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
} else if (B_FALSE == bHaveTarg) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
getTextString(MISSING_TARGET_PORT_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
} else if (B_FALSE == bHaveLu) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
getTextString(MISSING_LU_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
if (B_FALSE == getPathOid(options, &pathOid)) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
getTextString(FAILED_TO_FIND_PATH));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* found the path, attempt to enable it */
mpstatus = MP_EnablePath(pathOid);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* disablePath -
* mpathadm disable path -i <initiator-port>
* -t <target-port name> -l <logical-unit name>
*
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
disablePath(cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_OID pathOid;
cmdOptions_t *optionList = options;
boolean_t bHaveInit = B_FALSE,
bHaveTarg = B_FALSE,
bHaveLu = B_FALSE;
for (; optionList->optval; optionList++) {
switch (optionList->optval) {
case 'i':
/* have init port name */
bHaveInit = B_TRUE;
break;
case 't':
/* have target port id */
bHaveTarg = B_TRUE;
break;
case 'l':
/* have LU name */
bHaveLu = B_TRUE;
break;
}
}
if (B_FALSE == bHaveInit) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
getTextString(MISSING_INIT_PORT_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
} else if (B_FALSE == bHaveTarg) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
getTextString(MISSING_TARGET_PORT_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
} else if (B_FALSE == bHaveLu) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
getTextString(MISSING_LU_NAME));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
if (B_FALSE == getPathOid(options, &pathOid)) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
getTextString(FAILED_TO_FIND_PATH));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* found the path, attempt to enable it */
mpstatus = MP_DisablePath(pathOid);
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr, getTextString(
ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* overridePath -
* mpathadm override path {-i <initiator-port>
* -t <target-port name> | -c} <logical-unit name>
*
* options - pointer to option list from user
*
* ****************************************************************************
*/
int
overridePath(cmdOptions_t *options)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_OID pathOid, luOid;
boolean_t bCancelOverride = B_FALSE;
MP_CHAR pLuDeviceFileName[256];
cmdOptions_t *optionList = options;
/* First check to see if we have the cancel option, */
/* May as well save off the lun while we're at it */
for (; optionList->optval; optionList++) {
switch (optionList->optval) {
case 'c':
/* we have a cancel */
bCancelOverride = B_TRUE;
break;
case 'l':
/* we have a lun- save it while we're here */
(void) memcpy(pLuDeviceFileName,
optionList->optarg, 256);
break;
}
}
if (B_TRUE == bCancelOverride) {
/* if we have the cancel option, */
if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON),
getTextString(LU_NOT_FOUND));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* cancel the override path for the specified LU */
mpstatus = MP_CancelOverridePath(luOid);
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
} else {
/* must be wanting to override the path */
if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
getTextString(LU_NOT_FOUND));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
if (B_FALSE == getPathOid(options, &pathOid)) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
getTextString(FAILED_TO_FIND_PATH));
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* attempt to set the override path */
mpstatus = MP_SetOverridePath(luOid, pathOid);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
getMpStatusStr(mpstatus));
(void) printf("\n");
return (mpstatus);
}
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* getPathOid -
* Search through all plugins and get the OID for specified path
*
* operand - pointer to operand list from user
* options - pointer to option list from user
*
* ****************************************************************************
*/
boolean_t
getPathOid(cmdOptions_t *options, MP_OID *pPathOid)
{
MP_STATUS mpstatus = MP_STATUS_SUCCESS;
MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
MP_INITIATOR_PORT_PROPERTIES initProps;
MP_TARGET_PORT_PROPERTIES targProps;
MP_OID_LIST *pPluginOidList,
*pLogicalUnitOidList,
*pathOidListArray;
boolean_t bFoundIt = B_FALSE;
MP_CHAR initPortID[256];
MP_CHAR targetPortID[256];
MP_CHAR luDeviceFileName[256];
boolean_t bHaveTarg = B_FALSE,
bHaveLu = B_FALSE,
bHaveInit = B_FALSE;
cmdOptions_t *optionList = options;
int i,
lu,
pa;
if (NULL == pPathOid) {
return (B_FALSE);
}
for (; optionList->optval; optionList++) {
switch (optionList->optval) {
case 'i':
/* save init port name */
(void) memcpy(initPortID,
optionList->optarg, 256);
bHaveInit = B_TRUE;
break;
case 't':
/* save target port id */
(void) memcpy(targetPortID,
optionList->optarg, 256);
bHaveTarg = B_TRUE;
break;
case 'l':
/* save LU name */
(void) memcpy(luDeviceFileName,
optionList->optarg, 256);
bHaveLu = B_TRUE;
break;
}
}
if ((B_FALSE == bHaveInit) ||
(B_FALSE == bHaveTarg) ||
(B_FALSE == bHaveLu)) {
/* if we don't have all three pieces, we can't find the path */
return (B_FALSE);
}
/* get the plugin ist */
if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
!= MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (B_FALSE);
}
if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_MPATH_SUPPORT_LIST));
return (B_FALSE);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
/* get Logical Unit list */
mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
&pLogicalUnitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_LU_LIST));
return (B_FALSE);
}
for (lu = 0; (lu < pLogicalUnitOidList->oidCount) &&
(B_FALSE == bFoundIt); lu++) {
/* get lu properties so we can check the name */
(void) memset(&luProps, 0,
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
MP_GetMPLogicalUnitProperties(
pLogicalUnitOidList->oids[lu], &luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(ERR_NO_PROPERTIES));
return (B_FALSE);
}
if (0 == strcmp(luDeviceFileName,
luProps.deviceFileName)) {
/* get paths for this LU and search from here */
mpstatus =
MP_GetAssociatedPathOidList(
pLogicalUnitOidList->oids[lu],
&pathOidListArray);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) fprintf(stderr,
getTextString(
ERR_FAILED_TO_FIND_PATH));
(void) printf("\n");
return (B_FALSE);
}
for (pa = 0;
(pa < pathOidListArray->oidCount) &&
(B_FALSE == bFoundIt); pa++) {
mpstatus =
MP_GetPathLogicalUnitProperties
(pathOidListArray->oids[pa],
&pathProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(
ERR_NO_PROPERTIES));
return (B_FALSE);
}
/*
* get properties of iniator port and
* target port to see if we have the
* right path
*/
mpstatus =
MP_GetInitiatorPortProperties(
pathProps.initiatorPortOid,
&initProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr,
"%s: %s\n", cmdName,
getTextString(
ERR_NO_PROPERTIES));
return (B_FALSE);
}
if (0 == strcmp(initPortID, initProps.portID)) {
/* lu and init port matches, check target port */
mpstatus = MP_GetTargetPortProperties(pathProps.targetPortOid,
&targProps);
if (mpstatus != MP_STATUS_SUCCESS) {
(void) fprintf(stderr, "%s: %s\n", cmdName,
getTextString(ERR_NO_PROPERTIES));
return (B_FALSE);
}
if (0 == strcmp(targetPortID, targProps.portID)) {
/* we found our path */
pPathOid->objectSequenceNumber =
pathOidListArray->oids[pa].objectSequenceNumber;
pPathOid->objectType =
pathOidListArray->oids[pa].objectType;
pPathOid->ownerId = pathOidListArray->oids[pa].ownerId;
bFoundIt = B_TRUE;
}
} /* init port matched */
} /* for each path associated with this lu */
} /* lu matched */
} /* for each lu */
} /* for each plugin */
return (bFoundIt);
}
/*
* ****************************************************************************
*
* getLbValueFromString
* Gets the MP_LOAD_BALANCE_TYPE specified load balance type string
*
* lbStr - load balance string defined in the .h file
* This is what users will be required to feed into the
* modify lu command.
*
* ****************************************************************************
*/
MP_LOAD_BALANCE_TYPE
getLbValueFromString(char *lbStr)
{
MP_LOAD_BALANCE_TYPE lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN;
if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_ROUNDROBIN))) {
lbVal = MP_LOAD_BALANCE_TYPE_ROUNDROBIN;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTBLOCKS))) {
lbVal = MP_LOAD_BALANCE_TYPE_LEASTBLOCKS;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTIO))) {
lbVal = MP_LOAD_BALANCE_TYPE_LEASTIO;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_DEVICEPROD))) {
lbVal = MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LBAREGION))) {
lbVal = MP_LOAD_BALANCE_TYPE_LBA_REGION;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_FAILOVER_ONLY))) {
lbVal = MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_UNKNOWN))) {
lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN;
} else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_NONE))) {
lbVal = 0;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY1))) {
lbVal = ((MP_UINT32)0x00000001)<<16;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY2))) {
lbVal = ((MP_UINT32)0x00000001)<<17;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY3))) {
lbVal = ((MP_UINT32)0x00000001)<<18;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY4))) {
lbVal = ((MP_UINT32)0x00000001)<<19;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY5))) {
lbVal = ((MP_UINT32)0x00000001)<<20;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY6))) {
lbVal = ((MP_UINT32)0x00000001)<<21;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY7))) {
lbVal = ((MP_UINT32)0x00000001)<<22;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY8))) {
lbVal = ((MP_UINT32)0x00000001)<<23;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY9))) {
lbVal = ((MP_UINT32)0x00000001)<<24;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY10))) {
lbVal = ((MP_UINT32)0x00000001)<<25;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY11))) {
lbVal = ((MP_UINT32)0x00000001)<<26;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY12))) {
lbVal = ((MP_UINT32)0x00000001)<<27;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY13))) {
lbVal = ((MP_UINT32)0x00000001)<<28;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY14))) {
lbVal = ((MP_UINT32)0x00000001)<<29;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY15))) {
lbVal = ((MP_UINT32)0x00000001)<<30;
} else if (0 == strcmp(lbStr,
getTextString(TEXT_LBTYPE_PROPRIETARY16))) {
lbVal = ((MP_UINT32)0x00000001)<<31;
}
return (lbVal);
} /* end getLbValueFromString */
/*
* ****************************************************************************
*
* displayLogicalUnitNameTypeString
* Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE
* specified load balance type
*
* typeVal - load balance type defined in the MPAPI spec
*
* ****************************************************************************
*/
void
displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal)
{
char *typeString;
switch (typeVal) {
case MP_LU_NAME_TYPE_UNKNOWN:
typeString = getTextString(TEXT_NAME_TYPE_UNKNOWN);
break;
case MP_LU_NAME_TYPE_VPD83_TYPE1:
typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE1);
break;
case MP_LU_NAME_TYPE_VPD83_TYPE2:
typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE2);
break;
case MP_LU_NAME_TYPE_VPD83_TYPE3:
typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE3);
break;
case MP_LU_NAME_TYPE_DEVICE_SPECIFIC:
typeString =
getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC);
break;
default:
typeString = getTextString(TEXT_UNKNOWN);
break;
}
(void) printf("%s", typeString);
} /* end displayLogicalUnitNameTypeString */
/*
* ****************************************************************************
*
* displayLoadBalanceString
* Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE
* specified load balance type
*
* lbVal - load balance type defined in the MPAPI spec
*
* ****************************************************************************
*/
void
displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal)
{
char *lbString;
switch (lbVal) {
case MP_LOAD_BALANCE_TYPE_UNKNOWN:
lbString = getTextString(TEXT_LBTYPE_UNKNOWN);
break;
case MP_LOAD_BALANCE_TYPE_ROUNDROBIN:
lbString = getTextString(TEXT_LBTYPE_ROUNDROBIN);
break;
case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS:
lbString = getTextString(TEXT_LBTYPE_LEASTBLOCKS);
break;
case MP_LOAD_BALANCE_TYPE_LEASTIO:
lbString = getTextString(TEXT_LBTYPE_LEASTIO);
break;
case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT:
lbString = getTextString(TEXT_LBTYPE_DEVICEPROD);
break;
case MP_LOAD_BALANCE_TYPE_LBA_REGION:
lbString = getTextString(TEXT_LBTYPE_LBAREGION);
break;
case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY:
lbString = getTextString(TEXT_LBTYPE_FAILOVER_ONLY);
break;
case (((MP_UINT32)0x00000001)<<16):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY1);
break;
case (((MP_UINT32)0x00000001)<<17):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY2);
break;
case (((MP_UINT32)0x00000001)<<18):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY3);
break;
case (((MP_UINT32)0x00000001)<<19):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY4);
break;
case (((MP_UINT32)0x00000001)<<20):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY5);
break;
case (((MP_UINT32)0x00000001)<<21):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY6);
break;
case (((MP_UINT32)0x00000001)<<22):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY7);
break;
case (((MP_UINT32)0x00000001)<<23):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY8);
break;
case (((MP_UINT32)0x00000001)<<24):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY9);
break;
case (((MP_UINT32)0x00000001)<<25):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY10);
break;
case (((MP_UINT32)0x00000001)<<26):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY11);
break;
case (((MP_UINT32)0x00000001)<<27):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY12);
break;
case (((MP_UINT32)0x00000001)<<28):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY13);
break;
case (((MP_UINT32)0x00000001)<<29):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY14);
break;
case (((MP_UINT32)0x00000001)<<30):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY15);
break;
case (((MP_UINT32)0x00000001)<<31):
lbString = getTextString(TEXT_LBTYPE_PROPRIETARY16);
break;
default:
lbString = getTextString(TEXT_UNKNOWN);
break;
}
(void) printf("%s", lbString);
} /* end displayLoadBalanceString */
/*
* ****************************************************************************
*
* displayTransportTypeString
* Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE
* specified load balance type
*
* transportTypeVal - transport type defined in the MPAPI spec
*
* ****************************************************************************
*/
void
displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal)
{
char *ttypeString;
switch (transportTypeVal) {
case MP_PORT_TRANSPORT_TYPE_MPNODE:
ttypeString =
getTextString(TEXT_TRANS_PORT_TYPE_MPNODE);
break;
case MP_PORT_TRANSPORT_TYPE_FC:
ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_FC);
break;
case MP_PORT_TRANSPORT_TYPE_SPI:
ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_SPI);
break;
case MP_PORT_TRANSPORT_TYPE_ISCSI:
ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_ISCSI);
break;
case MP_PORT_TRANSPORT_TYPE_IFB:
ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_IFB);
break;
default:
ttypeString = getTextString(TEXT_UNKNOWN);
break;
}
(void) printf("%s", ttypeString);
} /* end displayTransportTypeString */
/*
* ****************************************************************************
*
* getMpStatusStr
* Gets the string description for the specified load balance type value
*
* mpstatus - MP_STATUS value
*
* ****************************************************************************
*/
char *
getMpStatusStr(MP_STATUS mpstatus)
{
char *statString;
switch (mpstatus) {
case MP_STATUS_SUCCESS:
statString = getTextString(TEXT_MPSTATUS_SUCCESS);
break;
case MP_STATUS_INVALID_PARAMETER:
statString = getTextString(TEXT_MPSTATUS_INV_PARAMETER);
break;
case MP_STATUS_UNKNOWN_FN:
statString = getTextString(TEXT_MPSTATUS_UNKNOWN_FN);
break;
case MP_STATUS_FAILED:
statString = getTextString(TEXT_MPSTATUS_FAILED);
break;
case MP_STATUS_INSUFFICIENT_MEMORY:
statString = getTextString(TEXT_MPSTATUS_INSUFF_MEMORY);
break;
case MP_STATUS_INVALID_OBJECT_TYPE:
statString = getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE);
break;
case MP_STATUS_UNSUPPORTED:
statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED);
break;
case MP_STATUS_OBJECT_NOT_FOUND:
statString = getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND);
break;
case MP_STATUS_ACCESS_STATE_INVALID:
statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED);
break;
case MP_STATUS_FN_REPLACED:
statString = getTextString(TEXT_MPSTATUS_FN_REPLACED);
break;
case MP_STATUS_PATH_NONOPERATIONAL:
statString = getTextString(TEXT_MPSTATUS_PATH_NONOP);
break;
case MP_STATUS_TRY_AGAIN:
statString = getTextString(TEXT_MPSTATUS_TRY_AGAIN);
break;
case MP_STATUS_NOT_PERMITTED:
statString = getTextString(TEXT_MPSTATUS_NOT_PERMITTED);
break;
default:
statString = getTextString(TEXT_UNKNOWN);
break;
}
return (statString);
} /* end getMpStatusStr */
/*
* ****************************************************************************
*
* GetPathStateStr
* Gets the string description for the specified path state type value
*
* pathState - MP_PATH_STATE values
*
* ****************************************************************************
*/
char *
getPathStateStr(MP_PATH_STATE pathState)
{
char *pathString;
switch (pathState) {
case MP_PATH_STATE_OKAY:
pathString = getTextString(TEXT_PATH_STATE_OKAY);
break;
case MP_PATH_STATE_PATH_ERR:
pathString = getTextString(TEXT_PATH_STATE_PATH_ERR);
break;
case MP_PATH_STATE_LU_ERR:
pathString = getTextString(TEXT_PATH_STATE_LU_ERR);
break;
case MP_PATH_STATE_RESERVED:
pathString = getTextString(TEXT_PATH_STATE_RESERVED);
break;
case MP_PATH_STATE_REMOVED:
pathString = getTextString(TEXT_PATH_STATE_REMOVED);
break;
case MP_PATH_STATE_TRANSITIONING:
pathString =
getTextString(TEXT_PATH_STATE_TRANSITIONING);
break;
case MP_PATH_STATE_OPERATIONAL_CLOSED:
pathString =
getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED);
break;
case MP_PATH_STATE_INVALID_CLOSED:
pathString =
getTextString(TEXT_PATH_STATE_INVALID_CLOSED);
break;
case MP_PATH_STATE_OFFLINE_CLOSED:
pathString =
getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED);
break;
default:
pathString = getTextString(TEXT_UNKNOWN);
break;
}
return (pathString);
} /* end getPathStateStr */
/*
* ****************************************************************************
*
* getAccessStateStr
* Gets the string description for the specified access state type value
*
* accessState - MP_ACCESS_STATE_TYPE values
*
* ****************************************************************************
*/
char *
getAccessStateStr(MP_ACCESS_STATE_TYPE accessState)
{
char *accessString;
switch (accessState) {
case MP_ACCESS_STATE_ACTIVE_OPTIMIZED:
accessString =
getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED);
break;
case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED:
accessString =
getTextString(
TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED);
break;
case MP_ACCESS_STATE_STANDBY:
accessString =
getTextString(TEXT_ACCESS_STATE_STANDBY);
break;
case MP_ACCESS_STATE_UNAVAILABLE:
accessString =
getTextString(TEXT_ACCESS_STATE_UNAVAILABLE);
break;
case MP_ACCESS_STATE_TRANSITIONING:
accessString =
getTextString(TEXT_ACCESS_STATE_TRANSITIONING);
break;
case MP_ACCESS_STATE_ACTIVE:
accessString = getTextString(TEXT_ACCESS_STATE_ACTIVE);
break;
default:
accessString = getTextString(TEXT_UNKNOWN);
break;
}
return (accessString);
} /* end getAccessStateStr */
/*
* ****************************************************************************
*
* displayArray
* Print out the specified array.
*
* arrayToDisplay - array to display
* arraySize - size of array to display
*
* ****************************************************************************
*/
void
displayArray(MP_CHAR *arrayToDisplay, int arraySize)
{
int i;
for (i = 0; i < arraySize; i++) {
if ('\0' != arrayToDisplay[i]) {
(void) fprintf(stdout, "%c", arrayToDisplay[i]);
}
}
}
/*
* ****************************************************************************
*
* getStringArray
* Return a null terminated array for the specified array as a string,
* This is used for inputting into the %s in formatted strings.
*
* arrayToDisplay - array to display
* arraySize - size of array to display
*
* ****************************************************************************
*/
MP_CHAR *
getStringArray(MP_CHAR *arrayToDisplay, int arraySize)
{
MP_CHAR *newStr;
int i;
newStr = malloc(((sizeof (MP_CHAR)) * arraySize) + 1);
if (NULL == newStr) {
(void) fprintf(stdout, "%s\n",
getTextString(ERR_MEMORY_ALLOCATION));
} else {
for (i = 0; i < arraySize; i++) {
newStr[i] = arrayToDisplay[i];
}
newStr[arraySize] = '\0';
}
return (newStr);
}
/*
* ****************************************************************************
*
* displayWideArray
* Print out the specified wide character array as a string,
* adding the null termination
*
* arrayToDisplay - array to display
* arraySize - size of array to display
*
* ****************************************************************************
*/
void
displayWideArray(MP_WCHAR *arrayToDisplay, int arraySize)
{
int i;
int numChars = arraySize/4;
for (i = 0; i < numChars; i++) {
if (L'\0' != arrayToDisplay[i]) {
(void) fprintf(stdout, "%wc", arrayToDisplay[i]);
}
}
}
/*
* ****************************************************************************
*
* listfunc
* Used by cmdparse for list clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
ret = listMpathSupport(operandLen, operand);
break;
case LOGICAL_UNIT:
ret = listLogicalUnit(operandLen, operand, options);
break;
case INITIATOR_PORT:
ret = listInitiatorPort(operandLen, operand);
break;
default:
(void) fprintf(stderr, "%s: %s\n",
cmdName, getTextString(TEXT_UNKNOWN_OBJECT));
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* showFunc
* used bycmdparse for show clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
showFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
ret = showMpathSupport(operandLen, operand);
break;
case LOGICAL_UNIT:
ret = showLogicalUnit(operandLen, operand);
break;
case INITIATOR_PORT:
ret = showInitiatorPort(operandLen, operand);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* modifyFunc
* Used by cmdparse for midify clis
*
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
ret = modifyMpathSupport(operandLen, operand, options);
break;
case LOGICAL_UNIT:
ret = modifyLogicalUnit(operandLen, operand, options);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* enableFunc
* Used by cmdpars for enable clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
enableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
ret = enablePath(options);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* disableFunc
* Used by cmdpars for disable clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
disableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
ret = disablePath(options);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* failoverFunc
* Used by cmdpars for failover clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
failoverFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case LOGICAL_UNIT:
ret = failoverLogicalUnit(operand);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* overrideFunc
* Used by cmdpars for override clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
overrideFunc(int operandLen, char *operand[],
int object, cmdOptions_t *options,
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
ret = overridePath(options);
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* *************************************************************************
*
* main
*
* *************************************************************************
*/
int
main(int argc, char *argv[])
{
synTables_t synTables;
char versionString[VERSION_STRING_MAX_LEN];
int ret;
int funcRet;
void *subcommandArgs = NULL;
/* set global command name */
cmdName = getExecBasename(argv[0]);
(void) sprintf(versionString, "%2s.%2s",
VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
synTables.versionString = versionString;
synTables.longOptionTbl = &longOptions[0];
synTables.subcommandTbl = &subcommands[0];
synTables.objectTbl = &objects[0];
synTables.objectRulesTbl = &objectRules[0];
synTables.optionRulesTbl = &optionRules[0];
ret = cmdParse(argc, argv, /* SUB_COMMAND_ISSUED, */ synTables,
subcommandArgs, &funcRet);
if (ret == 1) {
(void) fprintf(stdout, "%s %s(1M)\n",
getTextString(TEXT_MORE_INFO), cmdName);
return (ERROR_CLI_FAILED);
} else if (ret == -1) {
perror(argv[0]);
return (1);
}
if (funcRet != 0) {
(void) fprintf(stderr, "%s: %s\n",
argv[0], getTextString(TEXT_UNABLE_TO_COMPLETE));
return (1);
}
return (0);
} /* end main */