1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * mpathadm.c : MP API CLI program
28 *
29 */
30
31 #include <libintl.h>
32
33 #include <mpapi.h>
34 #include "cmdparse.h"
35 #include "mpathadm_text.h"
36 #include "mpathadm.h"
37
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <devid.h>
43 #include <fcntl.h>
44
45 /* helper functions */
46 static char *getExecBasename(char *);
47
48 /* object functions per subcommand */
49 static int listFunc(int, char **, int, cmdOptions_t *, void *);
50 static int showFunc(int, char **, int, cmdOptions_t *, void *);
51 static int modifyFunc(int, char **, int, cmdOptions_t *, void *);
52 static int enableFunc(int, char **, int, cmdOptions_t *, void *);
53 static int disableFunc(int, char **, int, cmdOptions_t *, void *);
54 static int failoverFunc(int, char **, int, cmdOptions_t *, void *);
55 static int overrideFunc(int, char **, int, cmdOptions_t *, void *);
56
57 #define VERSION_STRING_MAX_LEN 10
58
59 #define OPTIONSTRING_NAME "name"
60 #define OPTIONSTRING_TPNAME "target-port name"
61 #define OPTIONSTRING_ONOFF "on/off"
62 #define OPTIONSTRING_LBTYPE "loadbalance type"
63 #define OPTIONSTRING_IPORT "initiator-port name"
64 #define OPTIONSTRING_LUNIT "logical-unit name"
65 #define OPTIONSTRING_CANCEL "cancel"
66 #define OPTIONSTRING_VALUE "value"
67
68 /*
69 * Version number: (copied from iscsiadm)
70 * MAJOR - This should only change when there is an incompatible change made
71 * to the interfaces or the output.
72 *
73 * MINOR - This should change whenever there is a new command or new feature
74 * with no incompatible change.
75 */
76 #define VERSION_STRING_MAJOR "1"
77 #define VERSION_STRING_MINOR "0"
78
79
80 /* globals */
81 static char *cmdName;
82
83
84 /*
85 * ****************************************************************************
86 *
87 * getExecBasename - copied from iscsiadm code
88 *
89 * input:
90 * execFullName - exec name of program (argv[0])
91 *
92 * Returns:
93 * command name portion of execFullName
94 *
95 * ****************************************************************************
96 */
97 static char *
getExecBasename(char * execFullname)98 getExecBasename(char *execFullname)
99 {
100 char *lastSlash, *execBasename;
101
102 /* guard against '/' at end of command invocation */
103 for (;;) {
104 lastSlash = strrchr(execFullname, '/');
105 if (lastSlash == NULL) {
106 execBasename = execFullname;
107 break;
108 } else {
109 execBasename = lastSlash + 1;
110 if (*execBasename == '\0') {
111 *lastSlash = '\0';
112 continue;
113 }
114 break;
115 }
116 }
117 return (execBasename);
118 }
119
120
121 /*
122 * Add new options here
123 */
124
125 /* tables set up based on cmdparse instructions */
126 optionTbl_t longOptions[] = {
127 {"inqname", required_arg, 'n', OPTIONSTRING_NAME},
128 {"target-port", required_arg, 't', OPTIONSTRING_TPNAME},
129 {"autofailback", required_arg, 'a', OPTIONSTRING_ONOFF},
130 {"autoprobe", required_arg, 'p', OPTIONSTRING_ONOFF},
131 {"loadbalance", required_arg, 'b', OPTIONSTRING_LBTYPE},
132 {"initiator-port", required_arg, 'i', OPTIONSTRING_IPORT},
133 {"logical-unit", required_arg, 'l', OPTIONSTRING_LUNIT},
134 {"cancel", no_arg, 'c', OPTIONSTRING_CANCEL},
135 {"vendor-id", required_arg, 'd', OPTIONSTRING_VALUE},
136 {NULL, 0, 0, 0}
137 };
138
139
140 /*
141 * Add new subcommands here
142 */
143 subcommand_t subcommands[] = {
144 {"list", LIST, listFunc},
145 {"show", SHOW, showFunc},
146 {"modify", MODIFY, modifyFunc},
147 {"enable", ENABLE, enableFunc},
148 {"disable", DISABLE, disableFunc},
149 {"failover", FAILOVER, failoverFunc},
150 {"override", OVERRIDE, overrideFunc},
151 {NULL, 0, NULL}
152 };
153
154 /*
155 * Add objects here
156 */
157 object_t objects[] = {
158 {"mpath-support", MPATH_SUPPORT},
159 {"logical-unit", LOGICAL_UNIT},
160 {"LU", LOGICAL_UNIT},
161 {"initiator-port", INITIATOR_PORT},
162 {"path", PATH},
163 {NULL, 0}
164 };
165
166 /*
167 * Rules for subcommands and objects
168 *
169 * command
170 *
171 * reqOpCmd -> subcommands that must have an operand
172 * optOpCmd -> subcommands that may have an operand
173 * noOpCmd -> subcommands that will have no operand
174 * invCmd -> subcommands that are invalid
175 * multOpCmd -> subcommands that can accept multiple operands
176 * operandDefinition -> Usage definition for the operand of this object
177 */
178 objectRules_t objectRules[] = {
179 {MPATH_SUPPORT, SHOW|MODIFY|ADD, LIST|REMOVE, 0,
180 ENABLE|DISABLE|FAILOVER|OVERRIDE, LIST|SHOW|MODIFY,
181 "mpath-support name"},
182 {INITIATOR_PORT, SHOW, LIST, 0,
183 MODIFY|ENABLE|DISABLE|FAILOVER|OVERRIDE|ADD|REMOVE, LIST|SHOW,
184 "initiator-port name"},
185 {LOGICAL_UNIT, SHOW|MODIFY|FAILOVER, LIST, 0,
186 ENABLE|DISABLE|OVERRIDE|ADD|REMOVE, LIST|SHOW|MODIFY,
187 "logical-unit name"},
188 {PATH, 0, 0, ENABLE|DISABLE|OVERRIDE,
189 SHOW|LIST|MODIFY|FAILOVER|ADD|REMOVE, 0,
190 "initiator-port name"},
191 {0, 0, 0, 0, 0, NULL}
192 };
193
194 /*
195 * list of objects, subcommands, valid short options, required flag and
196 * exclusive option string
197 *
198 * If it's not here, there are no options for that object.
199 */
200 optionRules_t optionRules[] = {
201 {LOGICAL_UNIT, LIST, "nt", B_FALSE, NULL},
202 {LOGICAL_UNIT, MODIFY, "apb", B_TRUE, NULL},
203 {MPATH_SUPPORT, MODIFY, "apb", B_TRUE, NULL},
204 {MPATH_SUPPORT, ADD, "d", B_TRUE, NULL},
205 {MPATH_SUPPORT, REMOVE, "d", B_TRUE, NULL},
206 {PATH, ENABLE, "itl", B_TRUE, NULL},
207 {PATH, DISABLE, "itl", B_TRUE, NULL},
208 {PATH, OVERRIDE, "itlc", B_TRUE, NULL},
209 {0, 0, 0, 0, 0}
210 };
211
212
213 /*
214 * ****************************************************************************
215 *
216 * listMpathSupport - mpathadm list mpath-support
217 *
218 * operandLen - number of operands user passed into the cli
219 * operand - pointer to operand list from user
220 *
221 * ****************************************************************************
222 */
223 int
listMpathSupport(int operandLen,char * operand[])224 listMpathSupport(int operandLen, char *operand[])
225 {
226 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
227 MP_PLUGIN_PROPERTIES pluginProps;
228 MP_OID_LIST *pPluginOidList;
229 boolean_t shown = B_FALSE;
230 /* number of plugins listed */
231 int i, op;
232
233 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
234 != MP_STATUS_SUCCESS) {
235 (void) fprintf(stderr, "%s: %s\n", cmdName,
236 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
237 return (mpstatus);
238 }
239 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
240 (void) fprintf(stderr, "%s: %s\n", cmdName,
241 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
242 return (ERROR_CLI_FAILED);
243 }
244
245
246 /* loop through operands first */
247 for (op = 0; (op < operandLen) |
248 ((0 == operandLen) && (B_FALSE == shown)); op++) {
249 shown = B_TRUE;
250 for (i = 0; i < pPluginOidList->oidCount; i++) {
251
252 (void) memset(&pluginProps, 0,
253 sizeof (MP_PLUGIN_PROPERTIES));
254 mpstatus =
255 MP_GetPluginProperties(pPluginOidList->oids[i],
256 &pluginProps);
257 if (mpstatus != MP_STATUS_SUCCESS) {
258 (void) fprintf(stderr, "%s: %s\n",
259 cmdName, getTextString(ERR_NO_PROPERTIES));
260 } else {
261 if (0 == operandLen) {
262 /* if no operands, list them all */
263 (void) printf("%s %s\n",
264 getTextString(
265 TEXT_LB_MPATH_SUPPORT),
266 pluginProps.fileName);
267 } else {
268 /* if there is an operand... */
269 /* ... compare and display if match */
270 if (0 ==
271 strcmp(operand[op],
272 pluginProps.fileName)) {
273 (void) printf("%s %s\n",
274 getTextString(
275 TEXT_LB_MPATH_SUPPORT),
276 pluginProps.fileName);
277 } else {
278 /* begin back-up indentation */
279 /* LINTED E_SEC_PRINTF_VAR_FMT */
280 (void) fprintf(stderr, getTextString(
281 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME),
282 operand[op]);
283 /* end back-up indentation */
284 (void) printf("\n");
285 }
286 }
287 }
288 }
289 }
290
291 return (mpstatus);
292 }
293
294
295 /*
296 * ****************************************************************************
297 *
298 * showMpathSupport - mpathadm show mpath-support <mpath-support name>, ...
299 *
300 * operandLen - number of operands user passed into the cli
301 * operand - pointer to operand list from user
302 *
303 * ****************************************************************************
304 */
305 int
showMpathSupport(int operandLen,char * operand[])306 showMpathSupport(int operandLen, char *operand[])
307 {
308 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
309 MP_PLUGIN_PROPERTIES pluginProps;
310 MP_OID_LIST *pPluginOidList;
311 MP_OID_LIST *deviceOidListArray;
312 MP_DEVICE_PRODUCT_PROPERTIES devProps;
313 boolean_t bListIt = B_FALSE;
314 int op, i, j;
315 MP_LOAD_BALANCE_TYPE lb;
316
317
318 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList)) !=
319 MP_STATUS_SUCCESS) {
320 (void) fprintf(stderr, "%s: %s\n",
321 cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST));
322 return (mpstatus);
323 }
324 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
325 (void) fprintf(stderr, "%s: %s\n",
326 cmdName, getTextString(ERR_NO_MPATH_SUPPORT_LIST));
327 return (ERROR_CLI_FAILED);
328 }
329
330 for (op = 0; op < operandLen; op++) {
331 bListIt = B_FALSE;
332
333 for (i = 0; i < pPluginOidList->oidCount; i++) {
334
335 (void) memset(&pluginProps, 0,
336 sizeof (MP_PLUGIN_PROPERTIES));
337 mpstatus =
338 MP_GetPluginProperties(pPluginOidList->oids[i],
339 &pluginProps);
340 if (MP_STATUS_SUCCESS != mpstatus) {
341 (void) fprintf(stderr, "%s: %s\n",
342 cmdName, getTextString(ERR_NO_PROPERTIES));
343 return (mpstatus);
344 }
345
346 if (0 == operandLen) {
347 /* if no operand, list it */
348 bListIt = B_TRUE;
349 } else {
350 /* ... compare and display if match */
351 if (0 ==
352 strcmp(operand[op],
353 pluginProps.fileName)) {
354 bListIt = B_TRUE;
355 }
356 }
357
358 if (B_TRUE != bListIt) {
359 break;
360 }
361
362 (void) printf("%s %s\n",
363 getTextString(TEXT_LB_MPATH_SUPPORT),
364 pluginProps.fileName);
365
366 /* display the info for this plugin */
367 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR));
368 displayWideArray(pluginProps.vendor,
369 sizeof (pluginProps.vendor));
370 (void) printf("\n\t%s ",
371 getTextString(TEXT_LB_DRIVER_NAME));
372 displayArray(pluginProps.driverName,
373 sizeof (pluginProps.driverName));
374 (void) printf("\n\t%s ",
375 getTextString(TEXT_LB_DEFAULT_LB));
376 /* don't ignore load balance type none. */
377 if (pluginProps.defaultloadBalanceType == 0) {
378 (void) printf("%s",
379 getTextString(TEXT_LBTYPE_NONE));
380 } else {
381 displayLoadBalanceString(
382 pluginProps.defaultloadBalanceType);
383 }
384 (void) printf("\n");
385
386
387 (void) printf("\t%s \n",
388 getTextString(TEXT_LB_SUPPORTED_LB));
389 /* check each bit, display string if found set */
390 if (pluginProps.supportedLoadBalanceTypes == 0) {
391 (void) printf("\t\t%s\n",
392 getTextString(TEXT_LBTYPE_NONE));
393 } else {
394 lb = 1;
395 do {
396 if (0 != (lb & pluginProps.
397 supportedLoadBalanceTypes)) {
398 (void) printf("\t\t");
399 displayLoadBalanceString(lb &
400 pluginProps.
401 supportedLoadBalanceTypes);
402 (void) printf("\n");
403 }
404 lb = lb<<1;
405 } while (lb < 0x80000000);
406 }
407
408 (void) printf("\t%s %s\n",
409 getTextString(TEXT_LB_ALLOWS_ACT_TPG),
410 (MP_TRUE == pluginProps.canSetTPGAccess)?
411 getTextString(TEXT_YES):getTextString(TEXT_NO));
412 (void) printf("\t%s %s\n",
413 getTextString(TEXT_LB_ALLOWS_PATH_OV),
414 (MP_TRUE == pluginProps.canOverridePaths)?
415 getTextString(TEXT_YES):getTextString(TEXT_NO));
416 (void) printf("\t%s %d\n",
417 getTextString(TEXT_LB_SUPP_AUTO_FB),
418 pluginProps.autoFailbackSupport);
419 if ((MP_AUTOFAILBACK_SUPPORT_PLUGIN ==
420 pluginProps.autoFailbackSupport) |
421 (MP_AUTOFAILBACK_SUPPORT_PLUGINANDMPLU
422 == pluginProps.autoFailbackSupport)) {
423 (void) printf("\t%s %s\n",
424 getTextString(TEXT_LB_AUTO_FB),
425 pluginProps.pluginAutoFailbackEnabled?\
426 getTextString(TEXT_ON):
427 getTextString(TEXT_OFF));
428 (void) printf("\t%s %d/%d\n",
429 getTextString(TEXT_LB_FB_POLLING_RATE),
430 pluginProps.currentFailbackPollingRate,
431 pluginProps.failbackPollingRateMax);
432 } else {
433 (void) printf("\t%s %s\n",
434 getTextString(TEXT_LB_AUTO_FB),
435 getTextString(TEXT_NA));
436 (void) printf("\t%s %s/%s\n",
437 getTextString(TEXT_LB_FB_POLLING_RATE),
438 getTextString(TEXT_NA),
439 getTextString(TEXT_NA));
440 }
441 (void) printf("\t%s %d\n",
442 getTextString(TEXT_LB_SUPP_AUTO_P),
443 pluginProps.autoProbingSupport);
444 if ((MP_AUTOPROBING_SUPPORT_PLUGIN ==
445 pluginProps.autoProbingSupport) |
446 (MP_AUTOPROBING_SUPPORT_PLUGIN ==
447 pluginProps.autoProbingSupport)) {
448 (void) printf("\t%s %s\n",
449 getTextString(TEXT_LB_AUTO_PROB),
450 (MP_TRUE ==
451 pluginProps.pluginAutoProbingEnabled)?\
452 getTextString(TEXT_YES):
453 getTextString(TEXT_NO));
454 (void) printf("\t%s %d/%d\n",
455 getTextString(TEXT_LB_PR_POLLING_RATE),
456 pluginProps.currentProbingPollingRate,
457 pluginProps.probingPollingRateMax);
458 } else {
459 (void) printf("\t%s %s\n",
460 getTextString(TEXT_LB_AUTO_PROB),
461 getTextString(TEXT_NA));
462 (void) printf("\t%s %s/%s\n",
463 getTextString(TEXT_LB_PR_POLLING_RATE),
464 getTextString(TEXT_NA),
465 getTextString(TEXT_NA));
466 }
467
468
469 (void) printf("\t%s\n",
470 getTextString(TEXT_LB_SUPP_DEVICES));
471
472
473 if (MP_TRUE !=
474 pluginProps.onlySupportsSpecifiedProducts) {
475 /* LINTED E_SEC_PRINTF_VAR_FMT */
476 (void) printf(getTextString(TEXT_ANY_DEVICE));
477 } else {
478 /* if only supports specific products, */
479 /* get device product properties supported */
480
481 mpstatus = MP_GetDeviceProductOidList(\
482 pPluginOidList->oids[i],
483 &deviceOidListArray);
484 if (mpstatus != MP_STATUS_SUCCESS) {
485 (void) fprintf(stderr, "%s: %s\n",
486 cmdName, getTextString(
487 ERR_NO_SUPP_DEVICE_INFO));
488 /* can't get any more info, */
489 /* so we're done with this one */
490 break;
491 }
492
493 for (j = 0; j < deviceOidListArray->oidCount;
494 j++) {
495 /* begin backup indentation */
496 (void) memset(&devProps, 0,
497 sizeof (MP_DEVICE_PRODUCT_PROPERTIES));
498 /* end backup indentation */
499 if ((mpstatus =
500 MP_GetDeviceProductProperties(\
501 deviceOidListArray->oids[j],
502 &devProps)) == MP_STATUS_SUCCESS) {
503
504 (void) printf("\t\t%s ",
505 getTextString(
506 TEXT_LB_VENDOR));
507 displayArray(devProps.vendor,
508 sizeof (devProps.vendor));
509 (void) printf("\n\t\t%s ",
510 getTextString(
511 TEXT_LB_PRODUCT));
512 displayArray(devProps.product,
513 sizeof (devProps.product));
514 (void) printf("\n\t\t%s ",
515 getTextString(
516 TEXT_LB_REVISION));
517 displayArray(devProps.revision,
518 sizeof (devProps.revision));
519
520 (void) printf("\n\t\t%s\n",
521 getTextString(
522 TEXT_LB_SUPPORTED_LB));
523 /* begin back-up indentation */
524 if (devProps.supportedLoadBalanceTypes == 0) {
525 (void) printf("\t\t\t%s\n",
526 getTextString(TEXT_LBTYPE_NONE));
527 } else {
528 lb = 1;
529 do {
530 if (0 != (lb &
531 devProps.supportedLoadBalanceTypes)) {
532 (void) printf("\t\t\t");
533 displayLoadBalanceString(lb &
534 devProps.supportedLoadBalanceTypes);
535 (void) printf("\n");
536 }
537 lb = lb<<1;
538 } while (lb < 0x80000000);
539 }
540 /* end back-up indentation */
541 (void) printf("\n");
542
543 } else {
544 (void) fprintf(stderr,
545 "%s: %s\n", cmdName,
546 getTextString(
547 ERR_NO_SUPP_DEVICE_INFO));
548 }
549 } /* for j */
550 } /* if only supports specified devices */
551
552 } /* for each plugin */
553
554 if (B_FALSE == bListIt) {
555 /* LINTED E_SEC_PRINTF_VAR_FMT */
556 (void) fprintf(stderr, getTextString(
557 ERR_CANT_FIND_MPATH_SUPPORT_WITH_NAME),
558 operand[op]);
559 (void) printf("\n");
560
561 }
562
563 } /* for each operand */
564
565
566 return (mpstatus);
567 }
568
569
570 /*
571 * ****************************************************************************
572 *
573 * modifyMpathSupport -
574 * mpathadm modify mpath-support [options] <mpath-support name>, ...
575 *
576 * operandLen - number of operands user passed into the cli
577 * operand - pointer to operand list from user
578 * options - pointer to option list from user
579 *
580 * ****************************************************************************
581 */
582 int
modifyMpathSupport(int operandLen,char * operand[],cmdOptions_t * options)583 modifyMpathSupport(int operandLen, char *operand[], cmdOptions_t *options)
584 {
585 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
586 MP_PLUGIN_PROPERTIES pluginProps;
587 MP_OID_LIST *pPluginOidList;
588 boolean_t bFoundIt = B_FALSE;
589 MP_OID pluginOid;
590 cmdOptions_t *optionList = options;
591 char *cmdStr = getTextString(TEXT_UNKNOWN);
592 int op, i, lbValue;
593
594 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
595 != MP_STATUS_SUCCESS) {
596 (void) fprintf(stderr, "%s: %s\n", cmdName,
597 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
598 return (mpstatus);
599 }
600 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
601 (void) fprintf(stderr, "%s: %s\n", cmdName,
602 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
603 return (ERROR_CLI_FAILED);
604 }
605
606 for (op = 0; op < operandLen; op++) {
607 bFoundIt = B_FALSE;
608 for (i = 0;
609 (i < pPluginOidList->oidCount) && (B_TRUE != bFoundIt);
610 i++) {
611
612 (void) memset(&pluginProps, 0,
613 sizeof (MP_PLUGIN_PROPERTIES));
614 if ((mpstatus =
615 MP_GetPluginProperties(pPluginOidList->oids[i],
616 &pluginProps)) == MP_STATUS_SUCCESS) {
617
618 if (0 == strcmp(operand[op],
619 pluginProps.fileName)) {
620 bFoundIt = B_TRUE;
621 pluginOid = pPluginOidList->oids[i];
622 }
623 } else {
624 (void) fprintf(stderr, "%s: %s\n",
625 cmdName, getTextString(ERR_NO_PROPERTIES));
626 }
627
628 if (B_FALSE == bFoundIt) {
629 break;
630 }
631
632 /* begin back-up indentation */
633 /* we found the plugin oid */
634 /* now change the options requested */
635 switch (optionList->optval) {
636 case 'a':
637 /* modify autofailback */
638 cmdStr = getTextString(TEXT_AUTO_FAILBACK);
639 if (0 == strcasecmp(optionList->optarg,
640 getTextString(TEXT_ON))) {
641 mpstatus =
642 MP_EnableAutoFailback(pluginOid);
643 } else if (0 ==
644 strcasecmp(optionList->optarg,
645 getTextString(TEXT_OFF))) {
646 mpstatus =
647 MP_DisableAutoFailback(pluginOid);
648 } else {
649 /* LINTED E_SEC_PRINTF_VAR_FMT */
650 (void) fprintf(stderr, getTextString(
651 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
652 cmdStr,
653 getTextString(TEXT_ILLEGAL_ARGUMENT));
654 (void) printf("\n");
655 return (ERROR_CLI_FAILED);
656 }
657 break;
658 case 'p':
659 /* modify autoprobing */
660 cmdStr = getTextString(TEXT_AUTO_PROBING);
661 if (0 == strcasecmp(optionList->optarg,
662 getTextString(TEXT_ON))) {
663 mpstatus =
664 MP_EnableAutoProbing(pluginOid);
665 } else if (0 ==
666 strcasecmp(optionList->optarg,
667 getTextString(TEXT_OFF))) {
668 mpstatus =
669 MP_DisableAutoProbing(pluginOid);
670 } else {
671 /* LINTED E_SEC_PRINTF_VAR_FMT */
672 (void) fprintf(stderr, getTextString(
673 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
674 cmdStr,
675 getTextString(TEXT_ILLEGAL_ARGUMENT));
676 (void) printf("\n");
677 return (ERROR_CLI_FAILED);
678 }
679 break;
680 case 'b':
681 /* modify loadbalance type */
682 cmdStr = getTextString(TEXT_LOAD_BALANCE);
683 /* user of the cli sends text string, we need the int */
684 /* value to pass to the mpapi */
685 lbValue = getLbValueFromString(optionList->optarg);
686 mpstatus =
687 MP_SetPluginLoadBalanceType(pluginOid,
688 lbValue);
689 break;
690
691 } /* switch */
692 if (MP_STATUS_SUCCESS != mpstatus) {
693 /* LINTED E_SEC_PRINTF_VAR_FMT */
694 (void) fprintf(stderr,
695 getTextString(
696 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
697 cmdStr, getMpStatusStr(mpstatus));
698 (void) printf("\n");
699 return (mpstatus);
700 }
701 /* end back-up indentation */
702
703 } /* for each plugin */
704
705 if (B_FALSE == bFoundIt) {
706 /* LINTED E_SEC_PRINTF_VAR_FMT */
707 (void) fprintf(stderr,
708 getTextString(
709 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
710 cmdStr,
711 getTextString(TEXT_MPATH_SUPPORT_NOT_FOUND));
712 (void) printf("\n");
713 return (ERROR_CLI_FAILED);
714 }
715
716 } /* for each operand */
717
718 return (mpstatus);
719 }
720
721
722 /*
723 * ****************************************************************************
724 *
725 * listLogicalUnit -
726 * mpathadm list {logical-unit | LU} [options] [<logical-unit name>, ...]
727 *
728 * operandLen - number of operands user passed into the cli
729 * operand - pointer to operand list from user
730 * options - pointer to option list from user
731 *
732 * ****************************************************************************
733 */
734 int
listLogicalUnit(int operandLen,char * operand[],cmdOptions_t * options)735 listLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options)
736 {
737 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
738 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
739 MP_PLUGIN_PROPERTIES pluginProps;
740 MP_TARGET_PORT_PROPERTIES tportProps;
741 MP_OID_LIST *pPluginOidList, *pLogicalUnitOidList,
742 *pTpgOidListArray, *pTportOidListArray;
743 boolean_t bListIt = B_FALSE, bFoundOperand = B_FALSE,
744 *bFoundOption, bContinue = B_FALSE;
745 MP_OID luOid;
746 cmdOptions_t *optionList = options;
747 int opListCount = 0, i = 0, lu = 0, tpg = 0, opoffset = 0, j = 0,
748 opStart = 0, opEnd = 0, opIndex;
749
750 /* count number of options */
751 for (; optionList->optval; optionList++) {
752 opListCount++;
753 }
754
755 bFoundOption = malloc((sizeof (boolean_t)) * opListCount);
756 if (NULL == bFoundOption) {
757 (void) fprintf(stdout, "%s\n",
758 getTextString(ERR_MEMORY_ALLOCATION));
759 return (ERROR_CLI_FAILED);
760 }
761
762 /* list to keep track of multiple options */
763 optionList = options;
764 for (opIndex = 0; opIndex < opListCount; opIndex++) {
765 bFoundOption[opIndex] = B_FALSE;
766 }
767
768 optionList = options;
769
770 /* if no operands or options, list everything we find */
771 if ((0 == operandLen) && (0 == opListCount)) {
772 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
773 != MP_STATUS_SUCCESS) {
774 (void) fprintf(stderr, "%s: %s\n", cmdName,
775 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
776 return (mpstatus);
777 }
778 if ((NULL == pPluginOidList) ||
779 (pPluginOidList->oidCount < 1)) {
780 (void) fprintf(stderr, "%s: %s\n", cmdName,
781 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
782 return (ERROR_CLI_FAILED);
783 }
784
785 for (i = 0; i < pPluginOidList->oidCount; i++) {
786 /* get properties so we can list the name */
787 (void) memset(&pluginProps, 0,
788 sizeof (MP_PLUGIN_PROPERTIES));
789 if ((mpstatus =
790 MP_GetPluginProperties(pPluginOidList->oids[i],
791 &pluginProps)) != MP_STATUS_SUCCESS) {
792 (void) fprintf(stderr, "%s: %s\n",
793 cmdName, getTextString(ERR_NO_PROPERTIES));
794 return (mpstatus);
795 }
796
797 /* attempt to find this logical unit */
798 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
799 &pLogicalUnitOidList);
800 if (mpstatus != MP_STATUS_SUCCESS) {
801 (void) fprintf(stderr, "%s: %s\n",
802 cmdName, getTextString(ERR_NO_LU_LIST));
803 return (mpstatus);
804 }
805
806 for (lu = 0; lu < pLogicalUnitOidList->oidCount; lu++) {
807 /* begin backup indentation */
808 /* get lu properties so we can check the name */
809 (void) memset(&luProps, 0,
810 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
811 /* end backup indentation */
812 mpstatus =
813 MP_GetMPLogicalUnitProperties(
814 pLogicalUnitOidList->oids[lu],
815 &luProps);
816 if (mpstatus != MP_STATUS_SUCCESS) {
817 (void) fprintf(stderr, "%s: %s\n",
818 cmdName,
819 getTextString(ERR_NO_PROPERTIES));
820 return (mpstatus);
821 }
822
823 luOid = pLogicalUnitOidList->oids[lu];
824 if (listIndividualLogicalUnit(luOid, luProps)
825 != 0) {
826 return (ERROR_CLI_FAILED);
827 }
828 } /* for each LU */
829 } /* for each plugin */
830 } else { /* we have operands and/or options */
831
832 /* check if we have operands */
833 if (0 == operandLen) {
834 /* no operands */
835 opStart = -1;
836 opEnd = 0;
837 } else {
838 /* operands */
839 opStart = 0;
840 opEnd = operandLen;
841 }
842
843 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
844 != MP_STATUS_SUCCESS) {
845 (void) fprintf(stderr, "%s: %s\n", cmdName,
846 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
847 return (mpstatus);
848 }
849 if ((NULL == pPluginOidList) ||
850 (pPluginOidList->oidCount < 1)) {
851 (void) fprintf(stderr, "%s: %s\n", cmdName,
852 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
853 return (ERROR_CLI_FAILED);
854 }
855
856 for (opoffset = opStart; opoffset < opEnd; opoffset++) {
857 /* loop through operands */
858 bFoundOperand = B_FALSE;
859
860 for (i = 0; i < pPluginOidList->oidCount; i++) {
861
862 /*
863 * loop through plugin, and get properties
864 * so we can list the name
865 */
866 (void) memset(&pluginProps, 0,
867 sizeof (MP_PLUGIN_PROPERTIES));
868 if ((mpstatus =
869 MP_GetPluginProperties(
870 pPluginOidList->oids[i], &pluginProps))
871 != MP_STATUS_SUCCESS) {
872 (void) fprintf(stderr, "%s: %s\n",
873 cmdName,
874 getTextString(ERR_NO_PROPERTIES));
875 return (mpstatus);
876 }
877
878 /* attempt to find this logical unit */
879 mpstatus =
880 MP_GetMultipathLus(pPluginOidList->oids[i],
881 &pLogicalUnitOidList);
882 if (mpstatus != MP_STATUS_SUCCESS) {
883 (void) fprintf(stderr, "%s: %s\n",
884 cmdName,
885 getTextString(ERR_NO_LU_LIST));
886 return (mpstatus);
887 }
888
889 for (lu = 0;
890 (lu < pLogicalUnitOidList->oidCount);
891 lu++) {
892 bListIt = B_FALSE;
893 /* begin backup indentation */
894 /* get lu props & check the name */
895 (void) memset(&luProps, 0,
896 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
897 /* end backup indentation */
898 mpstatus =
899 MP_GetMPLogicalUnitProperties(
900 pLogicalUnitOidList->oids[lu],
901 &luProps);
902 if (mpstatus != MP_STATUS_SUCCESS) {
903 (void) fprintf(stderr,
904 "%s: %s\n", cmdName,
905 getTextString(
906 ERR_NO_PROPERTIES));
907 return (mpstatus);
908 }
909
910 /*
911 * compare operand - is it a match?
912 * If so, continue
913 */
914
915 bContinue = B_TRUE;
916 if (operandLen > 0) {
917 bContinue =
918 compareLUName(
919 operand[opoffset],
920 luProps.deviceFileName);
921 }
922
923 if (B_TRUE == bContinue) {
924
925 if (0 != opListCount) {
926 /* check options */
927
928
929 /* begin backup indentation */
930 optionList = options;
931
932 for (opIndex = 0; optionList->optval; optionList++, opIndex++) {
933 switch (optionList->optval) {
934 case 'n':
935 if (B_TRUE ==
936 compareLUName(optionList->optarg, luProps.name)) {
937 bListIt = B_TRUE;
938 bFoundOperand = B_TRUE;
939 bFoundOption[opIndex] = B_TRUE;
940 }
941 break;
942 case 't':
943 /* get TPG list */
944 mpstatus =
945 MP_GetAssociatedTPGOidList(pLogicalUnitOidList->oids[lu],
946 &pTpgOidListArray);
947 if (mpstatus != MP_STATUS_SUCCESS) {
948 (void) fprintf(stderr, "%s: %s\n", cmdName,
949 getTextString(ERR_NO_ASSOC_TPGS));
950 return (mpstatus);
951 }
952
953 /* get target ports */
954 for (tpg = 0;
955 (NULL != pTpgOidListArray) &&
956 (tpg < pTpgOidListArray->oidCount) &&
957 (B_FALSE == bListIt); tpg++) {
958 mpstatus =
959 MP_GetTargetPortOidList(pTpgOidListArray->oids[tpg],
960 &pTportOidListArray);
961 if (mpstatus != MP_STATUS_SUCCESS) {
962 (void) fprintf(stderr, "%s: %s\n",
963 cmdName,
964 getTextString(ERR_NO_ASSOC_TPORTS));
965 return (mpstatus);
966 }
967
968 /* get target port properties for the name */
969 for (j = 0; (NULL != pTportOidListArray) &&
970 (j < pTportOidListArray->oidCount) &&
971 (B_FALSE == bListIt); j++) {
972 (void) memset(&tportProps, 0,
973 sizeof (MP_TARGET_PORT_PROPERTIES));
974 mpstatus =
975 MP_GetTargetPortProperties(
976 pTportOidListArray->oids[j], &tportProps);
977 if (mpstatus != MP_STATUS_SUCCESS) {
978 (void) fprintf(stderr, "%s: %s\n",
979 cmdName,
980 getTextString(ERR_NO_PROPERTIES));
981 return (mpstatus);
982 }
983
984
985 /* check the name */
986 if (0 == strcmp(optionList->optarg,
987 tportProps.portID)) {
988 bListIt = B_TRUE;
989 bFoundOperand = B_TRUE;
990 bFoundOption[opIndex] = B_TRUE;
991 }
992 } /* for each target port */
993 } /* for each tpg */
994 } /* end switch */
995 } /* loop through options */
996 /* end back-up indentation */
997
998 } else {
999 /*
1000 * if no options,
1001 * listit
1002 */
1003 bListIt = B_TRUE;
1004 bFoundOperand = B_TRUE;
1005 }
1006 } /* end bContinue check */
1007
1008 if (bListIt) {
1009 (void) printf("%s %s\n",
1010 getTextString(TEXT_LB_MPATH_SUPPORT),
1011 pluginProps.fileName);
1012 luOid = pLogicalUnitOidList->oids[lu];
1013 if (listIndividualLogicalUnit(luOid, luProps)
1014 != 0) {
1015 return (ERROR_CLI_FAILED);
1016 }
1017
1018 }
1019
1020 } /* end LU loop */
1021 } /* end plugin loop */
1022 if ((0 == opListCount) && (0 != operandLen)) {
1023 if (B_FALSE == bFoundOperand) {
1024 /* option/operand combo not found */
1025 /* LINTED E_SEC_PRINTF_VAR_FMT */
1026 (void) fprintf(stderr,
1027 getTextString(
1028 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
1029 operand[opoffset]);
1030 (void) fprintf(stderr, "\n");
1031 }
1032 }
1033
1034 optionList = options;
1035 for (opIndex = 0; optionList->optval; optionList++,
1036 opIndex++) {
1037 if (B_FALSE == bFoundOption[opIndex]) {
1038 /* LINTED E_SEC_PRINTF_VAR_FMT */
1039 (void) fprintf(stderr,
1040 getTextString(
1041 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
1042 optionList->optarg);
1043 (void) fprintf(stderr, "\n");
1044 }
1045 }
1046
1047
1048
1049 } /* end loop through operands */
1050 } /* we have operands and/or options */
1051
1052
1053 return (mpstatus);
1054 }
1055
1056
1057 /*
1058 * ****************************************************************************
1059 *
1060 * compareLUName -
1061 * compare names directly and via devid if no match directly
1062 *
1063 * cmpString - first string to compare
1064 * deviceProperty - string from properties
1065 * sizeToCompare - size of deviceProperty
1066 *
1067 * returns B_TRUE if the strings match either directly or via devid
1068 * B_FALSE otherwise
1069 *
1070 * ****************************************************************************
1071 */
1072 boolean_t
compareLUName(MP_CHAR * cmpString,MP_CHAR * deviceProperty)1073 compareLUName(MP_CHAR *cmpString, MP_CHAR *deviceProperty)
1074 {
1075
1076 boolean_t isSame = B_FALSE;
1077 int fd1, fd2;
1078 ddi_devid_t devid1 = NULL, devid2 = NULL;
1079
1080 if (0 == strcmp(cmpString, deviceProperty)) {
1081 isSame = B_TRUE;
1082 } else {
1083 /* user input didn't match, try via devid */
1084 /*
1085 * I don't see a reason to print the error for
1086 * any of these since they'll get the error at
1087 * the end anyway
1088 */
1089
1090 fd1 = fd2 = -1;
1091 if (((fd1 = open(cmpString, O_RDONLY|O_NDELAY)) >= 0) &&
1092 ((fd2 = open(deviceProperty, O_RDONLY|O_NDELAY)) >= 0) &&
1093 (devid_get(fd1, &devid1) == 0) &&
1094 (devid_get(fd2, &devid2) == 0) &&
1095 ((NULL != devid1) && (NULL != devid2))) {
1096 if (0 ==
1097 (devid_compare(devid1, devid2))) {
1098 isSame = B_TRUE;
1099 }
1100 }
1101
1102 if (NULL != devid1) {
1103 devid_free(devid1);
1104 }
1105 if (NULL != devid2) {
1106 devid_free(devid2);
1107 }
1108
1109 if (fd1 >= 0) {
1110 (void) close(fd1);
1111 }
1112 if (fd2 >= 0) {
1113 (void) close(fd2);
1114 }
1115 } /* compare */
1116
1117 return (isSame);
1118 }
1119
1120
1121 /*
1122 * ****************************************************************************
1123 *
1124 * listIndivudualLogicalUnit -
1125 * Used by list logical unit cli.
1126 * Displays info about an LU
1127 *
1128 * luOid - LU to list
1129 * luProps - properties of he LU to list
1130 *
1131 * ****************************************************************************
1132 */
1133 int
listIndividualLogicalUnit(MP_OID luOid,MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps)1134 listIndividualLogicalUnit(MP_OID luOid,
1135 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps)
1136 {
1137 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
1138 MP_OID_LIST *pPathOidListArray;
1139 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1140 int numOperationalPaths, pa;
1141
1142 (void) printf("\t");
1143 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName));
1144 (void) printf("\n");
1145
1146 mpstatus = MP_GetAssociatedPathOidList(luOid,
1147 &pPathOidListArray);
1148 if (mpstatus != MP_STATUS_SUCCESS) {
1149 /* LINTED E_SEC_PRINTF_VAR_FMT */
1150 (void) fprintf(stderr,
1151 getTextString(ERR_NO_LU_PATH_INFO_WITH_MISSING_LU_STR),
1152 getStringArray(luProps.deviceFileName,
1153 sizeof (luProps.deviceFileName)));
1154 (void) fprintf(stderr, "\n");
1155 return (mpstatus);
1156 }
1157 (void) printf("\t\t%s %d\n",
1158 getTextString(TEXT_LB_PATH_COUNT), pPathOidListArray->oidCount);
1159
1160 numOperationalPaths = 0;
1161 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) {
1162 (void) memset(&pathProps, 0,
1163 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
1164 mpstatus =
1165 MP_GetPathLogicalUnitProperties(
1166 pPathOidListArray->oids[pa], &pathProps);
1167 if (mpstatus != MP_STATUS_SUCCESS) {
1168 (void) fprintf(stderr, "%s: %s\n",
1169 cmdName, getTextString(ERR_NO_PROPERTIES));
1170 return (mpstatus);
1171 }
1172
1173 /* cycle through and check status of each for */
1174 /* operation path count */
1175 if (MP_PATH_STATE_OKAY == pathProps.pathState) {
1176 numOperationalPaths++;
1177 }
1178 }
1179
1180 (void) printf("\t\t%s %d\n",
1181 getTextString(TEXT_LB_OP_PATH_COUNT), numOperationalPaths);
1182
1183 return (mpstatus);
1184 }
1185
1186
1187 /*
1188 * ****************************************************************************
1189 *
1190 * showLogicalUnit -
1191 * mpathadm show {logical-unit | LU} <logical-unit name>, ...
1192 *
1193 * operandLen - number of operands user passed into the cli
1194 * operand - pointer to operand list from user
1195 *
1196 * ****************************************************************************
1197 */
1198 int
showLogicalUnit(int operandLen,char * operand[])1199 showLogicalUnit(int operandLen, char *operand[])
1200 {
1201 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1202 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
1203 MP_PLUGIN_PROPERTIES pluginProps;
1204 MP_OID luOid, pluginOid;
1205
1206 int op;
1207
1208 for (op = 0; op < operandLen; op++) {
1209 if (op > 0) {
1210 (void) printf("\n");
1211 }
1212 if (B_TRUE == getLogicalUnitOid(operand[op], &luOid)) {
1213 (void) memset(&luProps, 0,
1214 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
1215 mpstatus =
1216 MP_GetMPLogicalUnitProperties(
1217 luOid, &luProps);
1218 if (mpstatus != MP_STATUS_SUCCESS) {
1219 (void) fprintf(stderr, "%s: %s\n",
1220 cmdName, getTextString(ERR_NO_PROPERTIES));
1221 return (mpstatus);
1222 }
1223
1224 mpstatus =
1225 MP_GetAssociatedPluginOid(luOid, &pluginOid);
1226 if (mpstatus != MP_STATUS_SUCCESS) {
1227 (void) fprintf(stderr, "%s: %s\n",
1228 cmdName,
1229 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
1230 return (mpstatus);
1231 }
1232
1233 mpstatus =
1234 MP_GetPluginProperties(pluginOid, &pluginProps);
1235 if (mpstatus != MP_STATUS_SUCCESS) {
1236 (void) fprintf(stderr, "%s: %s\n",
1237 cmdName, getTextString(ERR_NO_PROPERTIES));
1238 return (mpstatus);
1239 }
1240
1241 if (showIndividualLogicalUnit(luOid, luProps,
1242 pluginProps) != 0) {
1243 return (ERROR_CLI_FAILED);
1244 }
1245
1246 } else {
1247 /* LINTED E_SEC_PRINTF_VAR_FMT */
1248 (void) fprintf(stderr, getTextString(
1249 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
1250 operand[op]);
1251 (void) printf("\n");
1252 }
1253
1254 } /* for each operand */
1255
1256 return (mpstatus);
1257 }
1258
1259
1260 /*
1261 * ****************************************************************************
1262 *
1263 * showIndivudualLogicalUnit -
1264 * Used by show logical unit cli.
1265 * Displays info about an LU
1266 *
1267 * luOid - LU to show
1268 * luProps - properties of he LU to show
1269 * pluginProps - propertis of the plugin this LU belongs to
1270 *
1271 * ****************************************************************************
1272 */
1273 int
showIndividualLogicalUnit(MP_OID luOid,MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps,MP_PLUGIN_PROPERTIES pluginProps)1274 showIndividualLogicalUnit(MP_OID luOid,
1275 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps,
1276 MP_PLUGIN_PROPERTIES pluginProps)
1277 {
1278 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
1279 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps;
1280 MP_TARGET_PORT_PROPERTIES tportProps;
1281 MP_INITIATOR_PORT_PROPERTIES initProps;
1282 MP_OID_LIST *pPathOidListArray, *pTPGOidListArray,
1283 *pTportOidListArray;
1284 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1285 boolean_t showTportLabel = B_TRUE;
1286
1287 int pa, tpg, tport;
1288
1289 (void) printf("%s ", getTextString(TEXT_LB_LOGICAL_UNIT));
1290 displayArray(luProps.deviceFileName, sizeof (luProps.deviceFileName));
1291 (void) printf("\n");
1292 (void) printf("\t%s %s\n", getTextString(TEXT_LB_MPATH_SUPPORT),
1293 pluginProps.fileName);
1294
1295 (void) printf("\t%s ", getTextString(TEXT_LB_VENDOR));
1296 displayArray(luProps.vendor,
1297 sizeof (luProps.vendor));
1298 (void) printf("\n\t%s ", getTextString(TEXT_LB_PRODUCT));
1299 displayArray(luProps.product,
1300 sizeof (luProps.product));
1301 (void) printf("\n\t%s ", getTextString(TEXT_LB_REVISION));
1302 displayArray(luProps.revision,
1303 sizeof (luProps.revision));
1304 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME_TYPE));
1305 displayLogicalUnitNameTypeString(luProps.nameType);
1306 (void) printf("\n\t%s ", getTextString(TEXT_LB_INQUIRY_NAME));
1307 displayArray(luProps.name, sizeof (luProps.name));
1308 (void) printf("\n\t%s %s\n", getTextString(TEXT_LB_ASYMMETRIC),
1309 (MP_TRUE == luProps.asymmetric)?
1310 getTextString(TEXT_YES):getTextString(TEXT_NO));
1311
1312 (void) printf("\t%s ", getTextString(TEXT_LB_CURR_LOAD_BALANCE));
1313 /* don't ignore load balance type none. */
1314 if (luProps.currentLoadBalanceType == 0) {
1315 (void) printf("%s", getTextString(TEXT_LBTYPE_NONE));
1316 } else {
1317 displayLoadBalanceString(luProps.currentLoadBalanceType);
1318 }
1319 (void) printf("\n");
1320
1321 (void) printf("\t%s ", getTextString(TEXT_LB_LU_GROUP_ID));
1322 if (0xffffffff == luProps.logicalUnitGroupID) {
1323 (void) printf("%s\n", getTextString(TEXT_NA));
1324 } else {
1325 (void) printf("0x%x\n", luProps.logicalUnitGroupID);
1326 }
1327
1328 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_FB));
1329 if (MP_FALSE == pluginProps.autoFailbackSupport) {
1330 (void) printf("%s\n", getTextString(TEXT_NA));
1331 } else {
1332 (void) printf("%s\n", (MP_TRUE == luProps.autoFailbackEnabled)?
1333 getTextString(TEXT_ON):getTextString(TEXT_OFF));
1334 }
1335
1336 (void) printf("\t%s ", getTextString(TEXT_LB_AUTO_PROB));
1337 if (MP_FALSE == pluginProps.autoProbingSupport) {
1338 (void) printf("%s\n", getTextString(TEXT_NA));
1339 } else {
1340 (void) printf("%s\n", (MP_TRUE == luProps.autoProbingEnabled)?
1341 getTextString(TEXT_ON):getTextString(TEXT_OFF));
1342 }
1343
1344
1345 /* get path info */
1346 mpstatus = MP_GetAssociatedPathOidList(luOid, &pPathOidListArray);
1347 if (mpstatus != MP_STATUS_SUCCESS) {
1348 (void) fprintf(stderr, "%s: %s", cmdName,
1349 getTextString(ERR_NO_LU_PATH_INFO));
1350 displayArray(luProps.deviceFileName,
1351 sizeof (luProps.deviceFileName));
1352 (void) fprintf(stderr, "\n");
1353 return (mpstatus);
1354 }
1355
1356 (void) printf("\n\t%s \n", getTextString(TEXT_LB_PATH_INFO));
1357
1358 for (pa = 0; pa < pPathOidListArray->oidCount; pa++) {
1359 (void) memset(&pathProps, 0,
1360 sizeof (MP_PATH_LOGICAL_UNIT_PROPERTIES));
1361 mpstatus = MP_GetPathLogicalUnitProperties(
1362 pPathOidListArray->oids[pa], &pathProps);
1363 if (mpstatus != MP_STATUS_SUCCESS) {
1364 (void) fprintf(stderr, "%s: %s\n",
1365 cmdName, getTextString(ERR_NO_PROPERTIES));
1366 return (mpstatus);
1367 }
1368
1369 (void) printf("\t\t%s ",
1370 getTextString(TEXT_LB_INIT_PORT_NAME));
1371 if ((mpstatus =
1372 MP_GetInitiatorPortProperties(pathProps.initiatorPortOid,
1373 &initProps)) != MP_STATUS_SUCCESS) {
1374 (void) printf("%s\n", getTextString(TEXT_UNKNOWN));
1375 } else {
1376 displayArray(initProps.portID,
1377 sizeof (initProps.portID));
1378 (void) printf("\n");
1379 }
1380
1381 (void) printf("\t\t%s ",
1382 getTextString(TEXT_LB_TARGET_PORT_NAME));
1383 if ((mpstatus =
1384 MP_GetTargetPortProperties(pathProps.targetPortOid,
1385 &tportProps)) != MP_STATUS_SUCCESS) {
1386 (void) printf("%s\n", getTextString(TEXT_UNKNOWN));
1387 } else {
1388 displayArray(tportProps.portID,
1389 sizeof (tportProps.portID));
1390 (void) printf("\n");
1391 }
1392
1393 (void) printf("\t\t%s ", getTextString(TEXT_LB_OVERRIDE_PATH));
1394 if (MP_FALSE == pluginProps.canOverridePaths) {
1395 (void) printf("%s\n", getTextString(TEXT_NA));
1396 } else if (luProps.overridePath.objectSequenceNumber ==
1397 pPathOidListArray->oids[pa].objectSequenceNumber) {
1398 (void) printf("%s\n", getTextString(TEXT_YES));
1399 } else {
1400 (void) printf("%s\n", getTextString(TEXT_NO));
1401 }
1402
1403 (void) printf("\t\t%s %s\n", getTextString(TEXT_LB_PATH_STATE),
1404 getPathStateStr(pathProps.pathState));
1405
1406 (void) printf("\t\t%s %s\n\n", getTextString(TEXT_LB_DISABLED),
1407 pathProps.disabled?getTextString(TEXT_YES):
1408 getTextString(TEXT_NO));
1409
1410 }
1411
1412 /* get tpg info */
1413 mpstatus = MP_GetAssociatedTPGOidList(luOid, &pTPGOidListArray);
1414 if (mpstatus != MP_STATUS_SUCCESS) {
1415 (void) fprintf(stderr, "%s: %s", cmdName,
1416 getTextString(ERR_NO_ASSOC_TPGS));
1417 } else {
1418
1419 /* display tpg info only if is assymetric */
1420 if (MP_TRUE == luProps.asymmetric) {
1421 (void) printf("\t%s \n", getTextString(TEXT_LB_TPG_INFO));
1422 }
1423
1424 for (tpg = 0; tpg < pTPGOidListArray->oidCount; tpg++) {
1425 (void) memset(&tpgProps, 0,
1426 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
1427 mpstatus = MP_GetTargetPortGroupProperties(
1428 pTPGOidListArray->oids[tpg], &tpgProps);
1429 if (mpstatus != MP_STATUS_SUCCESS) {
1430 (void) fprintf(stderr, "%s: %s",
1431 cmdName, getTextString(ERR_NO_PROPERTIES));
1432 } else {
1433 /* display tpg info only if is assymetric */
1434 if (tpg > 0) {
1435 (void) printf("\n");
1436 }
1437 if (MP_TRUE == luProps.asymmetric) {
1438 (void) printf("\t\t%s %d\n",
1439 getTextString(TEXT_LB_ID),
1440 tpgProps.tpgID);
1441 (void) printf("\t\t%s %s\n",
1442 getTextString(
1443 TEXT_LB_EXPLICIT_FAILOVER),
1444 (MP_TRUE ==
1445 tpgProps.explicitFailover)?
1446 getTextString(TEXT_YES):
1447 getTextString(TEXT_NO));
1448 (void) printf("\t\t%s %s\n",
1449 getTextString(
1450 TEXT_LB_ACCESS_STATE),
1451 getAccessStateStr(
1452 tpgProps.accessState));
1453 /* display label for each tpg. */
1454 (void) printf("\t\t%s\n",
1455 getTextString(TEXT_TPORT_LIST));
1456 } else {
1457 /* display label once for symmetric. */
1458 if (B_TRUE == showTportLabel) {
1459 /* begin back-up indentation */
1460 (void) printf("\t%s\n",
1461 getTextString(TEXT_TPORT_LIST));
1462 showTportLabel = B_FALSE;
1463 /* end back-up indentation */
1464 }
1465 }
1466
1467 /* get target port info */
1468 mpstatus = MP_GetTargetPortOidList(
1469 pTPGOidListArray->oids[tpg],
1470 &pTportOidListArray);
1471 if (mpstatus != MP_STATUS_SUCCESS) {
1472 (void) fprintf(stderr, "%s: %s",
1473 cmdName,
1474 getTextString(ERR_NO_ASSOC_TPORTS));
1475 } else {
1476
1477 /* begin back-up indentation */
1478 for (tport = 0; tport < pTportOidListArray->oidCount; tport++) {
1479 (void) memset(&tportProps, 0,
1480 sizeof (MP_TARGET_PORT_PROPERTIES));
1481 if ((mpstatus =
1482 MP_GetTargetPortProperties(pTportOidListArray->oids[tport],
1483 &tportProps)) != MP_STATUS_SUCCESS) {
1484 (void) fprintf(stderr, "%s: %s",
1485 cmdName, getTextString(ERR_NO_PROPERTIES));
1486 } else {
1487 if (MP_TRUE == luProps.asymmetric) {
1488 (void) printf("\t\t\t%s ",
1489 getTextString(TEXT_LB_NAME));
1490 displayArray(tportProps.portID,
1491 sizeof (tportProps.portID));
1492 (void) printf("\n\t\t\t%s %d\n",
1493 getTextString(TEXT_LB_RELATIVE_ID),
1494 tportProps.relativePortID);
1495 } else {
1496 (void) printf("\t\t%s ",
1497 getTextString(TEXT_LB_NAME));
1498 displayArray(tportProps.portID,
1499 sizeof (tportProps.portID));
1500 (void) printf("\n\t\t%s %d\n",
1501 getTextString(TEXT_LB_RELATIVE_ID),
1502 tportProps.relativePortID);
1503 }
1504 /* insert blank line if not the last target port. */
1505 if (!(tport == (pTportOidListArray->oidCount - 1))) {
1506 (void) printf("\n");
1507 }
1508 }
1509 } /* for each target port */
1510 /* end back-up indentation */
1511
1512 } /* else got target port props */
1513 } /* else got TPG props */
1514 } /* for each TPG */
1515 } /* else got tpg list */
1516
1517
1518 return (mpstatus);
1519 }
1520
1521
1522 /*
1523 * ****************************************************************************
1524 *
1525 * modifyLogicalUnit -
1526 * mpathadm modify {logical-unit | LU} [options] <logical-unit name>, ...
1527 *
1528 * operandLen - number of operands user passed into the cli
1529 * operand - pointer to operand list from user
1530 * options - pointer to option list from user
1531 *
1532 * ****************************************************************************
1533 */
1534 int
modifyLogicalUnit(int operandLen,char * operand[],cmdOptions_t * options)1535 modifyLogicalUnit(int operandLen, char *operand[], cmdOptions_t *options)
1536 {
1537 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1538 MP_OID luOid;
1539 cmdOptions_t *optionList = options;
1540 char *cmdStr = getTextString(TEXT_UNKNOWN);
1541 int op;
1542
1543 for (op = 0; op < operandLen; op++) {
1544 if (B_TRUE != getLogicalUnitOid(operand[op], &luOid)) {
1545 /* LINTED E_SEC_PRINTF_VAR_FMT */
1546 (void) fprintf(stderr,
1547 getTextString(ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
1548 operand[op]);
1549 (void) printf("\n");
1550 return (ERROR_CLI_FAILED);
1551 }
1552
1553 /* we found the lu oid, now change the options requested */
1554 switch (optionList->optval) {
1555 case 'a':
1556 /* modify autofailback */
1557 cmdStr = getTextString(TEXT_AUTO_FAILBACK);
1558 if (0 == strcasecmp(optionList->optarg,
1559 getTextString(TEXT_ON))) {
1560 mpstatus =
1561 MP_EnableAutoFailback(luOid);
1562 } else if (0 == strcasecmp(optionList->optarg,
1563 getTextString(TEXT_OFF))) {
1564 mpstatus =
1565 MP_DisableAutoFailback(luOid);
1566 } else {
1567 /* begin back-up indentation */
1568 /* LINTED E_SEC_PRINTF_VAR_FMT */
1569 (void) fprintf(stderr, getTextString(
1570 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
1571 cmdStr, getTextString(
1572 TEXT_ILLEGAL_ARGUMENT));
1573 (void) printf("\n");
1574 return (ERROR_CLI_FAILED);
1575 /* start back-up indentation */
1576 }
1577 break;
1578 case 'p':
1579 /* modify autoprobing */
1580 cmdStr = getTextString(TEXT_AUTO_PROBING);
1581 if (0 == strcasecmp(optionList->optarg,
1582 getTextString(TEXT_ON))) {
1583 mpstatus =
1584 MP_EnableAutoProbing(luOid);
1585 } else if (0 == strcasecmp(optionList->optarg,
1586 getTextString(TEXT_OFF))) {
1587 mpstatus =
1588 MP_DisableAutoProbing(luOid);
1589 } else {
1590 /* begin back-up indentation */
1591 /* LINTED E_SEC_PRINTF_VAR_FMT */
1592 (void) fprintf(stderr, getTextString(
1593 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
1594 cmdStr, getTextString(
1595 TEXT_ILLEGAL_ARGUMENT));
1596 (void) printf("\n");
1597 return (ERROR_CLI_FAILED);
1598 /* end back-up indentation */
1599 }
1600 break;
1601 case 'b':
1602 /* modify loadbalance type */
1603 cmdStr = getTextString(TEXT_LOAD_BALANCE);
1604 mpstatus =
1605 MP_SetLogicalUnitLoadBalanceType(luOid,
1606 getLbValueFromString(optionList->optarg));
1607 break;
1608
1609 } /* switch */
1610 if (MP_STATUS_SUCCESS != mpstatus) {
1611 /* LINTED E_SEC_PRINTF_VAR_FMT */
1612 (void) fprintf(stderr,
1613 getTextString(
1614 ERR_FAILED_TO_CHANGE_OPTION_WITH_REASON),
1615 cmdStr, getMpStatusStr(mpstatus));
1616 (void) printf("\n");
1617 return (ERROR_CLI_FAILED);
1618 }
1619 } /* for each operand */
1620 return (mpstatus);
1621 }
1622
1623
1624 /*
1625 * ****************************************************************************
1626 *
1627 * failoverLogicalUnit -
1628 * mpathadm failover {logical-unit | LU} <logical-unit name>, ...
1629 *
1630 * operand - pointer to operand list from user
1631 *
1632 * ****************************************************************************
1633 */
1634 int
failoverLogicalUnit(char * operand[])1635 failoverLogicalUnit(char *operand[])
1636 {
1637 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1638 MP_OID luOid;
1639 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
1640 MP_TARGET_PORT_GROUP_PROPERTIES tpgProps;
1641 MP_OID_LIST *pTpgOidListArray;
1642 boolean_t bFoundIt = B_FALSE;
1643 MP_TPG_STATE_PAIR tpgStatePair;
1644
1645 int tpg;
1646
1647 if (B_TRUE != getLogicalUnitOid(operand[0], &luOid)) {
1648 /* LINTED E_SEC_PRINTF_VAR_FMT */
1649 (void) fprintf(stderr, getTextString(
1650 ERR_LU_NOT_FOUND_WITH_MISSING_LU_STR),
1651 operand[0]);
1652 (void) printf("\n");
1653 return (ERROR_CLI_FAILED);
1654 }
1655
1656 /* get LUN properties and check to be sure it's asymmetric */
1657 (void) memset(&luProps, 0,
1658 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
1659 mpstatus =
1660 MP_GetMPLogicalUnitProperties(luOid, &luProps);
1661 if (mpstatus != MP_STATUS_SUCCESS) {
1662 (void) fprintf(stderr, "%s: %s\n",
1663 cmdName, getTextString(ERR_NO_PROPERTIES));
1664 return (mpstatus);
1665 }
1666
1667 if (MP_TRUE != luProps.asymmetric) {
1668 (void) fprintf(stderr, "%s: %s\n",
1669 cmdName, getTextString(ERR_LU_NOT_ASYMMETRIC));
1670 return (ERROR_CLI_FAILED);
1671 }
1672
1673 /* get TPGs for this LUN */
1674 mpstatus =
1675 MP_GetAssociatedTPGOidList(luOid, &pTpgOidListArray);
1676 if (mpstatus != MP_STATUS_SUCCESS) {
1677 (void) fprintf(stderr, "%s: %s\n",
1678 cmdName, getTextString(ERR_NO_ASSOC_TPGS));
1679 return (mpstatus);
1680 }
1681
1682 /* pick a TPG whose state is active or standby, and change it */
1683 /* to opposite via MP_SetTPGAccessState */
1684 bFoundIt = B_FALSE;
1685 for (tpg = 0; tpg < pTpgOidListArray->oidCount; tpg++) {
1686 (void) memset(&tpgProps, 0,
1687 sizeof (MP_TARGET_PORT_GROUP_PROPERTIES));
1688 mpstatus =
1689 MP_GetTargetPortGroupProperties(
1690 pTpgOidListArray->oids[tpg], &tpgProps);
1691 if (mpstatus != MP_STATUS_SUCCESS) {
1692 (void) fprintf(stderr, "%s: %s\n",
1693 cmdName, getTextString(ERR_NO_PROPERTIES));
1694 return (ERROR_CLI_FAILED);
1695 }
1696 if (MP_FALSE == tpgProps.explicitFailover) {
1697 (void) fprintf(stderr, "%s: %s\n",
1698 cmdName, getTextString(ERR_NO_FAILOVER_ALLOWED));
1699 return (ERROR_CLI_FAILED);
1700 }
1701
1702 /* find one that is standby */
1703 if ((MP_ACCESS_STATE_STANDBY ==
1704 tpgProps.accessState) && (B_FALSE == bFoundIt)) {
1705
1706 bFoundIt = B_TRUE;
1707
1708 tpgStatePair.tpgOid =
1709 pTpgOidListArray->oids[tpg];
1710 tpgStatePair.desiredState =
1711 MP_ACCESS_STATE_ACTIVE;
1712 mpstatus =
1713 MP_SetTPGAccess(luOid, 1, &tpgStatePair);
1714 if (MP_STATUS_SUCCESS != mpstatus) {
1715 /* begin back-up indentation */
1716 /* LINTED E_SEC_PRINTF_VAR_FMT */
1717 (void) fprintf(stderr, getTextString(
1718 ERR_FAILED_TO_FAILOVER_WITH_REASON),
1719 getMpStatusStr(mpstatus));
1720 (void) printf("\n");
1721 return (mpstatus);
1722 /* end back-up indentation */
1723 }
1724 }
1725
1726
1727 } /* for each tpg */
1728
1729 if (B_FALSE == bFoundIt) {
1730 (void) fprintf(stderr, "%s: %s\n",
1731 cmdName, getTextString(ERR_LU_ACCESS_STATE_UNCHANGED));
1732 return (ERROR_CLI_FAILED);
1733 }
1734
1735 return (mpstatus);
1736 }
1737
1738
1739 /*
1740 * ****************************************************************************
1741 *
1742 * getLogicalUnitOid -
1743 * Search through all plugins and get the OID for specified logical unit
1744 *
1745 * luFileName - file name of LU (specified by the user) to find
1746 * pLuOid - OID to return
1747 *
1748 * ****************************************************************************
1749 */
1750 boolean_t
getLogicalUnitOid(MP_CHAR * luFileName,MP_OID * pluOid)1751 getLogicalUnitOid(MP_CHAR *luFileName, MP_OID *pluOid)
1752 {
1753 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1754 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
1755 MP_PLUGIN_PROPERTIES pluginProps;
1756 MP_OID_LIST *pPluginOidList, *pLogicalUnitOidList;
1757 boolean_t foundIt = B_FALSE;
1758
1759 int i, lu;
1760
1761 int fd1, fd2;
1762 ddi_devid_t devid1, devid2;
1763
1764 if (NULL == pluOid) {
1765 /* print some kind of error msg here - should never happen */
1766 /* LINTED E_SEC_PRINTF_VAR_FMT */
1767 (void) fprintf(stderr, getTextString(ERR_MEMORY_ALLOCATION));
1768 (void) printf("\n");
1769 return (B_FALSE);
1770 }
1771
1772 pluOid->objectSequenceNumber = 0;
1773 pluOid->objectType = 0;
1774 pluOid->ownerId = 0;
1775
1776 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
1777 != MP_STATUS_SUCCESS) {
1778 (void) fprintf(stderr, "%s: %s\n", cmdName,
1779 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
1780 return (B_FALSE);
1781 }
1782 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
1783 (void) fprintf(stderr, "%s: %s\n", cmdName,
1784 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
1785 return (ERROR_CLI_FAILED);
1786 }
1787 for (i = 0; i < pPluginOidList->oidCount; i++) {
1788
1789 /* get properties so we can list the name */
1790 (void) memset(&pluginProps, 0, sizeof (MP_PLUGIN_PROPERTIES));
1791 if ((mpstatus =
1792 MP_GetPluginProperties(pPluginOidList->oids[i],
1793 &pluginProps)) != MP_STATUS_SUCCESS) {
1794 (void) fprintf(stderr, "%s: %s\n",
1795 cmdName, getTextString(ERR_NO_PROPERTIES));
1796 return (B_FALSE);
1797 }
1798
1799 /* attempt to find this logical unit */
1800 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
1801 &pLogicalUnitOidList);
1802 if (mpstatus != MP_STATUS_SUCCESS) {
1803 (void) fprintf(stderr, "%s: %s\n",
1804 cmdName, getTextString(ERR_NO_LU_LIST));
1805 return (B_FALSE);
1806 }
1807
1808 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) &&
1809 (B_FALSE == foundIt); lu++) {
1810
1811 /* get lu properties so we can check the name */
1812 (void) memset(&luProps, 0,
1813 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
1814 mpstatus =
1815 MP_GetMPLogicalUnitProperties(
1816 pLogicalUnitOidList->oids[lu], &luProps);
1817 if (mpstatus != MP_STATUS_SUCCESS) {
1818 (void) fprintf(stderr, "%s: %s\n",
1819 cmdName, getTextString(ERR_NO_PROPERTIES));
1820 return (B_FALSE);
1821 }
1822
1823 if (compareLUName(luFileName, luProps.deviceFileName)
1824 == B_TRUE) {
1825 foundIt = B_TRUE;
1826 } else {
1827 /* user input didn't match, try via devid */
1828 /*
1829 * I don't see a reason to print the error for
1830 * any of these since they'll get the error at
1831 * the end anyway
1832 */
1833
1834 fd1 = fd2 = -1;
1835 devid1 = devid2 = NULL;
1836 if (((fd1 = open(luFileName,
1837 O_RDONLY|O_NDELAY)) >= 0) &&
1838 ((fd2 = open(luProps.deviceFileName,
1839 O_RDONLY|O_NDELAY)) >= 0) &&
1840 (devid_get(fd1, &devid1) == 0) &&
1841 (devid_get(fd2, &devid2) == 0) &&
1842 ((NULL != devid1) && (NULL != devid2))) {
1843 if (0 ==
1844 (devid_compare(devid1, devid2))) {
1845 foundIt = B_TRUE;
1846 }
1847 }
1848
1849 if (NULL != devid1) {
1850 devid_free(devid1);
1851 }
1852 if (NULL != devid2) {
1853 devid_free(devid2);
1854 }
1855
1856 if (fd1 >= 0) {
1857 (void) close(fd1);
1858 }
1859 if (fd2 >= 0) {
1860 (void) close(fd2);
1861 }
1862 }
1863 if (B_TRUE == foundIt) {
1864 pluOid->objectSequenceNumber =
1865 pLogicalUnitOidList->
1866 oids[lu].objectSequenceNumber;
1867 pluOid->objectType =
1868 pLogicalUnitOidList->
1869 oids[lu].objectType;
1870 pluOid->ownerId =
1871 pLogicalUnitOidList->oids[lu].ownerId;
1872 }
1873 }
1874 }
1875
1876 return (foundIt);
1877 }
1878
1879
1880 /*
1881 * ****************************************************************************
1882 *
1883 * listInitiatorPort -
1884 * mpathadm list initiator-port [<initiator-port name>, ...]
1885 *
1886 * operandLen - number of operands user passed into the cli
1887 * operand - pointer to operand list from user
1888 *
1889 * ****************************************************************************
1890 */
1891 int
listInitiatorPort(int operandLen,char * operand[])1892 listInitiatorPort(int operandLen, char *operand[])
1893 {
1894 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
1895 MP_INITIATOR_PORT_PROPERTIES initProps;
1896 MP_OID_LIST *pPluginOidList, *pInitOidList;
1897 boolean_t bListIt = B_FALSE;
1898 boolean_t *foundOp;
1899
1900 int ol, i, iport;
1901
1902 foundOp = malloc((sizeof (boolean_t)) * operandLen);
1903 if (NULL == foundOp) {
1904 (void) fprintf(stdout, "%s\n",
1905 getTextString(ERR_MEMORY_ALLOCATION));
1906 return (ERROR_CLI_FAILED);
1907 }
1908
1909 for (ol = 0; ol < operandLen; ol++) {
1910 foundOp[ol] = B_FALSE;
1911 }
1912
1913 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
1914 != MP_STATUS_SUCCESS) {
1915 (void) fprintf(stderr, "%s: %s\n", cmdName,
1916 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
1917 return (mpstatus);
1918 }
1919 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
1920 (void) fprintf(stderr, "%s: %s\n", cmdName,
1921 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
1922 return (ERROR_CLI_FAILED);
1923 }
1924
1925 for (i = 0; i < pPluginOidList->oidCount; i++) {
1926 mpstatus =
1927 MP_GetInitiatorPortOidList(pPluginOidList->oids[i],
1928 &pInitOidList);
1929 if (mpstatus != MP_STATUS_SUCCESS) {
1930 /* LINTED E_SEC_PRINTF_VAR_FMT */
1931 (void) fprintf(stderr,
1932 getTextString(ERR_NO_INIT_PORT_LIST_WITH_REASON),
1933 getMpStatusStr(mpstatus));
1934 (void) printf("\n");
1935 } else if ((NULL == pInitOidList) ||
1936 (pInitOidList->oidCount < 1)) {
1937 (void) fprintf(stderr, "%s: %s\n", cmdName,
1938 getTextString(ERR_NO_INIT_PORTS));
1939 } else {
1940 for (iport = 0;
1941 iport < pInitOidList->oidCount; iport ++) {
1942 bListIt = B_FALSE;
1943 if ((mpstatus =
1944 MP_GetInitiatorPortProperties(
1945 pInitOidList->oids[iport],
1946 &initProps)) != MP_STATUS_SUCCESS) {
1947 (void) fprintf(stderr,
1948 "%s: %s\n", cmdName,
1949 getTextString(ERR_NO_PROPERTIES));
1950 } else {
1951 /* if no operands listed, */
1952 /* list all we find */
1953 if (0 == operandLen) {
1954 bListIt = B_TRUE;
1955 } else {
1956
1957 /* check each operand */
1958 /* Is it */
1959 /* the one we want to list? */
1960 for (ol = 0;
1961 ol < operandLen; ol++) {
1962 if (0 ==
1963 strcmp(operand[ol],
1964 initProps.
1965 portID)) {
1966 bListIt =
1967 B_TRUE;
1968 foundOp[ol] =
1969 B_TRUE;
1970 }
1971 }
1972 }
1973 }
1974
1975 if (B_TRUE == bListIt) {
1976
1977 if (listIndividualInitiatorPort(
1978 initProps) != 0) {
1979 return (ERROR_CLI_FAILED);
1980 }
1981
1982 } /* list It */
1983
1984 } /* for each initiator port */
1985 } /* else found an init port */
1986
1987 } /* for each plugin */
1988
1989 for (ol = 0; ol < operandLen; ol++) {
1990 if (B_FALSE == foundOp[ol]) {
1991 /* LINTED E_SEC_PRINTF_VAR_FMT */
1992 (void) fprintf(stderr, getTextString(
1993 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR),
1994 operand[ol]);
1995 (void) printf("\n");
1996 }
1997 }
1998
1999 return (mpstatus);
2000 }
2001
2002
2003 /*
2004 * ****************************************************************************
2005 *
2006 * listIndividualInitiatorPort -
2007 * used by listInitiatorPort to list info for one init port
2008 *
2009 * initProps - properties of initiator port to list
2010 *
2011 * ****************************************************************************
2012 */
2013 int
listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)2014 listIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)
2015 {
2016 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2017
2018 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT));
2019 displayArray(initProps.portID,
2020 sizeof (initProps.portID));
2021 (void) printf("\n");
2022
2023 return (mpstatus);
2024
2025 }
2026
2027
2028 /*
2029 * ****************************************************************************
2030 *
2031 * showInitiatorPort -
2032 * mpathadm show initiator-port <initiator-port name>, ...
2033 *
2034 * operandLen - number of operands user passed into the cli
2035 * operand - pointer to operand list from user
2036 *
2037 * ****************************************************************************
2038 */
2039 int
showInitiatorPort(int operandLen,char * operand[])2040 showInitiatorPort(int operandLen, char *operand[])
2041 {
2042 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2043 MP_INITIATOR_PORT_PROPERTIES initProps;
2044 MP_OID_LIST *pPluginOidList, *pInitOidList;
2045 boolean_t bListIt = B_FALSE, bFoundIt = B_FALSE;
2046 int op, i, iport;
2047
2048 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
2049 != MP_STATUS_SUCCESS) {
2050 (void) fprintf(stderr, "%s: %s\n", cmdName,
2051 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
2052 return (mpstatus);
2053 }
2054 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
2055 (void) fprintf(stderr, "%s: %s\n", cmdName,
2056 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
2057 return (ERROR_CLI_FAILED);
2058 }
2059
2060 for (op = 0; op < operandLen; op++) {
2061 bFoundIt = B_FALSE;
2062
2063 for (i = 0; i < pPluginOidList->oidCount; i++) {
2064
2065 mpstatus =
2066 MP_GetInitiatorPortOidList(pPluginOidList->oids[i],
2067 &pInitOidList);
2068 if (mpstatus != MP_STATUS_SUCCESS) {
2069 /* LINTED E_SEC_PRINTF_VAR_FMT */
2070 (void) fprintf(stderr,
2071 getTextString(
2072 ERR_NO_INIT_PORT_LIST_WITH_REASON),
2073 getMpStatusStr(mpstatus));
2074 (void) printf("\n");
2075 } else if ((NULL == pInitOidList) ||
2076 (pInitOidList->oidCount < 1)) {
2077 (void) fprintf(stderr, "%s: %s\n", cmdName,
2078 getTextString(ERR_NO_INIT_PORTS));
2079 } else {
2080
2081 for (iport = 0;
2082 iport < pInitOidList->oidCount;
2083 iport ++) {
2084 bListIt = B_FALSE;
2085
2086 if ((mpstatus =
2087 MP_GetInitiatorPortProperties(
2088 pInitOidList->oids[iport],
2089 &initProps))
2090 != MP_STATUS_SUCCESS) {
2091 /* begin back-up indentation */
2092 (void) fprintf(stderr,
2093 "%s: %s\n", cmdName,
2094 getTextString(ERR_NO_PROPERTIES));
2095 /* end back-up indentation */
2096 } else {
2097 if (0 == strcmp(operand[op],
2098 initProps.portID)) {
2099 bListIt = B_TRUE;
2100 bFoundIt = B_TRUE;
2101 }
2102 }
2103
2104 if (B_TRUE == bListIt) {
2105 mpstatus =
2106 showIndividualInitiatorPort(
2107 initProps);
2108 if (0 != mpstatus) {
2109 return (mpstatus);
2110 }
2111
2112 } /* list It */
2113
2114 } /* for each initiator port */
2115 } /* else found an init port */
2116
2117 } /* for each plugin */
2118
2119 if (B_FALSE == bFoundIt) {
2120 /* need temp string here since we need to fill in a */
2121 /* name in the error string */
2122 /* LINTED E_SEC_PRINTF_VAR_FMT */
2123 (void) fprintf(stderr, getTextString(
2124 ERR_INIT_PORT_NOT_FOUND_WITH_MISSING_LU_STR),
2125 operand[op]);
2126 (void) printf("\n");
2127 }
2128
2129 } /* for each operand */
2130
2131 return (mpstatus);
2132 }
2133
2134
2135 /*
2136 * ****************************************************************************
2137 *
2138 * showIndividualInitiatorPort -
2139 * used by showInitiatorPort to show info for one init port
2140 *
2141 * initProps - properties of initiator port to show
2142 *
2143 * ****************************************************************************
2144 */
2145 int
showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)2146 showIndividualInitiatorPort(MP_INITIATOR_PORT_PROPERTIES initProps)
2147 {
2148 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2149
2150 (void) printf("%s ", getTextString(TEXT_LB_INITATOR_PORT));
2151 displayArray(initProps.portID,
2152 sizeof (initProps.portID));
2153
2154 (void) printf("\n\t%s ", getTextString(TEXT_LB_TRANSPORT_TYPE));
2155 displayTransportTypeString(initProps.portType);
2156 (void) printf("\n");
2157
2158 (void) printf("\t%s ", getTextString(TEXT_LB_OS_DEVICE_FILE));
2159 displayArray(initProps.osDeviceFile,
2160 sizeof (initProps.osDeviceFile));
2161 (void) printf("\n");
2162
2163 return (mpstatus);
2164 }
2165
2166
2167 /*
2168 * ****************************************************************************
2169 *
2170 * enablePath -
2171 * mpathadm enable path -i <initiator-port>
2172 * -t <target-port name> -l <logical-unit name>
2173 *
2174 * options - pointer to option list from user
2175 *
2176 * ****************************************************************************
2177 */
2178 int
enablePath(cmdOptions_t * options)2179 enablePath(cmdOptions_t *options)
2180 {
2181 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2182 MP_OID pathOid;
2183
2184 cmdOptions_t *optionList = options;
2185 boolean_t bHaveInit = B_FALSE, bHaveTarg = B_FALSE, bHaveLu = B_FALSE;
2186
2187 for (; optionList->optval; optionList++) {
2188 switch (optionList->optval) {
2189 case 'i':
2190 /* have init port name */
2191 bHaveInit = B_TRUE;
2192 break;
2193 case 't':
2194 /* have target port id */
2195 bHaveTarg = B_TRUE;
2196 break;
2197 case 'l':
2198 /* have LU name */
2199 bHaveLu = B_TRUE;
2200 break;
2201 }
2202 }
2203 if (B_FALSE == bHaveInit) {
2204 /* LINTED E_SEC_PRINTF_VAR_FMT */
2205 (void) fprintf(stderr,
2206 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
2207 getTextString(MISSING_INIT_PORT_NAME));
2208 (void) printf("\n");
2209 return (ERROR_CLI_FAILED);
2210 } else if (B_FALSE == bHaveTarg) {
2211 /* LINTED E_SEC_PRINTF_VAR_FMT */
2212 (void) fprintf(stderr,
2213 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
2214 getTextString(MISSING_TARGET_PORT_NAME));
2215 (void) printf("\n");
2216 return (ERROR_CLI_FAILED);
2217 } else if (B_FALSE == bHaveLu) {
2218 /* LINTED E_SEC_PRINTF_VAR_FMT */
2219 (void) fprintf(stderr,
2220 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
2221 getTextString(MISSING_LU_NAME));
2222 (void) printf("\n");
2223 return (ERROR_CLI_FAILED);
2224 }
2225
2226 if (B_FALSE == getPathOid(options, &pathOid)) {
2227 /* LINTED E_SEC_PRINTF_VAR_FMT */
2228 (void) fprintf(stderr,
2229 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
2230 getTextString(FAILED_TO_FIND_PATH));
2231 (void) printf("\n");
2232 return (ERROR_CLI_FAILED);
2233 }
2234
2235 /* found the path, attempt to enable it */
2236 mpstatus = MP_EnablePath(pathOid);
2237 if (mpstatus != MP_STATUS_SUCCESS) {
2238 /* LINTED E_SEC_PRINTF_VAR_FMT */
2239 (void) fprintf(stderr,
2240 getTextString(ERR_FAILED_TO_ENABLE_PATH_WITH_REASON),
2241 getMpStatusStr(mpstatus));
2242 (void) printf("\n");
2243 return (mpstatus);
2244 }
2245
2246 return (mpstatus);
2247 }
2248
2249
2250 /*
2251 * ****************************************************************************
2252 *
2253 * disablePath -
2254 * mpathadm disable path -i <initiator-port>
2255 * -t <target-port name> -l <logical-unit name>
2256 *
2257 * options - pointer to option list from user
2258 *
2259 * ****************************************************************************
2260 */
2261 int
disablePath(cmdOptions_t * options)2262 disablePath(cmdOptions_t *options)
2263 {
2264 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2265 MP_OID pathOid;
2266
2267 cmdOptions_t *optionList = options;
2268 boolean_t bHaveInit = B_FALSE, bHaveTarg = B_FALSE,
2269 bHaveLu = B_FALSE;
2270
2271 for (; optionList->optval; optionList++) {
2272 switch (optionList->optval) {
2273 case 'i':
2274 /* have init port name */
2275 bHaveInit = B_TRUE;
2276 break;
2277 case 't':
2278 /* have target port id */
2279 bHaveTarg = B_TRUE;
2280 break;
2281 case 'l':
2282 /* have LU name */
2283 bHaveLu = B_TRUE;
2284 break;
2285 }
2286 }
2287 if (B_FALSE == bHaveInit) {
2288 /* LINTED E_SEC_PRINTF_VAR_FMT */
2289 (void) fprintf(stderr,
2290 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
2291 getTextString(MISSING_INIT_PORT_NAME));
2292 (void) printf("\n");
2293 return (ERROR_CLI_FAILED);
2294 } else if (B_FALSE == bHaveTarg) {
2295 /* LINTED E_SEC_PRINTF_VAR_FMT */
2296 (void) fprintf(stderr,
2297 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
2298 getTextString(MISSING_TARGET_PORT_NAME));
2299 (void) printf("\n");
2300 return (ERROR_CLI_FAILED);
2301 } else if (B_FALSE == bHaveLu) {
2302 /* LINTED E_SEC_PRINTF_VAR_FMT */
2303 (void) fprintf(stderr,
2304 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
2305 getTextString(MISSING_LU_NAME));
2306 (void) printf("\n");
2307 return (ERROR_CLI_FAILED);
2308 }
2309
2310 if (B_FALSE == getPathOid(options, &pathOid)) {
2311 /* LINTED E_SEC_PRINTF_VAR_FMT */
2312 (void) fprintf(stderr,
2313 getTextString(ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
2314 getTextString(FAILED_TO_FIND_PATH));
2315 (void) printf("\n");
2316 return (ERROR_CLI_FAILED);
2317 }
2318
2319 /* found the path, attempt to enable it */
2320 mpstatus = MP_DisablePath(pathOid);
2321 if (MP_STATUS_SUCCESS != mpstatus) {
2322 /* LINTED E_SEC_PRINTF_VAR_FMT */
2323 (void) fprintf(stderr, getTextString(
2324 ERR_FAILED_TO_DISABLE_PATH_WITH_REASON),
2325 getMpStatusStr(mpstatus));
2326 (void) printf("\n");
2327 return (mpstatus);
2328 }
2329
2330
2331 return (mpstatus);
2332 }
2333
2334
2335 /*
2336 * ****************************************************************************
2337 *
2338 * overridePath -
2339 * mpathadm override path {-i <initiator-port>
2340 * -t <target-port name> | -c} <logical-unit name>
2341 *
2342 * options - pointer to option list from user
2343 *
2344 * ****************************************************************************
2345 */
2346 int
overridePath(cmdOptions_t * options)2347 overridePath(cmdOptions_t *options)
2348 {
2349 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2350 MP_OID pathOid, luOid;
2351 boolean_t bCancelOverride = B_FALSE;
2352 MP_CHAR pLuDeviceFileName[256];
2353 cmdOptions_t *optionList = options;
2354
2355 /* First check to see if we have the cancel option, */
2356 /* May as well save off the lun while we're at it */
2357 for (; optionList->optval; optionList++) {
2358 switch (optionList->optval) {
2359 case 'c':
2360 /* we have a cancel */
2361 bCancelOverride = B_TRUE;
2362 break;
2363 case 'l':
2364 /* we have a lun- save it while we're here */
2365 (void) memcpy(pLuDeviceFileName,
2366 optionList->optarg, 256);
2367 break;
2368 }
2369 }
2370
2371 if (B_TRUE == bCancelOverride) {
2372 /* if we have the cancel option, */
2373 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) {
2374 /* LINTED E_SEC_PRINTF_VAR_FMT */
2375 (void) fprintf(stderr,
2376 getTextString(
2377 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON),
2378 getTextString(LU_NOT_FOUND));
2379 (void) printf("\n");
2380 return (ERROR_CLI_FAILED);
2381 }
2382
2383 /* cancel the override path for the specified LU */
2384 mpstatus = MP_CancelOverridePath(luOid);
2385 if (MP_STATUS_SUCCESS != mpstatus) {
2386 /* LINTED E_SEC_PRINTF_VAR_FMT */
2387 (void) fprintf(stderr,
2388 getTextString(
2389 ERR_FAILED_TO_CANCEL_OVERRIDE_PATH_WITH_REASON),
2390 getMpStatusStr(mpstatus));
2391 (void) printf("\n");
2392 return (mpstatus);
2393 }
2394 } else {
2395 /* must be wanting to override the path */
2396 if (getLogicalUnitOid(pLuDeviceFileName, &luOid) == B_FALSE) {
2397 /* LINTED E_SEC_PRINTF_VAR_FMT */
2398 (void) fprintf(stderr,
2399 getTextString(
2400 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
2401 getTextString(LU_NOT_FOUND));
2402 (void) printf("\n");
2403 return (ERROR_CLI_FAILED);
2404 }
2405
2406 if (B_FALSE == getPathOid(options, &pathOid)) {
2407 /* LINTED E_SEC_PRINTF_VAR_FMT */
2408 (void) fprintf(stderr,
2409 getTextString(
2410 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
2411 getTextString(FAILED_TO_FIND_PATH));
2412
2413 (void) printf("\n");
2414 return (ERROR_CLI_FAILED);
2415 }
2416
2417 /* attempt to set the override path */
2418 mpstatus = MP_SetOverridePath(luOid, pathOid);
2419 if (mpstatus != MP_STATUS_SUCCESS) {
2420 /* LINTED E_SEC_PRINTF_VAR_FMT */
2421 (void) fprintf(stderr,
2422 getTextString(
2423 ERR_FAILED_TO_OVERRIDE_PATH_WITH_REASON),
2424 getMpStatusStr(mpstatus));
2425 (void) printf("\n");
2426 return (mpstatus);
2427 }
2428 }
2429
2430 return (mpstatus);
2431 }
2432
2433
2434 /*
2435 * ****************************************************************************
2436 *
2437 * getPathOid -
2438 * Search through all plugins and get the OID for specified path
2439 *
2440 * operand - pointer to operand list from user
2441 * options - pointer to option list from user
2442 *
2443 * ****************************************************************************
2444 */
2445 boolean_t
getPathOid(cmdOptions_t * options,MP_OID * pPathOid)2446 getPathOid(cmdOptions_t *options, MP_OID *pPathOid)
2447 {
2448 MP_STATUS mpstatus = MP_STATUS_SUCCESS;
2449 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES luProps;
2450 MP_PATH_LOGICAL_UNIT_PROPERTIES pathProps;
2451 MP_INITIATOR_PORT_PROPERTIES initProps;
2452 MP_TARGET_PORT_PROPERTIES targProps;
2453
2454 MP_OID_LIST *pPluginOidList, *pLogicalUnitOidList,
2455 *pathOidListArray;
2456
2457 boolean_t bFoundIt = B_FALSE;
2458 MP_CHAR initPortID[256];
2459 MP_CHAR targetPortID[256];
2460 MP_CHAR luDeviceFileName[256];
2461 boolean_t bHaveTarg = B_FALSE, bHaveLu = B_FALSE,
2462 bHaveInit = B_FALSE;
2463 cmdOptions_t *optionList = options;
2464
2465 int i, lu, pa;
2466 if (NULL == pPathOid) {
2467 return (B_FALSE);
2468 }
2469
2470 for (; optionList->optval; optionList++) {
2471 switch (optionList->optval) {
2472 case 'i':
2473 /* save init port name */
2474 (void) memcpy(initPortID,
2475 optionList->optarg, 256);
2476 bHaveInit = B_TRUE;
2477 break;
2478 case 't':
2479 /* save target port id */
2480 (void) memcpy(targetPortID,
2481 optionList->optarg, 256);
2482 bHaveTarg = B_TRUE;
2483 break;
2484 case 'l':
2485 /* save LU name */
2486 (void) memcpy(luDeviceFileName,
2487 optionList->optarg, 256);
2488 bHaveLu = B_TRUE;
2489 break;
2490 }
2491 }
2492
2493
2494 if ((B_FALSE == bHaveInit) ||
2495 (B_FALSE == bHaveTarg) ||
2496 (B_FALSE == bHaveLu)) {
2497 /* if we don't have all three pieces, we can't find the path */
2498
2499 return (B_FALSE);
2500 }
2501
2502 /* get the plugin ist */
2503 if ((mpstatus = MP_GetPluginOidList(&pPluginOidList))
2504 != MP_STATUS_SUCCESS) {
2505 (void) fprintf(stderr, "%s: %s\n", cmdName,
2506 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
2507 return (B_FALSE);
2508 }
2509 if ((NULL == pPluginOidList) || (pPluginOidList->oidCount < 1)) {
2510 (void) fprintf(stderr, "%s: %s\n", cmdName,
2511 getTextString(ERR_NO_MPATH_SUPPORT_LIST));
2512 return (B_FALSE);
2513 }
2514
2515 for (i = 0; i < pPluginOidList->oidCount; i++) {
2516
2517 /* get Logical Unit list */
2518 mpstatus = MP_GetMultipathLus(pPluginOidList->oids[i],
2519 &pLogicalUnitOidList);
2520 if (mpstatus != MP_STATUS_SUCCESS) {
2521 (void) fprintf(stderr, "%s: %s\n",
2522 cmdName, getTextString(ERR_NO_LU_LIST));
2523 return (B_FALSE);
2524 }
2525
2526 for (lu = 0; (lu < pLogicalUnitOidList->oidCount) &&
2527 (B_FALSE == bFoundIt); lu++) {
2528
2529 /* get lu properties so we can check the name */
2530 (void) memset(&luProps, 0,
2531 sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
2532 mpstatus =
2533 MP_GetMPLogicalUnitProperties(
2534 pLogicalUnitOidList->oids[lu], &luProps);
2535 if (mpstatus != MP_STATUS_SUCCESS) {
2536 (void) fprintf(stderr, "%s: %s\n",
2537 cmdName, getTextString(ERR_NO_PROPERTIES));
2538 return (B_FALSE);
2539 }
2540 if (compareLUName(luDeviceFileName,
2541 luProps.deviceFileName) == B_TRUE) {
2542 /* get paths for this LU and search from here */
2543 mpstatus =
2544 MP_GetAssociatedPathOidList(
2545 pLogicalUnitOidList->oids[lu],
2546 &pathOidListArray);
2547 if (mpstatus != MP_STATUS_SUCCESS) {
2548 /* LINTED E_SEC_PRINTF_VAR_FMT */
2549 (void) fprintf(stderr,
2550 getTextString(
2551 ERR_FAILED_TO_FIND_PATH));
2552 (void) printf("\n");
2553 return (B_FALSE);
2554 }
2555
2556 for (pa = 0;
2557 (pa < pathOidListArray->oidCount) &&
2558 (B_FALSE == bFoundIt); pa++) {
2559 mpstatus =
2560 MP_GetPathLogicalUnitProperties
2561 (pathOidListArray->oids[pa],
2562 &pathProps);
2563 if (mpstatus != MP_STATUS_SUCCESS) {
2564 (void) fprintf(stderr,
2565 "%s: %s\n", cmdName,
2566 getTextString(
2567 ERR_NO_PROPERTIES));
2568 return (B_FALSE);
2569 }
2570
2571 /*
2572 * get properties of iniator port and
2573 * target port to see if we have the
2574 * right path
2575 */
2576 mpstatus =
2577 MP_GetInitiatorPortProperties(
2578 pathProps.initiatorPortOid,
2579 &initProps);
2580
2581 if (mpstatus != MP_STATUS_SUCCESS) {
2582 (void) fprintf(stderr,
2583 "%s: %s\n", cmdName,
2584 getTextString(
2585 ERR_NO_PROPERTIES));
2586 return (B_FALSE);
2587 }
2588 if (0 == strcmp(initPortID, initProps.portID)) {
2589 /* lu and init port matches, check target port */
2590 mpstatus = MP_GetTargetPortProperties(pathProps.targetPortOid,
2591 &targProps);
2592 if (mpstatus != MP_STATUS_SUCCESS) {
2593 (void) fprintf(stderr, "%s: %s\n", cmdName,
2594 getTextString(ERR_NO_PROPERTIES));
2595 return (B_FALSE);
2596 }
2597
2598 if (0 == strcmp(targetPortID, targProps.portID)) {
2599 /* we found our path */
2600 pPathOid->objectSequenceNumber =
2601 pathOidListArray->oids[pa].objectSequenceNumber;
2602 pPathOid->objectType =
2603 pathOidListArray->oids[pa].objectType;
2604 pPathOid->ownerId = pathOidListArray->oids[pa].ownerId;
2605 bFoundIt = B_TRUE;
2606 }
2607 } /* init port matched */
2608
2609 } /* for each path associated with this lu */
2610
2611 } /* lu matched */
2612
2613 } /* for each lu */
2614
2615 } /* for each plugin */
2616
2617 return (bFoundIt);
2618 }
2619
2620
2621 /*
2622 * ****************************************************************************
2623 *
2624 * getLbValueFromString
2625 * Gets the MP_LOAD_BALANCE_TYPE specified load balance type string
2626 *
2627 * lbStr - load balance string defined in the .h file
2628 * This is what users will be required to feed into the
2629 * modify lu command.
2630 *
2631 * ****************************************************************************
2632 */
2633 MP_LOAD_BALANCE_TYPE
getLbValueFromString(char * lbStr)2634 getLbValueFromString(char *lbStr)
2635 {
2636 MP_LOAD_BALANCE_TYPE lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN;
2637
2638 if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_ROUNDROBIN))) {
2639 lbVal = MP_LOAD_BALANCE_TYPE_ROUNDROBIN;
2640 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTBLOCKS))) {
2641 lbVal = MP_LOAD_BALANCE_TYPE_LEASTBLOCKS;
2642 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LEASTIO))) {
2643 lbVal = MP_LOAD_BALANCE_TYPE_LEASTIO;
2644 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_DEVICEPROD))) {
2645 lbVal = MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT;
2646 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_LBAREGION))) {
2647 lbVal = MP_LOAD_BALANCE_TYPE_LBA_REGION;
2648 } else if (0 == strcmp(lbStr,
2649 getTextString(TEXT_LBTYPE_FAILOVER_ONLY))) {
2650 lbVal = MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY;
2651 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_UNKNOWN))) {
2652 lbVal = MP_LOAD_BALANCE_TYPE_UNKNOWN;
2653 } else if (0 == strcmp(lbStr, getTextString(TEXT_LBTYPE_NONE))) {
2654 lbVal = 0;
2655 } else if (0 == strcmp(lbStr,
2656 getTextString(TEXT_LBTYPE_PROPRIETARY1))) {
2657 lbVal = ((MP_UINT32)0x00000001)<<16;
2658 } else if (0 == strcmp(lbStr,
2659 getTextString(TEXT_LBTYPE_PROPRIETARY2))) {
2660 lbVal = ((MP_UINT32)0x00000001)<<17;
2661 } else if (0 == strcmp(lbStr,
2662 getTextString(TEXT_LBTYPE_PROPRIETARY3))) {
2663 lbVal = ((MP_UINT32)0x00000001)<<18;
2664 } else if (0 == strcmp(lbStr,
2665 getTextString(TEXT_LBTYPE_PROPRIETARY4))) {
2666 lbVal = ((MP_UINT32)0x00000001)<<19;
2667 } else if (0 == strcmp(lbStr,
2668 getTextString(TEXT_LBTYPE_PROPRIETARY5))) {
2669 lbVal = ((MP_UINT32)0x00000001)<<20;
2670 } else if (0 == strcmp(lbStr,
2671 getTextString(TEXT_LBTYPE_PROPRIETARY6))) {
2672 lbVal = ((MP_UINT32)0x00000001)<<21;
2673 } else if (0 == strcmp(lbStr,
2674 getTextString(TEXT_LBTYPE_PROPRIETARY7))) {
2675 lbVal = ((MP_UINT32)0x00000001)<<22;
2676 } else if (0 == strcmp(lbStr,
2677 getTextString(TEXT_LBTYPE_PROPRIETARY8))) {
2678 lbVal = ((MP_UINT32)0x00000001)<<23;
2679 } else if (0 == strcmp(lbStr,
2680 getTextString(TEXT_LBTYPE_PROPRIETARY9))) {
2681 lbVal = ((MP_UINT32)0x00000001)<<24;
2682 } else if (0 == strcmp(lbStr,
2683 getTextString(TEXT_LBTYPE_PROPRIETARY10))) {
2684 lbVal = ((MP_UINT32)0x00000001)<<25;
2685 } else if (0 == strcmp(lbStr,
2686 getTextString(TEXT_LBTYPE_PROPRIETARY11))) {
2687 lbVal = ((MP_UINT32)0x00000001)<<26;
2688 } else if (0 == strcmp(lbStr,
2689 getTextString(TEXT_LBTYPE_PROPRIETARY12))) {
2690 lbVal = ((MP_UINT32)0x00000001)<<27;
2691 } else if (0 == strcmp(lbStr,
2692 getTextString(TEXT_LBTYPE_PROPRIETARY13))) {
2693 lbVal = ((MP_UINT32)0x00000001)<<28;
2694 } else if (0 == strcmp(lbStr,
2695 getTextString(TEXT_LBTYPE_PROPRIETARY14))) {
2696 lbVal = ((MP_UINT32)0x00000001)<<29;
2697 } else if (0 == strcmp(lbStr,
2698 getTextString(TEXT_LBTYPE_PROPRIETARY15))) {
2699 lbVal = ((MP_UINT32)0x00000001)<<30;
2700 } else if (0 == strcmp(lbStr,
2701 getTextString(TEXT_LBTYPE_PROPRIETARY16))) {
2702 lbVal = ((MP_UINT32)0x00000001)<<31;
2703 }
2704
2705 return (lbVal);
2706
2707
2708 } /* end getLbValueFromString */
2709
2710
2711 /*
2712 * ****************************************************************************
2713 *
2714 * displayLogicalUnitNameTypeString
2715 * Displays the text equivalent string for the MP_LOGICAL_UNIT_NAME_TYPE
2716 * specified load balance type
2717 *
2718 * typeVal - load balance type defined in the MPAPI spec
2719 *
2720 * ****************************************************************************
2721 */
2722 void
displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal)2723 displayLogicalUnitNameTypeString(MP_LOGICAL_UNIT_NAME_TYPE typeVal)
2724 {
2725
2726 char *typeString;
2727
2728 switch (typeVal) {
2729
2730 case MP_LU_NAME_TYPE_UNKNOWN:
2731 typeString = getTextString(TEXT_NAME_TYPE_UNKNOWN);
2732 break;
2733 case MP_LU_NAME_TYPE_VPD83_TYPE1:
2734 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE1);
2735 break;
2736 case MP_LU_NAME_TYPE_VPD83_TYPE2:
2737 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE2);
2738 break;
2739 case MP_LU_NAME_TYPE_VPD83_TYPE3:
2740 typeString = getTextString(TEXT_NAME_TYPE_VPD83_TYPE3);
2741 break;
2742 case MP_LU_NAME_TYPE_DEVICE_SPECIFIC:
2743 typeString =
2744 getTextString(TEXT_NAME_TYPE_DEVICE_SPECIFIC);
2745 break;
2746 default:
2747 typeString = getTextString(TEXT_UNKNOWN);
2748 break;
2749 }
2750
2751 (void) printf("%s", typeString);
2752
2753
2754 } /* end displayLogicalUnitNameTypeString */
2755
2756 /*
2757 * ****************************************************************************
2758 *
2759 * displayLoadBalanceString
2760 * Displays the text equivalent string for the MP_LOAD_BALANCE_TYPE
2761 * specified load balance type
2762 *
2763 * lbVal - load balance type defined in the MPAPI spec
2764 *
2765 * ****************************************************************************
2766 */
2767 void
displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal)2768 displayLoadBalanceString(MP_LOAD_BALANCE_TYPE lbVal)
2769 {
2770
2771 char *lbString;
2772
2773 switch (lbVal) {
2774
2775 case MP_LOAD_BALANCE_TYPE_UNKNOWN:
2776 lbString = getTextString(TEXT_LBTYPE_UNKNOWN);
2777 break;
2778 case MP_LOAD_BALANCE_TYPE_ROUNDROBIN:
2779 lbString = getTextString(TEXT_LBTYPE_ROUNDROBIN);
2780 break;
2781 case MP_LOAD_BALANCE_TYPE_LEASTBLOCKS:
2782 lbString = getTextString(TEXT_LBTYPE_LEASTBLOCKS);
2783 break;
2784 case MP_LOAD_BALANCE_TYPE_LEASTIO:
2785 lbString = getTextString(TEXT_LBTYPE_LEASTIO);
2786 break;
2787 case MP_LOAD_BALANCE_TYPE_DEVICE_PRODUCT:
2788 lbString = getTextString(TEXT_LBTYPE_DEVICEPROD);
2789 break;
2790 case MP_LOAD_BALANCE_TYPE_LBA_REGION:
2791 lbString = getTextString(TEXT_LBTYPE_LBAREGION);
2792 break;
2793 case MP_LOAD_BALANCE_TYPE_FAILOVER_ONLY:
2794 lbString = getTextString(TEXT_LBTYPE_FAILOVER_ONLY);
2795 break;
2796 case (((MP_UINT32)0x00000001)<<16):
2797 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY1);
2798 break;
2799 case (((MP_UINT32)0x00000001)<<17):
2800 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY2);
2801 break;
2802 case (((MP_UINT32)0x00000001)<<18):
2803 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY3);
2804 break;
2805 case (((MP_UINT32)0x00000001)<<19):
2806 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY4);
2807 break;
2808 case (((MP_UINT32)0x00000001)<<20):
2809 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY5);
2810 break;
2811 case (((MP_UINT32)0x00000001)<<21):
2812 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY6);
2813 break;
2814 case (((MP_UINT32)0x00000001)<<22):
2815 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY7);
2816 break;
2817 case (((MP_UINT32)0x00000001)<<23):
2818 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY8);
2819 break;
2820 case (((MP_UINT32)0x00000001)<<24):
2821 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY9);
2822 break;
2823 case (((MP_UINT32)0x00000001)<<25):
2824 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY10);
2825 break;
2826 case (((MP_UINT32)0x00000001)<<26):
2827 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY11);
2828 break;
2829 case (((MP_UINT32)0x00000001)<<27):
2830 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY12);
2831 break;
2832 case (((MP_UINT32)0x00000001)<<28):
2833 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY13);
2834 break;
2835 case (((MP_UINT32)0x00000001)<<29):
2836 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY14);
2837 break;
2838 case (((MP_UINT32)0x00000001)<<30):
2839 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY15);
2840 break;
2841 case (((MP_UINT32)0x00000001)<<31):
2842 lbString = getTextString(TEXT_LBTYPE_PROPRIETARY16);
2843 break;
2844 default:
2845 lbString = getTextString(TEXT_UNKNOWN);
2846 break;
2847 }
2848
2849 (void) printf("%s", lbString);
2850
2851
2852 } /* end displayLoadBalanceString */
2853
2854 /*
2855 * ****************************************************************************
2856 *
2857 * displayTransportTypeString
2858 * Displays the text equivalent string for the MP_PORT_TRANSPORT_TYPE
2859 * specified load balance type
2860 *
2861 * transportTypeVal - transport type defined in the MPAPI spec
2862 *
2863 * ****************************************************************************
2864 */
2865 void
displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal)2866 displayTransportTypeString(MP_PORT_TRANSPORT_TYPE transportTypeVal)
2867 {
2868
2869 char *ttypeString;
2870 switch (transportTypeVal) {
2871
2872 case MP_PORT_TRANSPORT_TYPE_MPNODE:
2873 ttypeString =
2874 getTextString(TEXT_TRANS_PORT_TYPE_MPNODE);
2875 break;
2876 case MP_PORT_TRANSPORT_TYPE_FC:
2877 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_FC);
2878 break;
2879 case MP_PORT_TRANSPORT_TYPE_SPI:
2880 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_SPI);
2881 break;
2882 case MP_PORT_TRANSPORT_TYPE_ISCSI:
2883 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_ISCSI);
2884 break;
2885 case MP_PORT_TRANSPORT_TYPE_IFB:
2886 ttypeString = getTextString(TEXT_TRANS_PORT_TYPE_IFB);
2887 break;
2888 default:
2889 ttypeString = getTextString(TEXT_UNKNOWN);
2890 break;
2891 }
2892
2893 (void) printf("%s", ttypeString);
2894
2895 } /* end displayTransportTypeString */
2896
2897
2898 /*
2899 * ****************************************************************************
2900 *
2901 * getMpStatusStr
2902 * Gets the string description for the specified load balance type value
2903 *
2904 * mpstatus - MP_STATUS value
2905 *
2906 * ****************************************************************************
2907 */
2908 char *
getMpStatusStr(MP_STATUS mpstatus)2909 getMpStatusStr(MP_STATUS mpstatus)
2910 {
2911 char *statString;
2912
2913 switch (mpstatus) {
2914 case MP_STATUS_SUCCESS:
2915 statString = getTextString(TEXT_MPSTATUS_SUCCESS);
2916 break;
2917 case MP_STATUS_INVALID_PARAMETER:
2918 statString = getTextString(TEXT_MPSTATUS_INV_PARAMETER);
2919 break;
2920 case MP_STATUS_UNKNOWN_FN:
2921 statString = getTextString(TEXT_MPSTATUS_UNKNOWN_FN);
2922 break;
2923 case MP_STATUS_FAILED:
2924 statString = getTextString(TEXT_MPSTATUS_FAILED);
2925 break;
2926 case MP_STATUS_INSUFFICIENT_MEMORY:
2927 statString = getTextString(TEXT_MPSTATUS_INSUFF_MEMORY);
2928 break;
2929 case MP_STATUS_INVALID_OBJECT_TYPE:
2930 statString = getTextString(TEXT_MPSTATUS_INV_OBJ_TYPE);
2931 break;
2932 case MP_STATUS_UNSUPPORTED:
2933 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED);
2934 break;
2935 case MP_STATUS_OBJECT_NOT_FOUND:
2936 statString = getTextString(TEXT_MPSTATUS_OBJ_NOT_FOUND);
2937 break;
2938 case MP_STATUS_ACCESS_STATE_INVALID:
2939 statString = getTextString(TEXT_MPSTATUS_UNSUPPORTED);
2940 break;
2941 case MP_STATUS_FN_REPLACED:
2942 statString = getTextString(TEXT_MPSTATUS_FN_REPLACED);
2943 break;
2944 case MP_STATUS_PATH_NONOPERATIONAL:
2945 statString = getTextString(TEXT_MPSTATUS_PATH_NONOP);
2946 break;
2947 case MP_STATUS_TRY_AGAIN:
2948 statString = getTextString(TEXT_MPSTATUS_TRY_AGAIN);
2949 break;
2950 case MP_STATUS_NOT_PERMITTED:
2951 statString = getTextString(TEXT_MPSTATUS_NOT_PERMITTED);
2952 break;
2953 default:
2954 statString = getTextString(TEXT_UNKNOWN);
2955 break;
2956 }
2957
2958 return (statString);
2959 } /* end getMpStatusStr */
2960
2961
2962 /*
2963 * ****************************************************************************
2964 *
2965 * GetPathStateStr
2966 * Gets the string description for the specified path state type value
2967 *
2968 * pathState - MP_PATH_STATE values
2969 *
2970 * ****************************************************************************
2971 */
2972 char *
getPathStateStr(MP_PATH_STATE pathState)2973 getPathStateStr(MP_PATH_STATE pathState)
2974 {
2975 char *pathString;
2976
2977 switch (pathState) {
2978 case MP_PATH_STATE_OKAY:
2979 pathString = getTextString(TEXT_PATH_STATE_OKAY);
2980 break;
2981 case MP_PATH_STATE_PATH_ERR:
2982 pathString = getTextString(TEXT_PATH_STATE_PATH_ERR);
2983 break;
2984 case MP_PATH_STATE_LU_ERR:
2985 pathString = getTextString(TEXT_PATH_STATE_LU_ERR);
2986 break;
2987 case MP_PATH_STATE_RESERVED:
2988 pathString = getTextString(TEXT_PATH_STATE_RESERVED);
2989 break;
2990 case MP_PATH_STATE_REMOVED:
2991 pathString = getTextString(TEXT_PATH_STATE_REMOVED);
2992 break;
2993 case MP_PATH_STATE_TRANSITIONING:
2994 pathString =
2995 getTextString(TEXT_PATH_STATE_TRANSITIONING);
2996 break;
2997 case MP_PATH_STATE_OPERATIONAL_CLOSED:
2998 pathString =
2999 getTextString(TEXT_PATH_STATE_OPERATIONAL_CLOSED);
3000 break;
3001 case MP_PATH_STATE_INVALID_CLOSED:
3002 pathString =
3003 getTextString(TEXT_PATH_STATE_INVALID_CLOSED);
3004 break;
3005 case MP_PATH_STATE_OFFLINE_CLOSED:
3006 pathString =
3007 getTextString(TEXT_PATH_STATE_OFFLINE_CLOSED);
3008 break;
3009 default:
3010 pathString = getTextString(TEXT_UNKNOWN);
3011 break;
3012 }
3013
3014 return (pathString);
3015 } /* end getPathStateStr */
3016
3017
3018
3019 /*
3020 * ****************************************************************************
3021 *
3022 * getAccessStateStr
3023 * Gets the string description for the specified access state type value
3024 *
3025 * accessState - MP_ACCESS_STATE_TYPE values
3026 *
3027 * ****************************************************************************
3028 */
3029 char *
getAccessStateStr(MP_ACCESS_STATE_TYPE accessState)3030 getAccessStateStr(MP_ACCESS_STATE_TYPE accessState)
3031 {
3032 char *accessString;
3033
3034 switch (accessState) {
3035 case MP_ACCESS_STATE_ACTIVE_OPTIMIZED:
3036 accessString =
3037 getTextString(TEXT_ACCESS_STATE_ACTIVE_OPTIMIZED);
3038 break;
3039 case MP_ACCESS_STATE_ACTIVE_NONOPTIMIZED:
3040 accessString =
3041 getTextString(
3042 TEXT_ACCESS_STATE_ACTIVE_NONOPTIMIZED);
3043 break;
3044 case MP_ACCESS_STATE_STANDBY:
3045 accessString =
3046 getTextString(TEXT_ACCESS_STATE_STANDBY);
3047 break;
3048 case MP_ACCESS_STATE_UNAVAILABLE:
3049 accessString =
3050 getTextString(TEXT_ACCESS_STATE_UNAVAILABLE);
3051 break;
3052 case MP_ACCESS_STATE_TRANSITIONING:
3053 accessString =
3054 getTextString(TEXT_ACCESS_STATE_TRANSITIONING);
3055 break;
3056 case MP_ACCESS_STATE_ACTIVE:
3057 accessString = getTextString(TEXT_ACCESS_STATE_ACTIVE);
3058 break;
3059 default:
3060 accessString = getTextString(TEXT_UNKNOWN);
3061 break;
3062 }
3063 return (accessString);
3064 } /* end getAccessStateStr */
3065
3066
3067 /*
3068 * ****************************************************************************
3069 *
3070 * displayArray
3071 * Print out the specified array.
3072 *
3073 * arrayToDisplay - array to display
3074 * arraySize - size of array to display
3075 *
3076 * ****************************************************************************
3077 */
3078 void
displayArray(MP_CHAR * arrayToDisplay,int arraySize)3079 displayArray(MP_CHAR *arrayToDisplay, int arraySize)
3080 {
3081 int i;
3082
3083 for (i = 0; i < arraySize; i++) {
3084 if ('\0' != arrayToDisplay[i]) {
3085 (void) fprintf(stdout, "%c", arrayToDisplay[i]);
3086 }
3087 }
3088
3089 }
3090
3091
3092 /*
3093 * ****************************************************************************
3094 *
3095 * getStringArray
3096 * Return a null terminated array for the specified array as a string,
3097 * This is used for inputting into the %s in formatted strings.
3098 *
3099 * arrayToDisplay - array to display
3100 * arraySize - size of array to display
3101 *
3102 * ****************************************************************************
3103 */
3104 MP_CHAR *
getStringArray(MP_CHAR * arrayToDisplay,int arraySize)3105 getStringArray(MP_CHAR *arrayToDisplay, int arraySize)
3106 {
3107 MP_CHAR *newStr;
3108
3109 int i;
3110
3111 newStr = malloc(((sizeof (MP_CHAR)) * arraySize) + 1);
3112 if (NULL == newStr) {
3113 (void) fprintf(stdout, "%s\n",
3114 getTextString(ERR_MEMORY_ALLOCATION));
3115 } else {
3116
3117 for (i = 0; i < arraySize; i++) {
3118 newStr[i] = arrayToDisplay[i];
3119 }
3120 newStr[arraySize] = '\0';
3121 }
3122
3123 return (newStr);
3124 }
3125
3126
3127 /*
3128 * ****************************************************************************
3129 *
3130 * displayWideArray
3131 * Print out the specified wide character array as a string,
3132 * adding the null termination
3133 *
3134 * arrayToDisplay - array to display
3135 * arraySize - size of array to display
3136 *
3137 * ****************************************************************************
3138 */
3139 void
displayWideArray(MP_WCHAR * arrayToDisplay,int arraySize)3140 displayWideArray(MP_WCHAR *arrayToDisplay, int arraySize)
3141 {
3142 int i;
3143 int numChars = arraySize/4;
3144
3145 for (i = 0; i < numChars; i++) {
3146 if (L'\0' != arrayToDisplay[i]) {
3147 (void) fprintf(stdout, "%wc", (int)arrayToDisplay[i]);
3148 }
3149 }
3150 }
3151
3152
3153 /*
3154 * ****************************************************************************
3155 *
3156 * listfunc
3157 * Used by cmdparse for list clis
3158 *
3159 * ****************************************************************************
3160 */
3161 /*ARGSUSED*/
3162 static int
listFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3163 listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3164 void *addArgs)
3165 {
3166 int ret = 0;
3167
3168 switch (object) {
3169 case MPATH_SUPPORT:
3170 ret = listMpathSupport(operandLen, operand);
3171 break;
3172 case LOGICAL_UNIT:
3173 ret = listLogicalUnit(operandLen, operand, options);
3174 break;
3175 case INITIATOR_PORT:
3176 ret = listInitiatorPort(operandLen, operand);
3177 break;
3178 default:
3179 (void) fprintf(stderr, "%s: %s\n",
3180 cmdName, getTextString(TEXT_UNKNOWN_OBJECT));
3181 ret = 1;
3182 break;
3183 }
3184
3185 return (ret);
3186 }
3187
3188
3189 /*
3190 * ****************************************************************************
3191 *
3192 * showFunc
3193 * used bycmdparse for show clis
3194 *
3195 * ****************************************************************************
3196 */
3197 /*ARGSUSED*/
3198 static int
showFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3199 showFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3200 void *addArgs)
3201 {
3202 int ret = 0;
3203
3204 switch (object) {
3205 case MPATH_SUPPORT:
3206 ret = showMpathSupport(operandLen, operand);
3207 break;
3208 case LOGICAL_UNIT:
3209 ret = showLogicalUnit(operandLen, operand);
3210 break;
3211 case INITIATOR_PORT:
3212 ret = showInitiatorPort(operandLen, operand);
3213 break;
3214 default:
3215 ret = 1;
3216 break;
3217 }
3218
3219 return (ret);
3220 }
3221
3222
3223 /*
3224 * ****************************************************************************
3225 *
3226 * modifyFunc
3227 * Used by cmdparse for midify clis
3228 *
3229 *
3230 * ****************************************************************************
3231 */
3232 /*ARGSUSED*/
3233 static int
modifyFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3234 modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3235 void *addArgs)
3236 {
3237 int ret = 0;
3238
3239 switch (object) {
3240 case MPATH_SUPPORT:
3241 ret = modifyMpathSupport(operandLen, operand, options);
3242 break;
3243 case LOGICAL_UNIT:
3244 ret = modifyLogicalUnit(operandLen, operand, options);
3245 break;
3246 default:
3247 ret = 1;
3248 break;
3249 }
3250
3251
3252 return (ret);
3253 }
3254
3255
3256 /*
3257 * ****************************************************************************
3258 *
3259 * enableFunc
3260 * Used by cmdpars for enable clis
3261 *
3262 * ****************************************************************************
3263 */
3264 /*ARGSUSED*/
3265 static int
enableFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3266 enableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3267 void *addArgs)
3268 {
3269 int ret = 0;
3270
3271 switch (object) {
3272 case PATH:
3273 ret = enablePath(options);
3274 break;
3275 default:
3276 ret = 1;
3277 break;
3278 }
3279
3280 return (ret);
3281 }
3282
3283
3284 /*
3285 * ****************************************************************************
3286 *
3287 * disableFunc
3288 * Used by cmdpars for disable clis
3289 *
3290 * ****************************************************************************
3291 */
3292 /*ARGSUSED*/
3293 static int
disableFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3294 disableFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3295 void *addArgs)
3296 {
3297 int ret = 0;
3298
3299 switch (object) {
3300 case PATH:
3301 ret = disablePath(options);
3302 break;
3303 default:
3304 ret = 1;
3305 break;
3306 }
3307
3308 return (ret);
3309 }
3310
3311
3312 /*
3313 * ****************************************************************************
3314 *
3315 * failoverFunc
3316 * Used by cmdpars for failover clis
3317 *
3318 * ****************************************************************************
3319 */
3320 /*ARGSUSED*/
3321 static int
failoverFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3322 failoverFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
3323 void *addArgs)
3324 {
3325 int ret = 0;
3326
3327 switch (object) {
3328 case LOGICAL_UNIT:
3329 ret = failoverLogicalUnit(operand);
3330 break;
3331 default:
3332 ret = 1;
3333 break;
3334 }
3335
3336 return (ret);
3337 }
3338
3339
3340 /*
3341 * ****************************************************************************
3342 *
3343 * overrideFunc
3344 * Used by cmdpars for override clis
3345 *
3346 * ****************************************************************************
3347 */
3348 /*ARGSUSED*/
3349 static int
overrideFunc(int operandLen,char * operand[],int object,cmdOptions_t * options,void * addArgs)3350 overrideFunc(int operandLen, char *operand[],
3351 int object, cmdOptions_t *options,
3352 void *addArgs)
3353 {
3354 int ret = 0;
3355
3356 switch (object) {
3357 case PATH:
3358 ret = overridePath(options);
3359 break;
3360 default:
3361 ret = 1;
3362 break;
3363 }
3364
3365
3366 return (ret);
3367 }
3368
3369
3370 /*
3371 * *************************************************************************
3372 *
3373 * main
3374 *
3375 * *************************************************************************
3376 */
3377 int
main(int argc,char * argv[])3378 main(int argc, char *argv[])
3379 {
3380 synTables_t synTables;
3381 char versionString[VERSION_STRING_MAX_LEN];
3382 int ret;
3383 int funcRet;
3384 void *subcommandArgs = NULL;
3385
3386 /* set global command name */
3387 cmdName = getExecBasename(argv[0]);
3388
3389 (void) sprintf(versionString, "%2s.%2s",
3390 VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
3391 synTables.versionString = versionString;
3392 synTables.longOptionTbl = &longOptions[0];
3393 synTables.subcommandTbl = &subcommands[0];
3394 synTables.objectTbl = &objects[0];
3395 synTables.objectRulesTbl = &objectRules[0];
3396 synTables.optionRulesTbl = &optionRules[0];
3397
3398 ret = cmdParse(argc, argv, /* SUB_COMMAND_ISSUED, */ synTables,
3399 subcommandArgs, &funcRet);
3400 if (ret == 1) {
3401 (void) fprintf(stdout, "%s %s(1M)\n",
3402 getTextString(TEXT_MORE_INFO), cmdName);
3403 return (ERROR_CLI_FAILED);
3404 } else if (ret == -1) {
3405 perror(argv[0]);
3406 return (1);
3407 }
3408
3409 if (funcRet != 0) {
3410 (void) fprintf(stderr, "%s: %s\n",
3411 argv[0], getTextString(TEXT_UNABLE_TO_COMPLETE));
3412 return (1);
3413 }
3414 return (0);
3415
3416 } /* end main */
3417