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