mpathadm.c revision d3cfd299389905b5947a182ebffe96d3481b24e5
/*
* 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
* 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 <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 (;;) {
break;
} else {
if (*execBasename == '\0') {
*lastSlash = '\0';
continue;
}
break;
}
}
return (execBasename);
}
/*
* Add new options here
*/
/* tables set up based on cmdparse instructions */
optionTbl_t longOptions[] = {
{NULL, 0, 0, 0}
};
/*
* Add new subcommands here
*/
subcommand_t subcommands[] = {
};
/*
* Add objects here
*/
{"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 name"},
"initiator-port name"},
"logical-unit name"},
"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[] = {
{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
{
/* number of plugins listed */
int i,
op;
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
/* loop through operands first */
for (i = 0; i < pPluginOidList->oidCount; i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
mpstatus =
&pluginProps);
if (mpstatus != MP_STATUS_SUCCESS) {
} else {
if (0 == operandLen) {
/* if no operands, list them all */
(void) printf("%s %s\n",
} else {
/* if there is an operand... */
/* ... compare and display if match */
if (0 ==
pluginProps.fileName)) {
(void) printf("%s %s\n",
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
int op,
i,
j;
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
mpstatus =
&pluginProps);
if (MP_STATUS_SUCCESS != mpstatus) {
return (mpstatus);
}
if (0 == operandLen) {
/* if no operand, list it */
} else {
/* ... compare and display if match */
if (0 ==
pluginProps.fileName)) {
}
}
break;
}
(void) printf("%s %s\n",
/* display the info for this plugin */
sizeof (pluginProps.vendor));
(void) printf("\n\t%s ",
sizeof (pluginProps.driverName));
(void) printf("\n\t%s ",
/* don't ignore load balance type none. */
if (pluginProps.defaultloadBalanceType == 0) {
(void) printf("%s",
} else {
}
(void) printf("\n");
(void) printf("\t%s \n",
/* check each bit, display string if found set */
if (pluginProps.supportedLoadBalanceTypes == 0) {
(void) printf("\t\t%s\n",
} else {
lb = 1;
do {
if (0 != (lb &
(void) printf("\t\t");
(void) printf("\n");
}
} while (lb < 0x80000000);
}
(void) printf("\t%s %s\n",
(void) printf("\t%s %s\n",
(void) printf("\t%s %d\n",
if ((MP_AUTOFAILBACK_SUPPORT_PLUGIN ==
== pluginProps.autoFailbackSupport)) {
(void) printf("\t%s %s\n",
(void) printf("\t%s %d/%d\n",
} else {
(void) printf("\t%s %s\n",
(void) printf("\t%s %s/%s\n",
}
(void) printf("\t%s %d\n",
if ((MP_AUTOPROBING_SUPPORT_PLUGIN ==
(void) printf("\t%s %s\n",
(MP_TRUE ==
(void) printf("\t%s %d/%d\n",
} else {
(void) printf("\t%s %s\n",
(void) printf("\t%s %s/%s\n",
}
(void) printf("\t%s\n",
if (MP_TRUE !=
/* LINTED E_SEC_PRINTF_VAR_FMT */
} else {
/* if only supports specific products, */
/* get device product properties supported */
pPluginOidList->oids[i],
if (mpstatus != MP_STATUS_SUCCESS) {
/* can't get any more info, */
/* so we're done with this one */
break;
}
for (j = 0; j < deviceOidListArray->oidCount;
j++) {
sizeof (MP_DEVICE_PRODUCT_PROPERTIES));
if ((mpstatus =
deviceOidListArray->oids[j],
&devProps)) == MP_STATUS_SUCCESS) {
(void) printf("\t\t%s ",
(void) printf("\n\t\t%s ",
(void) printf("\n\t\t%s ",
(void) printf("\n\t\t%s\n",
if (devProps.supportedLoadBalanceTypes == 0) {
(void) printf("\t\t\t%s\n",
} else {
lb = 1;
do {
if (0 != (lb &
(void) printf("\t\t\t");
(void) printf("\n");
}
} while (lb < 0x80000000);
}
(void) printf("\n");
} else {
"%s: %s\n", cmdName,
}
} /* for j */
} /* if only supports specified devices */
} /* for each plugin */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
char *cmdStr =
int op,
i,
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
for (i = 0;
i++) {
(void) memset(&pluginProps, 0,
sizeof (MP_PLUGIN_PROPERTIES));
if ((mpstatus =
&pluginProps)) == MP_STATUS_SUCCESS) {
pluginProps.fileName)) {
}
} else {
}
break;
}
/* begin back-up indentation */
/* we found the plugin oid */
/* now change the options requested */
switch (optionList->optval) {
case 'a':
/* modify autofailback */
getTextString(TEXT_ON))) {
mpstatus =
} else if (0 ==
getTextString(TEXT_OFF))) {
mpstatus =
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'p':
/* modify autoprobing */
getTextString(TEXT_ON))) {
mpstatus =
} else if (0 ==
getTextString(TEXT_OFF))) {
mpstatus =
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'b':
/* modify loadbalance type */
/* user of the cli sends text string, we need the int */
/* value to pass to the mpapi */
mpstatus =
lbValue);
break;
} /* switch */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (mpstatus);
}
/* end back-up indentation */
} /* for each plugin */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
int opListCount = 0,
i = 0,
lu = 0,
tpg = 0,
opoffset = 0,
j = 0,
opStart = 0,
opEnd = 0,
/* count number of options */
opListCount++;
}
if (NULL == bFoundOption) {
return (ERROR_CLI_FAILED);
}
/* list to keep track of multiple options */
}
/* if no operands or options, list everything we find */
if ((0 == operandLen) && (0 == opListCount)) {
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
if ((NULL == pPluginOidList) ||
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 =
&pluginProps)) != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* attempt to find this logical unit */
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* get lu properties so we can check the name */
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
&luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
!= 0) {
return (ERROR_CLI_FAILED);
}
} /* for each LU */
} /* for each plugin */
/* check if we have operands */
if (0 == operandLen) {
/* no operands */
opStart = -1;
opEnd = 0;
} else {
/* operands */
opStart = 0;
opEnd = operandLen;
}
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
if ((NULL == pPluginOidList) ||
return (ERROR_CLI_FAILED);
}
/* loop through operands */
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_STATUS_SUCCESS) {
return (mpstatus);
}
/* attempt to find this logical unit */
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
for (lu = 0;
lu++) {
/* get lu props & check the name */
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
&luProps);
if (mpstatus != MP_STATUS_SUCCESS) {
"%s: %s\n", cmdName,
return (mpstatus);
}
/*
* compare operand - is it a match?
* If so, continue
*/
if (operandLen > 0) {
}
if (0 != opListCount) {
/* check options */
/* begin backup indentation */
switch (optionList->optval) {
case 'n':
if (B_TRUE ==
}
break;
case 't':
/* get TPG list */
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* get target ports */
for (tpg = 0;
(NULL != pTpgOidListArray) &&
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* get target port properties for the name */
for (j = 0; (NULL != pTportOidListArray) &&
(j < pTportOidListArray->oidCount) &&
(void) memset(&tportProps, 0,
sizeof (MP_TARGET_PORT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* check the name */
tportProps.portID)) {
}
} /* for each target port */
} /* for each tpg */
} /* end switch */
} /* loop through options */
/* end back-up indentation */
} else {
/*
* if no options,
* listit
*/
}
} /* end bContinue check */
if (bListIt) {
(void) printf("%s %s\n",
!= 0) {
return (ERROR_CLI_FAILED);
}
}
} /* end LU loop */
} /* end plugin loop */
if ((0 == opListCount) && (0 != operandLen)) {
if (B_FALSE == bFoundOperand) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
}
}
opIndex++) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
optionList->optarg);
}
}
} /* end loop through operands */
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
*
* ****************************************************************************
*/
{
} 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 (0 ==
}
}
}
}
if (fd1 >= 0) {
}
if (fd2 >= 0) {
}
} /* 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
{
int numOperationalPaths,
pa;
(void) printf("\t");
(void) printf("\n");
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
sizeof (luProps.deviceFileName)));
return (mpstatus);
}
(void) printf("\t\t%s %d\n",
numOperationalPaths = 0;
sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* cycle through and check status of each for */
/* operation path count */
}
}
(void) printf("\t\t%s %d\n",
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
{
int op;
if (op > 0) {
(void) printf("\n");
}
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
pluginProps) != 0) {
return (ERROR_CLI_FAILED);
}
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
int pa,
tpg,
(void) printf("\n");
/* don't ignore load balance type none. */
if (luProps.currentLoadBalanceType == 0) {
} else {
}
(void) printf("\n");
} else {
}
} else {
}
} else {
}
/* get path info */
if (mpstatus != MP_STATUS_SUCCESS) {
sizeof (luProps.deviceFileName));
return (mpstatus);
}
sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
(void) printf("\t\t%s ",
if ((mpstatus =
&initProps)) != MP_STATUS_SUCCESS) {
} else {
(void) printf("\n");
}
(void) printf("\t\t%s ",
if ((mpstatus =
&tportProps)) != MP_STATUS_SUCCESS) {
} else {
sizeof (tportProps.portID));
(void) printf("\n");
}
} else {
}
}
/* get tpg info */
if (mpstatus != MP_STATUS_SUCCESS) {
} else {
/* display tpg info only if is assymetric */
}
sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
if (mpstatus != MP_STATUS_SUCCESS) {
} else {
/* display tpg info only if is assymetric */
if (tpg > 0) {
(void) printf("\n");
}
(void) printf("\t\t%s %d\n",
(void) printf("\t\t%s %s\n",
(MP_TRUE ==
(void) printf("\t\t%s %s\n",
/* display label for each tpg. */
(void) printf("\t\t%s\n",
} else {
/* display label once for symmetric. */
if (B_TRUE == showTportLabel) {
(void) printf("\t%s\n",
}
}
/* get target port info */
if (mpstatus != MP_STATUS_SUCCESS) {
} else {
/* begin back-up indentation */
(void) memset(&tportProps, 0,
sizeof (MP_TARGET_PORT_PROPERTIES));
if ((mpstatus =
&tportProps)) != MP_STATUS_SUCCESS) {
} else {
(void) printf("\t\t\t%s ",
sizeof (tportProps.portID));
(void) printf("\n\t\t\t%s %d\n",
} else {
(void) printf("\t\t%s ",
sizeof (tportProps.portID));
(void) printf("\n\t\t%s %d\n",
}
/* insert blank line if not the last target port. */
(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
{
char *cmdStr =
int op;
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* we found the lu oid, now change the options requested */
switch (optionList->optval) {
case 'a':
/* modify autofailback */
getTextString(TEXT_ON))) {
mpstatus =
getTextString(TEXT_OFF))) {
mpstatus =
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'p':
/* modify autoprobing */
getTextString(TEXT_ON))) {
mpstatus =
getTextString(TEXT_OFF))) {
mpstatus =
} else {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
break;
case 'b':
/* modify loadbalance type */
mpstatus =
break;
} /* switch */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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[])
{
int tpg;
/* LINTED E_SEC_PRINTF_VAR_FMT */
operand[0]);
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* get LUN properties and check to be sure it's asymmetric */
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
/* get TPGs for this LUN */
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (mpstatus);
}
/* pick a TPG whose state is active or standby, and change it */
/* to opposite via MP_SetTPGAccessState */
sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (ERROR_CLI_FAILED);
}
return (ERROR_CLI_FAILED);
}
/* find one that is standby */
if ((MP_ACCESS_STATE_STANDBY ==
mpstatus =
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (mpstatus);
}
}
} /* for each tpg */
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
*
* ****************************************************************************
*/
{
int i,
lu;
/* print some kind of error msg here - should never happen */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (B_FALSE);
}
pluOid->objectSequenceNumber = 0;
pluOid->objectType = 0;
!= MP_STATUS_SUCCESS) {
return (B_FALSE);
}
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
/* get properties so we can list the name */
if ((mpstatus =
&pluginProps)) != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
/* attempt to find this logical unit */
if (mpstatus != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
/* get lu properties so we can check the name */
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
} 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 (0 ==
}
}
}
}
if (fd1 >= 0) {
}
if (fd2 >= 0) {
}
}
pluOid->objectType =
}
}
}
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
{
int ol,
i,
return (ERROR_CLI_FAILED);
}
}
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
mpstatus =
&pInitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
} else if ((NULL == pInitOidList) ||
} else {
for (iport = 0;
if ((mpstatus =
&initProps)) != MP_STATUS_SUCCESS) {
"%s: %s\n", cmdName,
} else {
/* if no operands listed, */
/* list all we find */
if (0 == operandLen) {
} else {
/* check each operand */
/* Is it */
/* the one we want to list? */
for (ol = 0;
if (0 ==
portID)) {
bListIt =
}
}
}
}
initProps) != 0) {
return (ERROR_CLI_FAILED);
}
} /* list It */
} /* for each initiator port */
} /* else found an init port */
} /* for each plugin */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
}
}
return (mpstatus);
}
/*
* ****************************************************************************
*
* listIndividualInitiatorPort -
* used by listInitiatorPort to list info for one init port
*
* initProps - properties of initiator port to list
*
* ****************************************************************************
*/
int
{
(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
{
int op,
i,
!= MP_STATUS_SUCCESS) {
return (mpstatus);
}
return (ERROR_CLI_FAILED);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
mpstatus =
&pInitOidList);
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
} else if ((NULL == pInitOidList) ||
} else {
for (iport = 0;
iport ++) {
if ((mpstatus =
&initProps))
!= MP_STATUS_SUCCESS) {
"%s: %s\n", cmdName,
} else {
}
}
mpstatus =
if (0 != mpstatus) {
return (mpstatus);
}
} /* list It */
} /* for each initiator port */
} /* else found an init port */
} /* for each plugin */
/* need temp string here since we need to fill in a */
/* name in the error string */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
(void) printf("\n");
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
{
switch (optionList->optval) {
case 'i':
/* have init port name */
break;
case 't':
/* have target port id */
break;
case 'l':
/* have LU name */
break;
}
}
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* found the path, attempt to enable it */
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
switch (optionList->optval) {
case 'i':
/* have init port name */
break;
case 't':
/* have target port id */
break;
case 'l':
/* have LU name */
break;
}
}
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* found the path, attempt to enable it */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
{
/* First check to see if we have the cancel option, */
/* May as well save off the lun while we're at it */
switch (optionList->optval) {
case 'c':
/* we have a cancel */
break;
case 'l':
/* we have a lun- save it while we're here */
(void) memcpy(pLuDeviceFileName,
break;
}
}
if (B_TRUE == bCancelOverride) {
/* if we have the cancel option, */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* cancel the override path for the specified LU */
if (MP_STATUS_SUCCESS != mpstatus) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (mpstatus);
}
} else {
/* must be wanting to override the path */
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (ERROR_CLI_FAILED);
}
/* attempt to set the override path */
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(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
*
* ****************************************************************************
*/
{
int i,
lu,
pa;
return (B_FALSE);
}
switch (optionList->optval) {
case 'i':
/* save init port name */
(void) memcpy(initPortID,
break;
case 't':
/* save target port id */
(void) memcpy(targetPortID,
break;
case 'l':
/* save LU name */
(void) memcpy(luDeviceFileName,
break;
}
}
/* if we don't have all three pieces, we can't find the path */
return (B_FALSE);
}
/* get the plugin ist */
!= MP_STATUS_SUCCESS) {
return (B_FALSE);
}
return (B_FALSE);
}
for (i = 0; i < pPluginOidList->oidCount; i++) {
/* get Logical Unit list */
if (mpstatus != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
/* get lu properties so we can check the name */
sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
if (0 == strcmp(luDeviceFileName,
/* get paths for this LU and search from here */
mpstatus =
if (mpstatus != MP_STATUS_SUCCESS) {
/* LINTED E_SEC_PRINTF_VAR_FMT */
(void) printf("\n");
return (B_FALSE);
}
for (pa = 0;
mpstatus =
&pathProps);
if (mpstatus != MP_STATUS_SUCCESS) {
"%s: %s\n", cmdName,
return (B_FALSE);
}
/*
* get properties of iniator port and
* target port to see if we have the
* right path
*/
mpstatus =
&initProps);
if (mpstatus != MP_STATUS_SUCCESS) {
"%s: %s\n", cmdName,
return (B_FALSE);
}
/* lu and init port matches, check target port */
&targProps);
if (mpstatus != MP_STATUS_SUCCESS) {
return (B_FALSE);
}
/* we found our path */
}
} /* 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.
*
* ****************************************************************************
*/
getLbValueFromString(char *lbStr)
{
lbVal = 0;
}
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
{
char *typeString;
switch (typeVal) {
case MP_LU_NAME_TYPE_UNKNOWN:
break;
break;
break;
break;
break;
default:
break;
}
} /* 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
{
char *lbString;
switch (lbVal) {
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
default:
break;
}
} /* 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
{
char *ttypeString;
switch (transportTypeVal) {
break;
break;
break;
break;
break;
default:
break;
}
} /* end displayTransportTypeString */
/*
* ****************************************************************************
*
* getMpStatusStr
* Gets the string description for the specified load balance type value
*
* mpstatus - MP_STATUS value
*
* ****************************************************************************
*/
char *
{
char *statString;
switch (mpstatus) {
case MP_STATUS_SUCCESS:
break;
break;
case MP_STATUS_UNKNOWN_FN:
break;
case MP_STATUS_FAILED:
break;
break;
break;
case MP_STATUS_UNSUPPORTED:
break;
break;
break;
case MP_STATUS_FN_REPLACED:
break;
break;
case MP_STATUS_TRY_AGAIN:
break;
case MP_STATUS_NOT_PERMITTED:
break;
default:
break;
}
return (statString);
} /* end getMpStatusStr */
/*
* ****************************************************************************
*
* GetPathStateStr
* Gets the string description for the specified path state type value
*
* pathState - MP_PATH_STATE values
*
* ****************************************************************************
*/
char *
{
char *pathString;
switch (pathState) {
case MP_PATH_STATE_OKAY:
break;
case MP_PATH_STATE_PATH_ERR:
break;
case MP_PATH_STATE_LU_ERR:
break;
case MP_PATH_STATE_RESERVED:
break;
case MP_PATH_STATE_REMOVED:
break;
break;
break;
break;
break;
default:
break;
}
return (pathString);
} /* end getPathStateStr */
/*
* ****************************************************************************
*
* getAccessStateStr
* Gets the string description for the specified access state type value
*
* accessState - MP_ACCESS_STATE_TYPE values
*
* ****************************************************************************
*/
char *
{
char *accessString;
switch (accessState) {
break;
break;
case MP_ACCESS_STATE_STANDBY:
break;
break;
break;
case MP_ACCESS_STATE_ACTIVE:
break;
default:
break;
}
return (accessString);
} /* end getAccessStateStr */
/*
* ****************************************************************************
*
* displayArray
* Print out the specified array.
*
* arrayToDisplay - array to display
* arraySize - size of array to display
*
* ****************************************************************************
*/
void
{
int i;
for (i = 0; i < arraySize; i++) {
if ('\0' != 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 *
{
int i;
} else {
for (i = 0; i < arraySize; i++) {
newStr[i] = arrayToDisplay[i];
}
}
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
{
int i;
for (i = 0; i < numChars; i++) {
if (L'\0' != arrayToDisplay[i]) {
}
}
}
/*
* ****************************************************************************
*
* listfunc
* Used by cmdparse for list clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
break;
case LOGICAL_UNIT:
break;
case INITIATOR_PORT:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* showFunc
* used bycmdparse for show clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
break;
case LOGICAL_UNIT:
break;
case INITIATOR_PORT:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* modifyFunc
* Used by cmdparse for midify clis
*
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case MPATH_SUPPORT:
break;
case LOGICAL_UNIT:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* enableFunc
* Used by cmdpars for enable clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* disableFunc
* Used by cmdpars for disable clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* failoverFunc
* Used by cmdpars for failover clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case LOGICAL_UNIT:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* ****************************************************************************
*
* overrideFunc
* Used by cmdpars for override clis
*
* ****************************************************************************
*/
/*ARGSUSED*/
static int
void *addArgs)
{
int ret = 0;
switch (object) {
case PATH:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*
* *************************************************************************
*
* main
*
* *************************************************************************
*/
int
{
int ret;
int funcRet;
void *subcommandArgs = NULL;
/* set global command name */
if (ret == 1) {
return (ERROR_CLI_FAILED);
} else if (ret == -1) {
return (1);
}
if (funcRet != 0) {
return (1);
}
return (0);
} /* end main */