/* * 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 #include #include "cmdparse.h" #include "mpathadm_text.h" #include "mpathadm.h" #include #include #include #include #include #include /* 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 , ... * * 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] , ... * * 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] [, ...] * * 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} , ... * * 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] , ... * * 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} , ... * * 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 [, ...] * * 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 , ... * * 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 * -t -l * * 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 * -t -l * * 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 * -t | -c} * * 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 */