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 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <strings.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <wchar.h>
32 #include <libintl.h>
33 #include <errno.h>
34 #include <time.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <getopt.h>
38 #include <cmdparse.h>
39 #include <stmfadm.h>
40 #include <libstmf.h>
41 #include <signal.h>
42 #include <pthread.h>
43 #include <locale.h>
44
45 static int addHostGroupMemberFunc(int, char **, cmdOptions_t *, void *);
46 static int addTargetGroupMemberFunc(int, char **, cmdOptions_t *, void *);
47 static int addViewFunc(int, char **, cmdOptions_t *, void *);
48 static int createHostGroupFunc(int, char **, cmdOptions_t *, void *);
49 static int createLuFunc(int, char **, cmdOptions_t *, void *);
50 static int modifyLuFunc(int, char **, cmdOptions_t *, void *);
51 static int importLuFunc(int, char **, cmdOptions_t *, void *);
52 static int deleteLuFunc(int, char **, cmdOptions_t *, void *);
53 static int createTargetGroupFunc(int, char **, cmdOptions_t *, void *);
54 static int deleteHostGroupFunc(int, char **, cmdOptions_t *, void *);
55 static int deleteTargetGroupFunc(int, char **, cmdOptions_t *, void *);
56 static int listLuFunc(int, char **, cmdOptions_t *, void *);
57 static int listTargetFunc(int, char **, cmdOptions_t *, void *);
58 static int listViewFunc(int, char **, cmdOptions_t *, void *);
59 static int listHostGroupFunc(int, char **, cmdOptions_t *, void *);
60 static int listStateFunc(int, char **, cmdOptions_t *, void *);
61 static int listTargetGroupFunc(int, char **, cmdOptions_t *, void *);
62 static int offlineTargetFunc(int, char **, cmdOptions_t *, void *);
63 static int offlineLuFunc(int, char **, cmdOptions_t *, void *);
64 static int onlineTargetFunc(int, char **, cmdOptions_t *, void *);
65 static int onlineLuFunc(int, char **, cmdOptions_t *, void *);
66 static int onlineOfflineTarget(char *, int);
67 static int onlineOfflineLu(char *, int);
68 static int removeHostGroupMemberFunc(int, char **, cmdOptions_t *, void *);
69 static int removeTargetGroupMemberFunc(int, char **, cmdOptions_t *, void *);
70 static int callModify(char *, stmfGuid *, uint32_t, const char *, const char *);
71 static int removeViewFunc(int, char **, cmdOptions_t *, void *);
72 static char *getExecBasename(char *);
73 static int parseDevid(char *input, stmfDevid *devid);
74 static void printGroupProps(stmfGroupProperties *groupProps);
75 static int checkScsiNameString(wchar_t *, stmfDevid *);
76 static int checkHexUpper(char *);
77 static int checkIscsiName(wchar_t *);
78 static void printLuProps(stmfLogicalUnitProperties *luProps);
79 static int printExtLuProps(stmfGuid *guid);
80 static void printGuid(stmfGuid *guid, FILE *printWhere);
81 static void printTargetProps(stmfTargetProperties *);
82 static void printSessionProps(stmfSessionList *);
83 static int setLuPropFromInput(luResource, char *);
84 static int convertCharToPropId(char *, uint32_t *);
85
86
87
88 /*
89 * MAJOR - This should only change when there is an incompatible change made
90 * to the interfaces or the output.
91 *
92 * MINOR - This should change whenever there is a new command or new feature
93 * with no incompatible change.
94 */
95 #define VERSION_STRING_MAJOR "1"
96 #define VERSION_STRING_MINOR "0"
97 #define MAX_DEVID_INPUT 256
98 #define GUID_INPUT 32
99 #define MAX_LU_NBR 16383
100 #define ONLINE_LU 0
101 #define OFFLINE_LU 1
102 #define ONLINE_TARGET 2
103 #define OFFLINE_TARGET 3
104 #define PROPS_FORMAT " %-18s: "
105 #define VIEW_FORMAT " %-13s: "
106 #define LVL3_FORMAT " %s"
107 #define LVL4_FORMAT " %s"
108 #define DELAYED_EXEC_WAIT_INTERVAL 300 * 1000 * 1000 /* in nano sec */
109 #define DELAYED_EXEC_WAIT_MAX 30 /* Maximum number of interval times */
110
111 /* SCSI Name String length definitions */
112 #define SNS_EUI_16 16
113 #define SNS_EUI_24 24
114 #define SNS_EUI_32 32
115 #define SNS_NAA_16 16
116 #define SNS_NAA_32 32
117 #define SNS_WWN_16 16
118 #define SNS_IQN_223 223
119
120 /* LU Property strings */
121 #define GUID "GUID"
122 #define ALIAS "ALIAS"
123 #define VID "VID"
124 #define PID "PID"
125 #define META_FILE "META"
126 #define WRITE_PROTECT "WP"
127 #define WRITEBACK_CACHE_DISABLE "WCD"
128 #define COMPANY_ID "OUI"
129 #define BLOCK_SIZE "BLK"
130 #define SERIAL_NUMBER "SERIAL"
131 #define MGMT_URL "MGMT-URL"
132 #define HOST_ID "HOST-ID"
133
134 #define STMFADM_SUCCESS 0
135 #define STMFADM_FAILURE 1
136
137 #define MODIFY_HELP "\n"\
138 "Description: Modify properties of a logical unit. \n" \
139 "Valid properties for -p, --lu-prop are: \n" \
140 " alias - alias for logical unit (up to 255 chars)\n" \
141 " mgmt-url - Management URL address\n" \
142 " wcd - write cache disabled (true, false)\n" \
143 " wp - write protect (true, false)\n\n" \
144 "-f alters the meaning of the operand to be a file name\n" \
145 "rather than a LU name. This allows for modification\n" \
146 "of a logical unit that is not yet imported into stmf\n"
147
148 #define CREATE_HELP "\n"\
149 "Description: Create a logical unit. \n" \
150 "Valid properties for -p, --lu-prop are: \n" \
151 " alias - alias for logical unit (up to 255 chars)\n" \
152 " blk - block size in bytes in 2^n\n" \
153 " guid - 32 ascii hex characters in NAA format \n" \
154 " host-id - host identifier to be used for GUID generation \n" \
155 " 8 ascii hex characters\n" \
156 " meta - separate meta data file name\n" \
157 " mgmt-url - Management URL address\n" \
158 " oui - organizational unique identifier\n" \
159 " 6 ascii hex characters of valid format\n" \
160 " pid - product identifier (up to 16 chars)\n" \
161 " serial - serial number (up to 252 chars)\n" \
162 " vid - vendor identifier (up to 8 chars)\n" \
163 " wcd - write cache disabled (true, false)\n" \
164 " wp - write protect (true, false)\n"
165 #define ADD_VIEW_HELP "\n"\
166 "Description: Add a view entry to a logical unit. \n" \
167 "A view entry is comprised of three elements; the \n" \
168 "logical unit number, the target group name and the\n" \
169 "host group name. These three elements combine together\n" \
170 "to form a view for a given COMSTAR logical unit.\n" \
171 "This view is realized by a client, a SCSI initiator,\n" \
172 "via a REPORT LUNS command. \n"
173
174
175
176 /* tables set up based on cmdparse instructions */
177
178 /* add new options here */
179 optionTbl_t longOptions[] = {
180 {"all", no_arg, 'a', NULL},
181 {"group-name", required_arg, 'g', "group-name"},
182 {"keep-views", no_arg, 'k', NULL},
183 {"lu-name", required_arg, 'l', "LU-Name"},
184 {"lun", required_arg, 'n', "logical-unit-number"},
185 {"lu-prop", required_arg, 'p', "logical-unit-property=value"},
186 {"file", no_arg, 'f', "filename"},
187 {"size", required_arg, 's', "size K/M/G/T/P"},
188 {"target-group", required_arg, 't', "group-name"},
189 {"host-group", required_arg, 'h', "group-name"},
190 {"verbose", no_arg, 'v', NULL},
191 {NULL, 0, 0, 0}
192 };
193
194 /*
195 * Add new subcommands here
196 */
197 subCommandProps_t subcommands[] = {
198 {"add-hg-member", addHostGroupMemberFunc, "g", "g", NULL,
199 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL},
200 {"add-tg-member", addTargetGroupMemberFunc, "g", "g", NULL,
201 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL},
202 {"add-view", addViewFunc, "nth", NULL, NULL,
203 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, ADD_VIEW_HELP},
204 {"create-hg", createHostGroupFunc, NULL, NULL, NULL,
205 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL},
206 {"create-tg", createTargetGroupFunc, NULL, NULL, NULL,
207 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL},
208 {"create-lu", createLuFunc, "ps", NULL, NULL, OPERAND_MANDATORY_SINGLE,
209 "lu file", CREATE_HELP},
210 {"delete-hg", deleteHostGroupFunc, NULL, NULL, NULL,
211 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL},
212 {"modify-lu", modifyLuFunc, "psf", NULL, NULL, OPERAND_MANDATORY_SINGLE,
213 OPERANDSTRING_LU, MODIFY_HELP},
214 {"delete-lu", deleteLuFunc, "k", NULL, NULL,
215 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_LU, NULL},
216 {"delete-tg", deleteTargetGroupFunc, NULL, NULL, NULL,
217 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL},
218 {"import-lu", importLuFunc, NULL, NULL, NULL,
219 OPERAND_MANDATORY_SINGLE, "file name", NULL},
220 {"list-hg", listHostGroupFunc, "v", NULL, NULL,
221 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_GROUP_NAME, NULL},
222 {"list-lu", listLuFunc, "v", NULL, NULL, OPERAND_OPTIONAL_MULTIPLE,
223 OPERANDSTRING_LU, NULL},
224 {"list-state", listStateFunc, NULL, NULL, NULL, OPERAND_NONE, NULL},
225 {"list-target", listTargetFunc, "v", NULL, NULL,
226 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_TARGET, NULL},
227 {"list-tg", listTargetGroupFunc, "v", NULL, NULL,
228 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_GROUP_NAME, NULL},
229 {"list-view", listViewFunc, "l", "l", NULL,
230 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_VIEW_ENTRY, NULL},
231 {"online-lu", onlineLuFunc, NULL, NULL, NULL,
232 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, NULL},
233 {"offline-lu", offlineLuFunc, NULL, NULL, NULL,
234 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, NULL},
235 {"online-target", onlineTargetFunc, NULL, NULL, NULL,
236 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_TARGET, NULL},
237 {"offline-target", offlineTargetFunc, NULL, NULL, NULL,
238 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_TARGET, NULL},
239 {"remove-hg-member", removeHostGroupMemberFunc, "g", "g", NULL,
240 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL},
241 {"remove-tg-member", removeTargetGroupMemberFunc, "g", "g", NULL,
242 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL},
243 {"remove-view", removeViewFunc, "la", "l", NULL,
244 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_VIEW_ENTRY, NULL},
245 {NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL}
246 };
247
248 /* globals */
249 char *cmdName;
250
251 /*
252 * addHostGroupMemberFunc
253 *
254 * Add members to a host group
255 *
256 */
257 /*ARGSUSED*/
258 static int
259 addHostGroupMemberFunc(int operandLen, char *operands[], cmdOptions_t *options,
260 void *args)
261 {
262 int i;
263 int ret = 0;
264 int stmfRet;
265 stmfGroupName groupName = {0};
266 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
267 stmfDevid devid;
268
269 for (; options->optval; options++) {
270 switch (options->optval) {
271 /* host group name */
272 case 'g':
273 (void) mbstowcs(groupNamePrint, options->optarg,
274 sizeof (stmfGroupName) - 1);
275 bcopy(options->optarg, groupName,
276 strlen(options->optarg));
277 break;
278 default:
279 (void) fprintf(stderr, "%s: %c: %s\n",
280 cmdName, options->optval,
281 gettext("unknown option"));
282 return (1);
283 }
284 }
285
286 for (i = 0; i < operandLen; i++) {
287 if (parseDevid(operands[i], &devid) != 0) {
288 (void) fprintf(stderr, "%s: %s: %s\n",
289 cmdName, operands[i],
290 gettext("unrecognized device id"));
291 ret++;
292 continue;
293 }
294 stmfRet = stmfAddToHostGroup(&groupName, &devid);
295 switch (stmfRet) {
296 case STMF_STATUS_SUCCESS:
297 break;
298 case STMF_ERROR_EXISTS:
299 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
300 operands[i], gettext("already exists"));
301 ret++;
302 break;
303 case STMF_ERROR_GROUP_NOT_FOUND:
304 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
305 groupNamePrint, gettext("not found"));
306 ret++;
307 break;
308 case STMF_ERROR_PERM:
309 (void) fprintf(stderr, "%s: %s\n", cmdName,
310 gettext("permission denied"));
311 ret++;
312 break;
313 case STMF_ERROR_BUSY:
314 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
315 operands[i], gettext("resource busy"));
316 ret++;
317 break;
318 case STMF_ERROR_SERVICE_NOT_FOUND:
319 (void) fprintf(stderr, "%s: %s\n", cmdName,
320 gettext("STMF service not found"));
321 ret++;
322 break;
323 case STMF_ERROR_SERVICE_DATA_VERSION:
324 (void) fprintf(stderr, "%s: %s\n", cmdName,
325 gettext("STMF service version incorrect"));
326 ret++;
327 break;
328 default:
329 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
330 operands[i], gettext("unknown error"));
331 ret++;
332 break;
333 }
334 }
335
336 return (ret);
337 }
338
339 /*
340 * addTargetGroupMemberFunc
341 *
342 * Add members to a target group
343 *
344 */
345 /*ARGSUSED*/
346 static int
347 addTargetGroupMemberFunc(int operandLen, char *operands[],
348 cmdOptions_t *options, void *args)
349 {
350 int i;
351 int ret = 0;
352 int stmfRet;
353 stmfGroupName groupName = {0};
354 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
355 stmfDevid devid;
356
357 for (; options->optval; options++) {
358 switch (options->optval) {
359 /* target group name */
360 case 'g':
361 (void) mbstowcs(groupNamePrint, options->optarg,
362 sizeof (stmfGroupName) - 1);
363 bcopy(options->optarg, groupName,
364 strlen(options->optarg));
365 break;
366 default:
367 (void) fprintf(stderr, "%s: %c: %s\n",
368 cmdName, options->optval,
369 gettext("unknown option"));
370 return (1);
371 }
372 }
373
374 for (i = 0; i < operandLen; i++) {
375 if (parseDevid(operands[i], &devid) != 0) {
376 (void) fprintf(stderr, "%s: %s: %s\n",
377 cmdName, operands[i],
378 gettext("unrecognized device id"));
379 ret++;
380 continue;
381 }
382 stmfRet = stmfAddToTargetGroup(&groupName, &devid);
383 switch (stmfRet) {
384 case STMF_STATUS_SUCCESS:
385 break;
386 case STMF_ERROR_EXISTS:
387 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
388 operands[i], gettext("already exists"));
389 ret++;
390 break;
391 case STMF_ERROR_GROUP_NOT_FOUND:
392 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
393 groupNamePrint, gettext("not found"));
394 ret++;
395 break;
396 case STMF_ERROR_PERM:
397 (void) fprintf(stderr, "%s: %s\n", cmdName,
398 gettext("permission denied"));
399 ret++;
400 break;
401 case STMF_ERROR_BUSY:
402 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
403 operands[i], gettext("resource busy"));
404 ret++;
405 break;
406 case STMF_ERROR_SERVICE_NOT_FOUND:
407 (void) fprintf(stderr, "%s: %s\n", cmdName,
408 gettext("STMF service not found"));
409 ret++;
410 break;
411 case STMF_ERROR_SERVICE_ONLINE:
412 (void) fprintf(stderr, "%s: %s\n", cmdName,
413 gettext("STMF service must be offline"));
414 ret++;
415 break;
416 case STMF_ERROR_SERVICE_DATA_VERSION:
417 (void) fprintf(stderr, "%s: %s\n", cmdName,
418 gettext("STMF service version incorrect"));
419 ret++;
420 break;
421 case STMF_ERROR_TG_ONLINE:
422 (void) fprintf(stderr, "%s: %s\n", cmdName,
423 gettext("STMF target must be offline"));
424 ret++;
425 break;
426 default:
427 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
428 operands[i], gettext("unknown error"));
429 ret++;
430 break;
431 }
432 }
433
434 return (ret);
435 }
436
437 /*
438 * parseDevid
439 *
440 * Converts char * input to a stmfDevid
441 *
442 * input - this should be in the following format with either a
443 * wwn. iqn. or eui. representation.
444 * A name string of the format:
445 * wwn.<WWN> (FC/SAS address)
446 * iqn.<iSCSI name> (iSCSI iqn)
447 * eui.<WWN> (iSCSI eui name)
448 *
449 * devid - pointer to stmfDevid structure allocated by the caller.
450 *
451 * Returns:
452 * 0 on success
453 * non-zero on failure
454 */
455 static int
456 parseDevid(char *input, stmfDevid *devid)
457 {
458 wchar_t inputWc[MAX_DEVID_INPUT + 1] = {0};
459
460 /* convert to wcs */
461 (void) mbstowcs(inputWc, input, MAX_DEVID_INPUT);
462
463 /*
464 * Check for known scsi name string formats
465 * If one is found, we're done
466 * If not, then it's a failure to parse
467 */
468 if (checkScsiNameString(inputWc, devid) == 0) {
469 return (0);
470 }
471
472 return (-1);
473 }
474
475 /*
476 * checkScsiNameString
477 *
478 * Validates known SCSI name string formats and converts to stmfDevid
479 * format
480 *
481 * input - input SCSI name string
482 * devid - pointer to stmfDevid structure allocated by the caller
483 * on successful return, contains the devid based on input
484 *
485 * returns:
486 * 0 on success
487 * -1 on failure
488 */
489 static int
490 checkScsiNameString(wchar_t *input, stmfDevid *devid)
491 {
492 char *mbString = NULL;
493 int mbStringLen;
494 int len;
495 int i;
496
497 /*
498 * Convert to multi-byte string
499 *
500 * This is used for either eui or naa formats
501 */
502 mbString = calloc(1, (mbStringLen = wcstombs(mbString, input, 0)) + 1);
503 if (mbString == NULL) {
504 (void) fprintf(stderr, "%s: %s\n",
505 cmdName, "Insufficient memory\n");
506 return (-1);
507 }
508 if (wcstombs(mbString, input, mbStringLen) == (size_t)-1) {
509 return (-1);
510 }
511
512 /*
513 * check for iqn format
514 */
515 if (strncmp(mbString, "iqn.", 4) == 0) {
516 if ((len = strlen(mbString)) > (SNS_IQN_223)) {
517 return (-1);
518 }
519 for (i = 0; i < len; i++) {
520 mbString[i] = tolower(mbString[i]);
521 }
522 if (checkIscsiName(input + 4) != 0) {
523 return (-1);
524 }
525 } else if (strncmp(mbString, "wwn.", 4) == 0) {
526 if ((len = strlen(mbString + 4)) != SNS_WWN_16) {
527 return (-1);
528 } else if (checkHexUpper(mbString + 4) != 0) {
529 return (-1);
530 }
531 } else if (strncmp(mbString, "eui.", 4) == 0) {
532 if ((len = strlen(mbString + 4)) != SNS_EUI_16) {
533 return (-1);
534 } else if (checkHexUpper(mbString + 4) != 0) {
535 return (-1);
536 }
537 } else {
538 return (-1);
539 }
540
541 /*
542 * We have a validated name string.
543 * Go ahead and set the length and copy it.
544 */
545 devid->identLength = strlen(mbString);
546 bzero(devid->ident, STMF_IDENT_LENGTH);
547 bcopy(mbString, devid->ident, devid->identLength);
548
549 return (0);
550 }
551
552
553 /*
554 * Checks whether the entire string is in hex and converts to upper
555 */
556 static int
557 checkHexUpper(char *input)
558 {
559 int i;
560
561 for (i = 0; i < strlen(input); i++) {
562 if (isxdigit(input[i])) {
563 input[i] = toupper(input[i]);
564 continue;
565 }
566 return (-1);
567 }
568
569 return (0);
570 }
571
572 /*
573 * checkIscsiName
574 *
575 * Purpose: Basic string checking on name
576 */
577 static int
578 checkIscsiName(wchar_t *input)
579 {
580 int i;
581
582 for (i = 0; input[i] != 0; i++) {
583 if (!iswalnum(input[i]) && input[i] != '-' &&
584 input[i] != '.' && input[i] != ':') {
585 return (-1);
586 }
587 }
588
589 return (0);
590 }
591
592
593 /*
594 * addViewFunc
595 *
596 * Adds a view entry to a logical unit
597 *
598 */
599 /*ARGSUSED*/
600 static int
601 addViewFunc(int operandLen, char *operands[], cmdOptions_t *options,
602 void *args)
603 {
604 stmfViewEntry viewEntry;
605 stmfGuid inGuid;
606 unsigned int guid[sizeof (stmfGuid)];
607 uint16_t inputLuNbr;
608 int ret = 0;
609 int stmfRet;
610 int i;
611 char sGuid[GUID_INPUT + 1];
612
613 bzero(&viewEntry, sizeof (viewEntry));
614 /* init view entry structure */
615 viewEntry.allHosts = B_TRUE;
616 viewEntry.allTargets = B_TRUE;
617 viewEntry.luNbrValid = B_FALSE;
618
619 /* check input length */
620 if (strlen(operands[0]) != GUID_INPUT) {
621 (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0],
622 gettext("must be "), GUID_INPUT,
623 gettext(" hexadecimal digits"));
624 return (1);
625 }
626
627 for (; options->optval; options++) {
628 switch (options->optval) {
629 /* logical unit number */
630 case 'n':
631 viewEntry.luNbrValid = B_TRUE;
632 inputLuNbr = atoi(options->optarg);
633 if (inputLuNbr > MAX_LU_NBR) {
634 (void) fprintf(stderr, "%s: %d: %s\n",
635 cmdName, inputLuNbr,
636 gettext("Logical unit number"
637 " must be less than 16384"));
638 return (1);
639 }
640 viewEntry.luNbr[0] = inputLuNbr >> 8;
641 viewEntry.luNbr[1] = inputLuNbr & 0xff;
642 break;
643 /* host group */
644 case 'h':
645 viewEntry.allHosts = B_FALSE;
646 bcopy(options->optarg, viewEntry.hostGroup,
647 strlen(options->optarg));
648 break;
649 /* target group */
650 case 't':
651 viewEntry.allTargets = B_FALSE;
652 bcopy(options->optarg, viewEntry.targetGroup,
653 strlen(options->optarg));
654 break;
655 default:
656 (void) fprintf(stderr, "%s: %c: %s\n",
657 cmdName, options->optval,
658 gettext("unknown option"));
659 return (1);
660 }
661 }
662
663 /* convert to lower case for scan */
664 for (i = 0; i < 32; i++)
665 sGuid[i] = tolower(operands[0][i]);
666 sGuid[i] = 0;
667
668 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
669 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
670 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11],
671 &guid[12], &guid[13], &guid[14], &guid[15]);
672
673 for (i = 0; i < sizeof (stmfGuid); i++) {
674 inGuid.guid[i] = guid[i];
675 }
676
677 /* add the view entry */
678 stmfRet = stmfAddViewEntry(&inGuid, &viewEntry);
679 switch (stmfRet) {
680 case STMF_STATUS_SUCCESS:
681 break;
682 case STMF_ERROR_EXISTS:
683 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
684 operands[0], gettext("already exists"));
685 ret++;
686 break;
687 case STMF_ERROR_BUSY:
688 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
689 operands[0], gettext("resource busy"));
690 ret++;
691 break;
692 case STMF_ERROR_SERVICE_NOT_FOUND:
693 (void) fprintf(stderr, "%s: %s\n", cmdName,
694 gettext("STMF service not found"));
695 ret++;
696 break;
697 case STMF_ERROR_PERM:
698 (void) fprintf(stderr, "%s: %s\n", cmdName,
699 gettext("permission denied"));
700 ret++;
701 break;
702 case STMF_ERROR_LUN_IN_USE:
703 (void) fprintf(stderr, "%s: %s\n", cmdName,
704 gettext("LUN already in use"));
705 ret++;
706 break;
707 case STMF_ERROR_VE_CONFLICT:
708 (void) fprintf(stderr, "%s: %s\n", cmdName,
709 gettext("view entry exists"));
710 ret++;
711 break;
712 case STMF_ERROR_CONFIG_NONE:
713 (void) fprintf(stderr, "%s: %s\n", cmdName,
714 gettext("STMF service is not initialized"));
715 ret++;
716 break;
717 case STMF_ERROR_SERVICE_DATA_VERSION:
718 (void) fprintf(stderr, "%s: %s\n", cmdName,
719 gettext("STMF service version incorrect"));
720 ret++;
721 break;
722 case STMF_ERROR_INVALID_HG:
723 (void) fprintf(stderr, "%s: %s\n", cmdName,
724 gettext("invalid host group"));
725 ret++;
726 break;
727 case STMF_ERROR_INVALID_TG:
728 (void) fprintf(stderr, "%s: %s\n", cmdName,
729 gettext("invalid target group"));
730 ret++;
731 break;
732 default:
733 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
734 operands[0], gettext("unknown error"));
735 ret++;
736 break;
737 }
738
739 return (ret);
740 }
741
742 /*
743 * createHostGroupFunc
744 *
745 * Create a host group
746 *
747 */
748 /*ARGSUSED*/
749 static int
750 createHostGroupFunc(int operandLen, char *operands[],
751 cmdOptions_t *options, void *args)
752 {
753 int ret = 0;
754 int stmfRet;
755 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
756 stmfGroupName groupName = {0};
757
758 (void) strlcpy(groupName, operands[0], sizeof (groupName));
759 (void) mbstowcs(groupNamePrint, (char *)groupName,
760 sizeof (stmfGroupName) - 1);
761 /* call create group */
762 stmfRet = stmfCreateHostGroup(&groupName);
763 switch (stmfRet) {
764 case STMF_STATUS_SUCCESS:
765 break;
766 case STMF_ERROR_EXISTS:
767 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
768 operands[0], gettext("already exists"));
769 ret++;
770 break;
771 case STMF_ERROR_BUSY:
772 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
773 operands[0], gettext("resource busy"));
774 ret++;
775 break;
776 case STMF_ERROR_SERVICE_NOT_FOUND:
777 (void) fprintf(stderr, "%s: %s\n", cmdName,
778 gettext("STMF service not found"));
779 ret++;
780 break;
781 case STMF_ERROR_PERM:
782 (void) fprintf(stderr, "%s: %s\n", cmdName,
783 gettext("permission denied"));
784 ret++;
785 break;
786 case STMF_ERROR_SERVICE_DATA_VERSION:
787 (void) fprintf(stderr, "%s: %s\n", cmdName,
788 gettext("STMF service version incorrect"));
789 ret++;
790 break;
791 default:
792 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
793 operands[0], gettext("unknown error"));
794 ret++;
795 break;
796 }
797
798 return (ret);
799 }
800
801 /*
802 * createLuFunc
803 *
804 * Create a logical unit
805 *
806 */
807 /*ARGSUSED*/
808 static int
809 createLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
810 void *args)
811 {
812 luResource hdl = NULL;
813 int ret = 0;
814 int stmfRet = 0;
815 char guidAsciiBuf[33];
816 stmfGuid createdGuid;
817
818 stmfRet = stmfCreateLuResource(STMF_DISK, &hdl);
819
820 if (stmfRet != STMF_STATUS_SUCCESS) {
821 (void) fprintf(stderr, "%s: %s\n",
822 cmdName, gettext("Failure to create lu resource\n"));
823 return (1);
824 }
825
826 for (; options->optval; options++) {
827 switch (options->optval) {
828 case 'p':
829 ret = setLuPropFromInput(hdl, options->optarg);
830 if (ret != 0) {
831 (void) stmfFreeLuResource(hdl);
832 return (1);
833 }
834 break;
835 case 's':
836 stmfRet = stmfSetLuProp(hdl, STMF_LU_PROP_SIZE,
837 options->optarg);
838 if (stmfRet != STMF_STATUS_SUCCESS) {
839 (void) fprintf(stderr, "%s: %c: %s\n",
840 cmdName, options->optval,
841 gettext("size param invalid"));
842 (void) stmfFreeLuResource(hdl);
843 return (1);
844 }
845 break;
846 default:
847 (void) fprintf(stderr, "%s: %c: %s\n",
848 cmdName, options->optval,
849 gettext("unknown option"));
850 return (1);
851 }
852 }
853
854 stmfRet = stmfSetLuProp(hdl, STMF_LU_PROP_FILENAME, operands[0]);
855
856 if (stmfRet != STMF_STATUS_SUCCESS) {
857 (void) fprintf(stderr, "%s: %s\n",
858 cmdName, gettext("could not set filename"));
859 return (1);
860 }
861
862 stmfRet = stmfCreateLu(hdl, &createdGuid);
863 switch (stmfRet) {
864 case STMF_STATUS_SUCCESS:
865 break;
866 case STMF_ERROR_BUSY:
867 case STMF_ERROR_LU_BUSY:
868 (void) fprintf(stderr, "%s: %s\n", cmdName,
869 gettext("resource busy"));
870 ret++;
871 break;
872 case STMF_ERROR_PERM:
873 (void) fprintf(stderr, "%s: %s\n", cmdName,
874 gettext("permission denied"));
875 ret++;
876 break;
877 case STMF_ERROR_FILE_IN_USE:
878 (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName,
879 operands[0], gettext("in use"));
880 ret++;
881 break;
882 case STMF_ERROR_INVALID_BLKSIZE:
883 (void) fprintf(stderr, "%s: %s\n", cmdName,
884 gettext("invalid block size"));
885 ret++;
886 break;
887 case STMF_ERROR_GUID_IN_USE:
888 (void) fprintf(stderr, "%s: %s\n", cmdName,
889 gettext("guid in use"));
890 ret++;
891 break;
892 case STMF_ERROR_META_FILE_NAME:
893 (void) fprintf(stderr, "%s: %s\n", cmdName,
894 gettext("meta file error"));
895 ret++;
896 break;
897 case STMF_ERROR_DATA_FILE_NAME:
898 (void) fprintf(stderr, "%s: %s\n", cmdName,
899 gettext("data file error"));
900 ret++;
901 break;
902 case STMF_ERROR_FILE_SIZE_INVALID:
903 (void) fprintf(stderr, "%s: %s\n", cmdName,
904 gettext("file size invalid"));
905 ret++;
906 break;
907 case STMF_ERROR_SIZE_OUT_OF_RANGE:
908 (void) fprintf(stderr, "%s: %s\n", cmdName,
909 gettext("invalid size"));
910 ret++;
911 break;
912 case STMF_ERROR_META_CREATION:
913 (void) fprintf(stderr, "%s: %s\n", cmdName,
914 gettext("could not create meta file"));
915 ret++;
916 break;
917 case STMF_ERROR_WRITE_CACHE_SET:
918 (void) fprintf(stderr, "%s: %s\n", cmdName,
919 gettext("could not set write cache"));
920 ret++;
921 break;
922 default:
923 (void) fprintf(stderr, "%s: %s\n", cmdName,
924 gettext("unknown error"));
925 ret++;
926 break;
927 }
928
929 if (ret != 0) {
930 goto done;
931 }
932
933 (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
934 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
935 "%02X%02X%02X%02X%02X%02X",
936 createdGuid.guid[0], createdGuid.guid[1], createdGuid.guid[2],
937 createdGuid.guid[3], createdGuid.guid[4], createdGuid.guid[5],
938 createdGuid.guid[6], createdGuid.guid[7], createdGuid.guid[8],
939 createdGuid.guid[9], createdGuid.guid[10], createdGuid.guid[11],
940 createdGuid.guid[12], createdGuid.guid[13], createdGuid.guid[14],
941 createdGuid.guid[15]);
942 (void) printf("Logical unit created: %s\n", guidAsciiBuf);
943
944 done:
945 (void) stmfFreeLuResource(hdl);
946 return (ret);
947 }
948
949 /*
950 * createLuFunc
951 *
952 * Create a logical unit
953 *
954 */
955 /*ARGSUSED*/
956 static int
957 modifyLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
958 void *args)
959 {
960 stmfGuid inGuid;
961 unsigned int guid[sizeof (stmfGuid)];
962 int ret = 0;
963 int i;
964 char *fname = NULL;
965 char *lasts = NULL;
966 char sGuid[GUID_INPUT + 1];
967 char *prop = NULL;
968 char *propVal = NULL;
969 boolean_t fnameUsed = B_FALSE;
970 uint32_t propId;
971 cmdOptions_t *optionStart = options;
972
973
974 for (; options->optval; options++) {
975 switch (options->optval) {
976 case 'f':
977 fnameUsed = B_TRUE;
978 fname = operands[0];
979 break;
980 }
981 }
982 options = optionStart;
983
984 /* check input length */
985 if (!fnameUsed && strlen(operands[0]) != GUID_INPUT) {
986 (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0],
987 gettext("must be "), GUID_INPUT,
988 gettext(" hexadecimal digits"));
989 return (1);
990 }
991
992 if (!fnameUsed) {
993 /* convert to lower case for scan */
994 for (i = 0; i < 32; i++)
995 sGuid[i] = tolower(operands[0][i]);
996 sGuid[i] = 0;
997 (void) sscanf(sGuid,
998 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
999 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
1000 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10],
1001 &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]);
1002
1003 for (i = 0; i < sizeof (stmfGuid); i++) {
1004 inGuid.guid[i] = guid[i];
1005 }
1006 }
1007
1008 for (; options->optval; options++) {
1009 switch (options->optval) {
1010 case 'p':
1011 prop = strtok_r(options->optarg, "=", &lasts);
1012 propVal = strtok_r(NULL, "=", &lasts);
1013 ret = convertCharToPropId(prop, &propId);
1014 if (ret != 0) {
1015 (void) fprintf(stderr, "%s: %s: %s\n",
1016 cmdName,
1017 gettext("invalid property specified"),
1018 prop);
1019 return (1);
1020 }
1021 if (propVal == NULL &&
1022 propId != STMF_LU_PROP_MGMT_URL) {
1023 (void) fprintf(stderr, "%s: %s: %s\n",
1024 cmdName, options->optarg,
1025 gettext("invalid property specifier"
1026 "- prop=val\n"));
1027 return (1);
1028 }
1029 if (propVal == NULL) {
1030 ret = callModify(fname, &inGuid, propId,
1031 "", prop);
1032 } else {
1033 ret = callModify(fname, &inGuid, propId,
1034 propVal, prop);
1035 }
1036 if (ret != 0) {
1037 return (1);
1038 }
1039 break;
1040 case 's':
1041 if (callModify(fname, &inGuid,
1042 STMF_LU_PROP_SIZE, options->optarg,
1043 "size") != 0) {
1044 return (1);
1045 }
1046 break;
1047 case 'f':
1048 break;
1049 default:
1050 (void) fprintf(stderr, "%s: %c: %s\n",
1051 cmdName, options->optval,
1052 gettext("unknown option"));
1053 return (1);
1054 }
1055 }
1056 return (ret);
1057 }
1058
1059 static int
1060 callModify(char *fname, stmfGuid *luGuid, uint32_t prop, const char *propVal,
1061 const char *propString)
1062 {
1063 int ret = 0;
1064 int stmfRet = 0;
1065
1066 if (!fname) {
1067 stmfRet = stmfModifyLu(luGuid, prop, propVal);
1068 } else {
1069 stmfRet = stmfModifyLuByFname(STMF_DISK, fname, prop,
1070 propVal);
1071 }
1072 switch (stmfRet) {
1073 case STMF_STATUS_SUCCESS:
1074 break;
1075 case STMF_ERROR_BUSY:
1076 case STMF_ERROR_LU_BUSY:
1077 (void) fprintf(stderr, "%s: %s\n", cmdName,
1078 gettext("resource busy"));
1079 ret++;
1080 break;
1081 case STMF_ERROR_PERM:
1082 (void) fprintf(stderr, "%s: %s\n", cmdName,
1083 gettext("permission denied"));
1084 ret++;
1085 break;
1086 case STMF_ERROR_INVALID_BLKSIZE:
1087 (void) fprintf(stderr, "%s: %s\n", cmdName,
1088 gettext("invalid block size"));
1089 ret++;
1090 break;
1091 case STMF_ERROR_GUID_IN_USE:
1092 (void) fprintf(stderr, "%s: %s\n", cmdName,
1093 gettext("guid in use"));
1094 ret++;
1095 break;
1096 case STMF_ERROR_META_FILE_NAME:
1097 (void) fprintf(stderr, "%s: %s\n", cmdName,
1098 gettext("meta file error"));
1099 ret++;
1100 break;
1101 case STMF_ERROR_DATA_FILE_NAME:
1102 (void) fprintf(stderr, "%s: %s\n", cmdName,
1103 gettext("data file error"));
1104 ret++;
1105 break;
1106 case STMF_ERROR_FILE_SIZE_INVALID:
1107 (void) fprintf(stderr, "%s: %s\n", cmdName,
1108 gettext("file size invalid"));
1109 ret++;
1110 break;
1111 case STMF_ERROR_SIZE_OUT_OF_RANGE:
1112 (void) fprintf(stderr, "%s: %s\n", cmdName,
1113 gettext("invalid size"));
1114 ret++;
1115 break;
1116 case STMF_ERROR_META_CREATION:
1117 (void) fprintf(stderr, "%s: %s\n", cmdName,
1118 gettext("could not create meta file"));
1119 ret++;
1120 break;
1121 case STMF_ERROR_INVALID_PROP:
1122 (void) fprintf(stderr, "%s: %s\n", cmdName,
1123 gettext("invalid property for modify"));
1124 ret++;
1125 break;
1126 case STMF_ERROR_WRITE_CACHE_SET:
1127 (void) fprintf(stderr, "%s: %s\n", cmdName,
1128 gettext("could not set write cache"));
1129 ret++;
1130 break;
1131 case STMF_ERROR_ACCESS_STATE_SET:
1132 (void) fprintf(stderr, "%s: %s\n", cmdName,
1133 gettext("cannot modify while in standby mode"));
1134 ret++;
1135 break;
1136 default:
1137 (void) fprintf(stderr, "%s: %s: %s: %d\n", cmdName,
1138 gettext("could not set property"), propString,
1139 stmfRet);
1140 ret++;
1141 break;
1142 }
1143
1144 return (ret);
1145 }
1146
1147
1148 /*
1149 * importLuFunc
1150 *
1151 * Create a logical unit
1152 *
1153 */
1154 /*ARGSUSED*/
1155 static int
1156 importLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
1157 void *args)
1158 {
1159 int stmfRet = 0;
1160 int ret = 0;
1161 char guidAsciiBuf[33];
1162 stmfGuid createdGuid;
1163
1164 stmfRet = stmfImportLu(STMF_DISK, operands[0], &createdGuid);
1165 switch (stmfRet) {
1166 case STMF_STATUS_SUCCESS:
1167 break;
1168 case STMF_ERROR_BUSY:
1169 case STMF_ERROR_LU_BUSY:
1170 (void) fprintf(stderr, "%s: %s\n", cmdName,
1171 gettext("resource busy"));
1172 ret++;
1173 break;
1174 case STMF_ERROR_PERM:
1175 (void) fprintf(stderr, "%s: %s\n", cmdName,
1176 gettext("permission denied"));
1177 ret++;
1178 break;
1179 case STMF_ERROR_FILE_IN_USE:
1180 (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName,
1181 operands[0], gettext("in use"));
1182 ret++;
1183 break;
1184 case STMF_ERROR_GUID_IN_USE:
1185 (void) fprintf(stderr, "%s: %s\n", cmdName,
1186 gettext("guid in use"));
1187 ret++;
1188 break;
1189 case STMF_ERROR_META_FILE_NAME:
1190 (void) fprintf(stderr, "%s: %s\n", cmdName,
1191 gettext("meta file error"));
1192 ret++;
1193 break;
1194 case STMF_ERROR_DATA_FILE_NAME:
1195 (void) fprintf(stderr, "%s: %s\n", cmdName,
1196 gettext("data file error"));
1197 ret++;
1198 break;
1199 case STMF_ERROR_META_CREATION:
1200 (void) fprintf(stderr, "%s: %s\n", cmdName,
1201 gettext("could not create meta file"));
1202 ret++;
1203 break;
1204 case STMF_ERROR_WRITE_CACHE_SET:
1205 (void) fprintf(stderr, "%s: %s\n", cmdName,
1206 gettext("could not set write cache"));
1207 ret++;
1208 break;
1209 default:
1210 (void) fprintf(stderr, "%s: %s\n", cmdName,
1211 gettext("unknown error"));
1212 ret++;
1213 break;
1214 }
1215
1216 if (ret != STMF_STATUS_SUCCESS) {
1217 goto done;
1218 }
1219
1220 (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
1221 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
1222 "%02X%02X%02X%02X%02X%02X",
1223 createdGuid.guid[0], createdGuid.guid[1], createdGuid.guid[2],
1224 createdGuid.guid[3], createdGuid.guid[4], createdGuid.guid[5],
1225 createdGuid.guid[6], createdGuid.guid[7], createdGuid.guid[8],
1226 createdGuid.guid[9], createdGuid.guid[10], createdGuid.guid[11],
1227 createdGuid.guid[12], createdGuid.guid[13], createdGuid.guid[14],
1228 createdGuid.guid[15]);
1229 (void) printf("Logical unit imported: %s\n", guidAsciiBuf);
1230
1231 done:
1232 return (ret);
1233 }
1234
1235 static int
1236 setLuPropFromInput(luResource hdl, char *optarg)
1237 {
1238 char *prop = NULL;
1239 char *propVal = NULL;
1240 char *lasts = NULL;
1241 uint32_t propId;
1242 int ret = 0;
1243
1244 prop = strtok_r(optarg, "=", &lasts);
1245 if ((propVal = strtok_r(NULL, "=", &lasts)) == NULL) {
1246 (void) fprintf(stderr, "%s: %s: %s\n",
1247 cmdName, optarg,
1248 gettext("invalid property specifier - prop=val\n"));
1249 return (1);
1250 }
1251
1252 ret = convertCharToPropId(prop, &propId);
1253 if (ret != 0) {
1254 (void) fprintf(stderr, "%s: %s: %s\n",
1255 cmdName, gettext("invalid property specified"), prop);
1256 return (1);
1257 }
1258
1259 ret = stmfSetLuProp(hdl, propId, propVal);
1260 if (ret != STMF_STATUS_SUCCESS) {
1261 (void) fprintf(stderr, "%s: %s %s: ",
1262 cmdName, gettext("unable to set"), prop);
1263 switch (ret) {
1264 case STMF_ERROR_INVALID_PROPSIZE:
1265 (void) fprintf(stderr, "invalid length\n");
1266 break;
1267 case STMF_ERROR_INVALID_ARG:
1268 (void) fprintf(stderr, "bad format\n");
1269 break;
1270 default:
1271 (void) fprintf(stderr, "\n");
1272 break;
1273 }
1274 return (1);
1275 }
1276
1277 return (0);
1278 }
1279
1280 static int
1281 convertCharToPropId(char *prop, uint32_t *propId)
1282 {
1283 if (strcasecmp(prop, GUID) == 0) {
1284 *propId = STMF_LU_PROP_GUID;
1285 } else if (strcasecmp(prop, ALIAS) == 0) {
1286 *propId = STMF_LU_PROP_ALIAS;
1287 } else if (strcasecmp(prop, VID) == 0) {
1288 *propId = STMF_LU_PROP_VID;
1289 } else if (strcasecmp(prop, PID) == 0) {
1290 *propId = STMF_LU_PROP_PID;
1291 } else if (strcasecmp(prop, WRITE_PROTECT) == 0) {
1292 *propId = STMF_LU_PROP_WRITE_PROTECT;
1293 } else if (strcasecmp(prop, WRITEBACK_CACHE_DISABLE) == 0) {
1294 *propId = STMF_LU_PROP_WRITE_CACHE_DISABLE;
1295 } else if (strcasecmp(prop, BLOCK_SIZE) == 0) {
1296 *propId = STMF_LU_PROP_BLOCK_SIZE;
1297 } else if (strcasecmp(prop, SERIAL_NUMBER) == 0) {
1298 *propId = STMF_LU_PROP_SERIAL_NUM;
1299 } else if (strcasecmp(prop, COMPANY_ID) == 0) {
1300 *propId = STMF_LU_PROP_COMPANY_ID;
1301 } else if (strcasecmp(prop, META_FILE) == 0) {
1302 *propId = STMF_LU_PROP_META_FILENAME;
1303 } else if (strcasecmp(prop, MGMT_URL) == 0) {
1304 *propId = STMF_LU_PROP_MGMT_URL;
1305 } else if (strcasecmp(prop, HOST_ID) == 0) {
1306 *propId = STMF_LU_PROP_HOST_ID;
1307 } else {
1308 return (1);
1309 }
1310 return (0);
1311 }
1312
1313 /*
1314 * deleteLuFunc
1315 *
1316 * Delete a logical unit
1317 *
1318 */
1319 /*ARGSUSED*/
1320 static int
1321 deleteLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
1322 void *args)
1323 {
1324 int i, j;
1325 int ret = 0;
1326 int stmfRet;
1327 unsigned int inGuid[sizeof (stmfGuid)];
1328 stmfGuid delGuid;
1329 boolean_t keepViews = B_FALSE;
1330 boolean_t viewEntriesRemoved = B_FALSE;
1331 boolean_t noLunFound = B_FALSE;
1332 boolean_t views = B_FALSE;
1333 boolean_t notValidHexNumber = B_FALSE;
1334 char sGuid[GUID_INPUT + 1];
1335 stmfViewEntryList *viewEntryList = NULL;
1336
1337 for (; options->optval; options++) {
1338 switch (options->optval) {
1339 /* Keep views for logical unit */
1340 case 'k':
1341 keepViews = B_TRUE;
1342 break;
1343 default:
1344 (void) fprintf(stderr, "%s: %c: %s\n",
1345 cmdName, options->optval,
1346 gettext("unknown option"));
1347 return (1);
1348 }
1349 }
1350
1351
1352 for (i = 0; i < operandLen; i++) {
1353 for (j = 0; j < GUID_INPUT; j++) {
1354 if (!isxdigit(operands[i][j])) {
1355 notValidHexNumber = B_TRUE;
1356 break;
1357 }
1358 sGuid[j] = tolower(operands[i][j]);
1359 }
1360 if ((notValidHexNumber == B_TRUE) ||
1361 (strlen(operands[i]) != GUID_INPUT)) {
1362 (void) fprintf(stderr, "%s: %s: %s%d%s\n",
1363 cmdName, operands[i], gettext("must be "),
1364 GUID_INPUT,
1365 gettext(" hexadecimal digits long"));
1366 notValidHexNumber = B_FALSE;
1367 ret++;
1368 continue;
1369 }
1370
1371 sGuid[j] = 0;
1372
1373 (void) sscanf(sGuid,
1374 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
1375 &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3],
1376 &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7],
1377 &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11],
1378 &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]);
1379
1380 for (j = 0; j < sizeof (stmfGuid); j++) {
1381 delGuid.guid[j] = inGuid[j];
1382 }
1383
1384 stmfRet = stmfDeleteLu(&delGuid);
1385 switch (stmfRet) {
1386 case STMF_STATUS_SUCCESS:
1387 break;
1388 case STMF_ERROR_NOT_FOUND:
1389 noLunFound = B_TRUE;
1390 break;
1391 case STMF_ERROR_BUSY:
1392 (void) fprintf(stderr, "%s: %s\n", cmdName,
1393 gettext("resource busy"));
1394 ret++;
1395 break;
1396 case STMF_ERROR_PERM:
1397 (void) fprintf(stderr, "%s: %s\n", cmdName,
1398 gettext("permission denied"));
1399 ret++;
1400 break;
1401 default:
1402 (void) fprintf(stderr, "%s: %s\n", cmdName,
1403 gettext("unknown error"));
1404 ret++;
1405 break;
1406 }
1407
1408 if (!keepViews) {
1409 stmfRet = stmfGetViewEntryList(&delGuid,
1410 &viewEntryList);
1411 if (stmfRet == STMF_STATUS_SUCCESS) {
1412 for (j = 0; j < viewEntryList->cnt; j++) {
1413 (void) stmfRemoveViewEntry(&delGuid,
1414 viewEntryList->ve[j].veIndex);
1415 }
1416 /* check if viewEntryList is empty */
1417 if (viewEntryList->cnt != 0)
1418 viewEntriesRemoved = B_TRUE;
1419 stmfFreeMemory(viewEntryList);
1420 } else {
1421 (void) fprintf(stderr, "%s: %s\n", cmdName,
1422 gettext("unable to remove view entries\n"));
1423 ret++;
1424 }
1425
1426 }
1427 if (keepViews) {
1428 stmfRet = stmfGetViewEntryList(&delGuid,
1429 &viewEntryList);
1430 if (stmfRet == STMF_STATUS_SUCCESS) {
1431 views = B_TRUE;
1432 stmfFreeMemory(viewEntryList);
1433 }
1434 }
1435
1436 if ((!viewEntriesRemoved && noLunFound && !views) ||
1437 (!views && keepViews && noLunFound)) {
1438 (void) fprintf(stderr, "%s: %s: %s\n",
1439 cmdName, sGuid,
1440 gettext("not found"));
1441 ret++;
1442 }
1443 noLunFound = viewEntriesRemoved = views = B_FALSE;
1444 }
1445 return (ret);
1446 }
1447
1448
1449 /*
1450 * createTargetGroupFunc
1451 *
1452 * Create a target group
1453 *
1454 */
1455 /*ARGSUSED*/
1456 static int
1457 createTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options,
1458 void *args)
1459 {
1460 int ret = 0;
1461 int stmfRet;
1462 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
1463 stmfGroupName groupName = {0};
1464
1465 (void) strlcpy(groupName, operands[0], sizeof (groupName));
1466 (void) mbstowcs(groupNamePrint, (char *)groupName,
1467 sizeof (stmfGroupName) - 1);
1468 /* call create group */
1469 stmfRet = stmfCreateTargetGroup(&groupName);
1470 switch (stmfRet) {
1471 case STMF_STATUS_SUCCESS:
1472 break;
1473 case STMF_ERROR_EXISTS:
1474 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1475 groupNamePrint, gettext("already exists"));
1476 ret++;
1477 break;
1478 case STMF_ERROR_BUSY:
1479 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1480 groupNamePrint, gettext("resource busy"));
1481 ret++;
1482 break;
1483 case STMF_ERROR_PERM:
1484 (void) fprintf(stderr, "%s: %s\n", cmdName,
1485 gettext("permission denied"));
1486 ret++;
1487 break;
1488 case STMF_ERROR_SERVICE_NOT_FOUND:
1489 (void) fprintf(stderr, "%s: %s\n", cmdName,
1490 gettext("STMF service not found"));
1491 ret++;
1492 break;
1493 case STMF_ERROR_SERVICE_DATA_VERSION:
1494 (void) fprintf(stderr, "%s: %s\n", cmdName,
1495 gettext("STMF service version incorrect"));
1496 ret++;
1497 break;
1498 default:
1499 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1500 groupNamePrint, gettext("unknown error"));
1501 ret++;
1502 break;
1503 }
1504
1505 return (ret);
1506 }
1507
1508 /*
1509 * deleteHostGroupFunc
1510 *
1511 * Delete a host group
1512 *
1513 */
1514 /*ARGSUSED*/
1515 static int
1516 deleteHostGroupFunc(int operandLen, char *operands[],
1517 cmdOptions_t *options, void *args)
1518 {
1519 int ret = 0;
1520 int stmfRet;
1521 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
1522 stmfGroupName groupName = {0};
1523
1524 (void) strlcpy(groupName, operands[0], sizeof (groupName));
1525 (void) mbstowcs(groupNamePrint, (char *)groupName,
1526 sizeof (stmfGroupName) - 1);
1527 /* call delete group */
1528 stmfRet = stmfDeleteHostGroup(&groupName);
1529 switch (stmfRet) {
1530 case STMF_STATUS_SUCCESS:
1531 break;
1532 case STMF_ERROR_NOT_FOUND:
1533 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1534 groupNamePrint, gettext("not found"));
1535 ret++;
1536 break;
1537 case STMF_ERROR_BUSY:
1538 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1539 groupNamePrint, gettext("resource busy"));
1540 ret++;
1541 break;
1542 case STMF_ERROR_SERVICE_NOT_FOUND:
1543 (void) fprintf(stderr, "%s: %s\n", cmdName,
1544 gettext("STMF service not found"));
1545 ret++;
1546 break;
1547 case STMF_ERROR_PERM:
1548 (void) fprintf(stderr, "%s: %s\n", cmdName,
1549 gettext("permission denied"));
1550 ret++;
1551 break;
1552 case STMF_ERROR_GROUP_IN_USE:
1553 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1554 groupNamePrint,
1555 gettext("group is in use by existing view entry"));
1556 ret++;
1557 break;
1558 case STMF_ERROR_SERVICE_DATA_VERSION:
1559 (void) fprintf(stderr, "%s: %s\n", cmdName,
1560 gettext("STMF service version incorrect"));
1561 ret++;
1562 break;
1563 default:
1564 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1565 groupNamePrint, gettext("unknown error"));
1566 ret++;
1567 break;
1568 }
1569
1570 return (ret);
1571 }
1572
1573 /*
1574 * deleteTargetGroupFunc
1575 *
1576 * Delete a target group
1577 *
1578 */
1579 /*ARGSUSED*/
1580 static int
1581 deleteTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options,
1582 void *args)
1583 {
1584 int ret = 0;
1585 int stmfRet;
1586 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
1587 stmfGroupName groupName = {0};
1588
1589 (void) strlcpy(groupName, operands[0], sizeof (groupName));
1590 (void) mbstowcs(groupNamePrint, (char *)groupName,
1591 sizeof (stmfGroupName) - 1);
1592 /* call delete group */
1593 stmfRet = stmfDeleteTargetGroup(&groupName);
1594 switch (stmfRet) {
1595 case STMF_STATUS_SUCCESS:
1596 break;
1597 case STMF_ERROR_NOT_FOUND:
1598 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1599 groupNamePrint, gettext("not found"));
1600 ret++;
1601 break;
1602 case STMF_ERROR_BUSY:
1603 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1604 groupNamePrint, gettext("resource busy"));
1605 ret++;
1606 break;
1607 case STMF_ERROR_SERVICE_NOT_FOUND:
1608 (void) fprintf(stderr, "%s: %s\n", cmdName,
1609 gettext("STMF service not found"));
1610 ret++;
1611 break;
1612 case STMF_ERROR_PERM:
1613 (void) fprintf(stderr, "%s: %s\n", cmdName,
1614 gettext("permission denied"));
1615 ret++;
1616 break;
1617 case STMF_ERROR_GROUP_IN_USE:
1618 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1619 groupNamePrint,
1620 gettext("group is in use by existing view entry"));
1621 ret++;
1622 break;
1623 case STMF_ERROR_SERVICE_DATA_VERSION:
1624 (void) fprintf(stderr, "%s: %s\n", cmdName,
1625 gettext("STMF service version incorrect"));
1626 ret++;
1627 break;
1628 default:
1629 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
1630 groupNamePrint, gettext("unknown error"));
1631 ret++;
1632 break;
1633 }
1634
1635 return (ret);
1636 }
1637
1638 /*
1639 * listHostGroupFunc
1640 *
1641 * Lists the specified host groups or all if none are specified
1642 *
1643 */
1644 /*ARGSUSED*/
1645 static int
1646 listHostGroupFunc(int operandLen, char *operands[], cmdOptions_t *options,
1647 void *args)
1648 {
1649 int ret = 0;
1650 int stmfRet;
1651 int i, j, outerLoop;
1652 boolean_t verbose = B_FALSE;
1653 boolean_t found = B_TRUE;
1654 boolean_t operandEntered;
1655 stmfGroupList *groupList;
1656 stmfGroupProperties *groupProps;
1657 wchar_t operandName[sizeof (stmfGroupName)];
1658 wchar_t groupNamePrint[sizeof (stmfGroupName)];
1659
1660 for (; options->optval; options++) {
1661 switch (options->optval) {
1662 case 'v':
1663 verbose = B_TRUE;
1664 break;
1665 default:
1666 (void) fprintf(stderr, "%s: %c: %s\n",
1667 cmdName, options->optval,
1668 gettext("unknown option"));
1669 return (1);
1670 }
1671 }
1672
1673 if (operandLen > 0) {
1674 outerLoop = operandLen;
1675 operandEntered = B_TRUE;
1676 } else {
1677 outerLoop = 1;
1678 operandEntered = B_FALSE;
1679 }
1680
1681 stmfRet = stmfGetHostGroupList(&groupList);
1682 if (stmfRet != STMF_STATUS_SUCCESS) {
1683 switch (stmfRet) {
1684 case STMF_ERROR_BUSY:
1685 (void) fprintf(stderr, "%s: %s\n", cmdName,
1686 gettext("resource busy"));
1687 break;
1688 case STMF_ERROR_SERVICE_NOT_FOUND:
1689 (void) fprintf(stderr, "%s: %s\n", cmdName,
1690 gettext("STMF service not found"));
1691 break;
1692 case STMF_ERROR_PERM:
1693 (void) fprintf(stderr, "%s: %s\n", cmdName,
1694 gettext("permission denied"));
1695 break;
1696 case STMF_ERROR_SERVICE_DATA_VERSION:
1697 (void) fprintf(stderr, "%s: %s\n", cmdName,
1698 gettext("STMF service version incorrect"));
1699 break;
1700 default:
1701 (void) fprintf(stderr, "%s: %s\n", cmdName,
1702 gettext("unknown error"));
1703 break;
1704 }
1705 return (1);
1706 }
1707
1708 for (i = 0; i < outerLoop; i++) {
1709 for (found = B_FALSE, j = 0; j < groupList->cnt; j++) {
1710 (void) mbstowcs(groupNamePrint,
1711 (char *)groupList->name[j],
1712 sizeof (stmfGroupName) - 1);
1713 groupNamePrint[sizeof (stmfGroupName) - 1] = 0;
1714 if (operandEntered) {
1715 (void) mbstowcs(operandName, operands[i],
1716 sizeof (stmfGroupName) - 1);
1717 operandName[sizeof (stmfGroupName) - 1] = 0;
1718 if (wcscmp(operandName, groupNamePrint)
1719 == 0) {
1720 found = B_TRUE;
1721 }
1722 }
1723 if ((found && operandEntered) || !operandEntered) {
1724 (void) printf("Host Group: %ws\n",
1725 groupNamePrint);
1726 if (verbose) {
1727 stmfRet = stmfGetHostGroupMembers(
1728 &(groupList->name[j]), &groupProps);
1729 if (stmfRet != STMF_STATUS_SUCCESS) {
1730 return (1);
1731 }
1732 printGroupProps(groupProps);
1733 }
1734 if (found && operandEntered) {
1735 break;
1736 }
1737 }
1738
1739 }
1740 if (operandEntered && !found) {
1741 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
1742 operands[i], gettext("not found"));
1743 ret = 1;
1744 }
1745 }
1746 return (ret);
1747 }
1748
1749 /*
1750 * printGroupProps
1751 *
1752 * Prints group members for target or host groups
1753 *
1754 */
1755 static void
1756 printGroupProps(stmfGroupProperties *groupProps)
1757 {
1758 int i;
1759 wchar_t memberIdent[sizeof (groupProps->name[0].ident) + 1] = {0};
1760
1761
1762 for (i = 0; i < groupProps->cnt; i++) {
1763 (void) mbstowcs(memberIdent, (char *)groupProps->name[i].ident,
1764 sizeof (groupProps->name[0].ident));
1765 (void) printf("\tMember: %ws\n", memberIdent);
1766 }
1767 }
1768
1769 /*
1770 * listTargetGroupFunc
1771 *
1772 * Lists the specified target groups or all if none are specified
1773 *
1774 */
1775 /*ARGSUSED*/
1776 static int
1777 listTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options,
1778 void *args)
1779 {
1780 int ret = 0;
1781 int stmfRet;
1782 int i, j, outerLoop;
1783 boolean_t verbose = B_FALSE;
1784 boolean_t found = B_TRUE;
1785 boolean_t operandEntered;
1786 stmfGroupList *groupList;
1787 stmfGroupProperties *groupProps;
1788 wchar_t operandName[sizeof (stmfGroupName)];
1789 wchar_t groupNamePrint[sizeof (stmfGroupName)];
1790
1791 for (; options->optval; options++) {
1792 switch (options->optval) {
1793 case 'v':
1794 verbose = B_TRUE;
1795 break;
1796 default:
1797 (void) fprintf(stderr, "%s: %c: %s\n",
1798 cmdName, options->optval,
1799 gettext("unknown option"));
1800 return (1);
1801 }
1802 }
1803
1804 if (operandLen > 0) {
1805 outerLoop = operandLen;
1806 operandEntered = B_TRUE;
1807 } else {
1808 outerLoop = 1;
1809 operandEntered = B_FALSE;
1810 }
1811
1812 stmfRet = stmfGetTargetGroupList(&groupList);
1813 if (stmfRet != STMF_STATUS_SUCCESS) {
1814 switch (stmfRet) {
1815 case STMF_ERROR_BUSY:
1816 (void) fprintf(stderr, "%s: %s\n", cmdName,
1817 gettext("resource busy"));
1818 break;
1819 case STMF_ERROR_SERVICE_NOT_FOUND:
1820 (void) fprintf(stderr, "%s: %s\n", cmdName,
1821 gettext("STMF service not found"));
1822 break;
1823 case STMF_ERROR_SERVICE_DATA_VERSION:
1824 (void) fprintf(stderr, "%s: %s\n", cmdName,
1825 gettext("STMF service version incorrect"));
1826 break;
1827 case STMF_ERROR_PERM:
1828 (void) fprintf(stderr, "%s: %s\n", cmdName,
1829 gettext("permission denied"));
1830 break;
1831 default:
1832 (void) fprintf(stderr, "%s: %s\n", cmdName,
1833 gettext("unknown error"));
1834 break;
1835 }
1836 return (1);
1837 }
1838
1839 for (i = 0; i < outerLoop; i++) {
1840 for (found = B_FALSE, j = 0; j < groupList->cnt; j++) {
1841 (void) mbstowcs(groupNamePrint,
1842 (char *)groupList->name[j],
1843 sizeof (stmfGroupName) - 1);
1844 groupNamePrint[sizeof (stmfGroupName) - 1] = 0;
1845 if (operandEntered) {
1846 (void) mbstowcs(operandName, operands[i],
1847 sizeof (stmfGroupName) - 1);
1848 operandName[sizeof (stmfGroupName) - 1] = 0;
1849 if (wcscmp(operandName, groupNamePrint)
1850 == 0) {
1851 found = B_TRUE;
1852 }
1853 }
1854 if ((found && operandEntered) || !operandEntered) {
1855 (void) printf("Target Group: %ws\n",
1856 groupNamePrint);
1857 if (verbose) {
1858 stmfRet = stmfGetTargetGroupMembers(
1859 &(groupList->name[j]), &groupProps);
1860 if (stmfRet != STMF_STATUS_SUCCESS) {
1861 return (1);
1862 }
1863 printGroupProps(groupProps);
1864 }
1865 if (found && operandEntered) {
1866 break;
1867 }
1868 }
1869
1870 }
1871 if (operandEntered && !found) {
1872 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
1873 operands[i], gettext("not found"));
1874 ret = 1;
1875 }
1876 }
1877 return (ret);
1878 }
1879
1880 /*
1881 * listLuFunc
1882 *
1883 * List the logical units and optionally the properties
1884 *
1885 */
1886 /*ARGSUSED*/
1887 static int
1888 listLuFunc(int operandLen, char *operands[], cmdOptions_t *options, void *args)
1889 {
1890 cmdOptions_t *optionList = options;
1891 boolean_t operandEntered;
1892 int i, j;
1893 int ret = 0;
1894 int stmfRet;
1895 int outerLoop;
1896 unsigned int inGuid[sizeof (stmfGuid)];
1897 stmfGuid cmpGuid;
1898 boolean_t verbose = B_FALSE;
1899 boolean_t found;
1900 char sGuid[GUID_INPUT + 1];
1901 stmfGuidList *luList;
1902 stmfLogicalUnitProperties luProps;
1903 boolean_t invalidInput = B_FALSE;
1904 stmfViewEntryList *viewEntryList;
1905
1906 for (; optionList->optval; optionList++) {
1907 switch (optionList->optval) {
1908 case 'v':
1909 verbose = B_TRUE;
1910 break;
1911 }
1912 }
1913
1914 if ((stmfRet = stmfGetLogicalUnitList(&luList))
1915 != STMF_STATUS_SUCCESS) {
1916 switch (stmfRet) {
1917 case STMF_ERROR_SERVICE_NOT_FOUND:
1918 (void) fprintf(stderr, "%s: %s\n", cmdName,
1919 gettext("STMF service not found"));
1920 break;
1921 case STMF_ERROR_BUSY:
1922 (void) fprintf(stderr, "%s: %s\n", cmdName,
1923 gettext("resource busy"));
1924 break;
1925 case STMF_ERROR_PERM:
1926 (void) fprintf(stderr, "%s: %s\n", cmdName,
1927 gettext("permission denied"));
1928 break;
1929 case STMF_ERROR_SERVICE_DATA_VERSION:
1930 (void) fprintf(stderr, "%s: %s\n", cmdName,
1931 gettext("STMF service version incorrect"));
1932 break;
1933 default:
1934 (void) fprintf(stderr, "%s: %s\n", cmdName,
1935 gettext("list failed"));
1936 break;
1937 }
1938 return (1);
1939 }
1940
1941 if (operandLen > 0) {
1942 operandEntered = B_TRUE;
1943 outerLoop = operandLen;
1944 } else {
1945 operandEntered = B_FALSE;
1946 outerLoop = 1;
1947 }
1948
1949
1950 for (invalidInput = B_FALSE, i = 0; i < outerLoop; i++) {
1951 if (operandEntered) {
1952 if (strlen(operands[i]) != GUID_INPUT) {
1953 invalidInput = B_TRUE;
1954 } else {
1955 for (j = 0; j < GUID_INPUT; j++) {
1956 if (!isxdigit(operands[i][j])) {
1957 invalidInput = B_TRUE;
1958 break;
1959 }
1960 }
1961 }
1962 if (invalidInput) {
1963 (void) fprintf(stderr, "%s: %s: %s%d%s\n",
1964 cmdName, operands[i], gettext("must be "),
1965 GUID_INPUT,
1966 gettext(" hexadecimal digits long"));
1967 invalidInput = B_FALSE;
1968 continue;
1969 }
1970
1971 for (j = 0; j < GUID_INPUT; j++) {
1972 sGuid[j] = tolower(operands[i][j]);
1973 }
1974 sGuid[j] = 0;
1975
1976 (void) sscanf(sGuid,
1977 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
1978 &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3],
1979 &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7],
1980 &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11],
1981 &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]);
1982
1983 for (j = 0; j < sizeof (stmfGuid); j++) {
1984 cmpGuid.guid[j] = inGuid[j];
1985 }
1986 }
1987
1988 for (found = B_FALSE, j = 0; j < luList->cnt; j++) {
1989 if (operandEntered) {
1990 if (bcmp(luList->guid[j].guid, cmpGuid.guid,
1991 sizeof (stmfGuid)) == 0) {
1992 found = B_TRUE;
1993 }
1994 }
1995 if ((found && operandEntered) || !operandEntered) {
1996 (void) printf("LU Name: ");
1997 printGuid(&luList->guid[j], stdout);
1998 (void) printf("\n");
1999
2000 if (verbose) {
2001 stmfRet = stmfGetLogicalUnitProperties(
2002 &(luList->guid[j]), &luProps);
2003 if (stmfRet == STMF_STATUS_SUCCESS) {
2004 printLuProps(&luProps);
2005 } else {
2006 (void) fprintf(stderr, "%s:",
2007 cmdName);
2008 printGuid(&luList->guid[j],
2009 stderr);
2010 (void) fprintf(stderr, "%s\n",
2011 gettext(" get properties "
2012 "failed"));
2013 }
2014 stmfRet = stmfGetViewEntryList(
2015 &(luList->guid[j]),
2016 &viewEntryList);
2017 (void) printf(PROPS_FORMAT,
2018 "View Entry Count");
2019 if (stmfRet == STMF_STATUS_SUCCESS) {
2020 (void) printf("%d",
2021 viewEntryList->cnt);
2022 } else {
2023 (void) printf("unknown");
2024 }
2025 (void) printf("\n");
2026 ret = printExtLuProps(
2027 &(luList->guid[j]));
2028 }
2029 if (found && operandEntered) {
2030 break;
2031 }
2032 }
2033
2034 }
2035 if (operandEntered && !found) {
2036 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2037 operands[i], gettext("not found"));
2038 ret = 1;
2039 }
2040 }
2041
2042 return (ret);
2043 }
2044
2045 static void
2046 printGuid(stmfGuid *guid, FILE *stream)
2047 {
2048 int i;
2049 for (i = 0; i < 16; i++) {
2050 (void) fprintf(stream, "%02X", guid->guid[i]);
2051 }
2052 }
2053
2054 static int
2055 printExtLuProps(stmfGuid *guid)
2056 {
2057 int stmfRet;
2058 luResource hdl = NULL;
2059 int ret = 0;
2060 char propVal[MAXNAMELEN];
2061 size_t propValSize = sizeof (propVal);
2062
2063 if ((stmfRet = stmfGetLuResource(guid, &hdl))
2064 != STMF_STATUS_SUCCESS) {
2065 switch (stmfRet) {
2066 case STMF_ERROR_BUSY:
2067 (void) fprintf(stderr, "%s: %s\n", cmdName,
2068 gettext("resource busy"));
2069 break;
2070 case STMF_ERROR_PERM:
2071 (void) fprintf(stderr, "%s: %s\n", cmdName,
2072 gettext("permission denied"));
2073 break;
2074 case STMF_ERROR_NOT_FOUND:
2075 /* No error here */
2076 return (0);
2077 break;
2078 default:
2079 (void) fprintf(stderr, "%s: %s\n", cmdName,
2080 gettext("get extended properties failed"));
2081 break;
2082 }
2083 return (1);
2084 }
2085
2086 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_FILENAME, propVal,
2087 &propValSize);
2088 (void) printf(PROPS_FORMAT, "Data File");
2089 if (stmfRet == STMF_STATUS_SUCCESS) {
2090 (void) printf("%s\n", propVal);
2091 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2092 (void) printf("not set\n");
2093 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2094 (void) printf("prop unavailable in standby\n");
2095 } else {
2096 (void) printf("<error retrieving property>\n");
2097 ret++;
2098 }
2099
2100 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_META_FILENAME, propVal,
2101 &propValSize);
2102 (void) printf(PROPS_FORMAT, "Meta File");
2103 if (stmfRet == STMF_STATUS_SUCCESS) {
2104 (void) printf("%s\n", propVal);
2105 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2106 (void) printf("not set\n");
2107 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2108 (void) printf("prop unavailable in standby\n");
2109 } else {
2110 (void) printf("<error retrieving property>\n");
2111 ret++;
2112 }
2113
2114 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SIZE, propVal,
2115 &propValSize);
2116 (void) printf(PROPS_FORMAT, "Size");
2117 if (stmfRet == STMF_STATUS_SUCCESS) {
2118 (void) printf("%s\n", propVal);
2119 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2120 (void) printf("not set\n");
2121 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2122 (void) printf("prop unavailable in standby\n");
2123 } else {
2124 (void) printf("<error retrieving property>\n");
2125 ret++;
2126 }
2127
2128 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_BLOCK_SIZE, propVal,
2129 &propValSize);
2130 (void) printf(PROPS_FORMAT, "Block Size");
2131 if (stmfRet == STMF_STATUS_SUCCESS) {
2132 (void) printf("%s\n", propVal);
2133 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2134 (void) printf("not set\n");
2135 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2136 (void) printf("prop unavailable in standby\n");
2137 } else {
2138 (void) printf("<error retrieving property>\n");
2139 ret++;
2140 }
2141
2142 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_MGMT_URL, propVal,
2143 &propValSize);
2144 (void) printf(PROPS_FORMAT, "Management URL");
2145 if (stmfRet == STMF_STATUS_SUCCESS) {
2146 (void) printf("%s\n", propVal);
2147 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2148 (void) printf("not set\n");
2149 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2150 (void) printf("prop unavailable in standby\n");
2151 } else {
2152 (void) printf("<error retrieving property>\n");
2153 ret++;
2154 }
2155
2156 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_VID, propVal,
2157 &propValSize);
2158 (void) printf(PROPS_FORMAT, "Vendor ID");
2159 if (stmfRet == STMF_STATUS_SUCCESS) {
2160 (void) printf("%s\n", propVal);
2161 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2162 (void) printf("not set\n");
2163 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2164 (void) printf("prop unavailable in standby\n");
2165 } else {
2166 (void) printf("<error retrieving property>\n");
2167 ret++;
2168 }
2169
2170 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_PID, propVal,
2171 &propValSize);
2172 (void) printf(PROPS_FORMAT, "Product ID");
2173 if (stmfRet == STMF_STATUS_SUCCESS) {
2174 (void) printf("%s\n", propVal);
2175 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2176 (void) printf("not set\n");
2177 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2178 (void) printf("prop unavailable in standby\n");
2179 } else {
2180 (void) printf("<error retrieving property>\n");
2181 ret++;
2182 }
2183
2184 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SERIAL_NUM, propVal,
2185 &propValSize);
2186 (void) printf(PROPS_FORMAT, "Serial Num");
2187 if (stmfRet == STMF_STATUS_SUCCESS) {
2188 (void) printf("%s\n", propVal);
2189 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2190 (void) printf("not set\n");
2191 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2192 (void) printf("prop unavailable in standby\n");
2193 } else {
2194 (void) printf("<error retrieving property>\n");
2195 ret++;
2196 }
2197
2198 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_WRITE_PROTECT, propVal,
2199 &propValSize);
2200 (void) printf(PROPS_FORMAT, "Write Protect");
2201 if (stmfRet == STMF_STATUS_SUCCESS) {
2202 (void) printf("%s\n",
2203 strcasecmp(propVal, "true") ? "Disabled" : "Enabled");
2204 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2205 (void) printf("not set\n");
2206 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2207 (void) printf("prop unavailable in standby\n");
2208 } else {
2209 (void) printf("<error retrieving property>\n");
2210 ret++;
2211 }
2212
2213 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_WRITE_CACHE_DISABLE, propVal,
2214 &propValSize);
2215 (void) printf(PROPS_FORMAT, "Writeback Cache");
2216 if (stmfRet == STMF_STATUS_SUCCESS) {
2217 (void) printf("%s\n",
2218 strcasecmp(propVal, "true") ? "Enabled" : "Disabled");
2219 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2220 (void) printf("not set\n");
2221 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) {
2222 (void) printf("prop unavailable in standby\n");
2223 } else {
2224 (void) printf("<error retrieving property>\n");
2225 ret++;
2226 }
2227
2228 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
2229 &propValSize);
2230 (void) printf(PROPS_FORMAT, "Access State");
2231 if (stmfRet == STMF_STATUS_SUCCESS) {
2232 if (strcmp(propVal, STMF_ACCESS_ACTIVE) == 0) {
2233 (void) printf("%s\n", "Active");
2234 } else if (strcmp(propVal,
2235 STMF_ACCESS_ACTIVE_TO_STANDBY) == 0) {
2236 (void) printf("%s\n", "Active->Standby");
2237 } else if (strcmp(propVal, STMF_ACCESS_STANDBY) == 0) {
2238 (void) printf("%s\n", "Standby");
2239 } else if (strcmp(propVal,
2240 STMF_ACCESS_STANDBY_TO_ACTIVE) == 0) {
2241 (void) printf("%s\n", "Standby->Active");
2242 } else {
2243 (void) printf("%s\n", "Unknown");
2244 }
2245 } else if (stmfRet == STMF_ERROR_NO_PROP) {
2246 (void) printf("not set\n");
2247 } else {
2248 (void) printf("<error retrieving property>\n");
2249 ret++;
2250 }
2251
2252 done:
2253 (void) stmfFreeLuResource(hdl);
2254 return (ret);
2255
2256 }
2257
2258
2259 /*
2260 * printLuProps
2261 *
2262 * Prints the properties for a logical unit
2263 *
2264 */
2265 static void
2266 printLuProps(stmfLogicalUnitProperties *luProps)
2267 {
2268 (void) printf(PROPS_FORMAT, "Operational Status");
2269 switch (luProps->status) {
2270 case STMF_LOGICAL_UNIT_ONLINE:
2271 (void) printf("Online");
2272 break;
2273 case STMF_LOGICAL_UNIT_OFFLINE:
2274 (void) printf("Offline");
2275 break;
2276 case STMF_LOGICAL_UNIT_ONLINING:
2277 (void) printf("Onlining");
2278 break;
2279 case STMF_LOGICAL_UNIT_OFFLINING:
2280 (void) printf("Offlining");
2281 break;
2282 case STMF_LOGICAL_UNIT_UNREGISTERED:
2283 (void) printf("unregistered");
2284 (void) strncpy(luProps->providerName, "unregistered",
2285 sizeof (luProps->providerName));
2286 break;
2287 default:
2288 (void) printf("unknown");
2289 break;
2290 }
2291 (void) printf("\n");
2292 (void) printf(PROPS_FORMAT, "Provider Name");
2293 if (luProps->providerName[0] != 0) {
2294 (void) printf("%s", luProps->providerName);
2295 } else {
2296 (void) printf("unknown");
2297 }
2298 (void) printf("\n");
2299 (void) printf(PROPS_FORMAT, "Alias");
2300 if (luProps->alias[0] != 0) {
2301 (void) printf("%s", luProps->alias);
2302 } else {
2303 (void) printf("-");
2304 }
2305 (void) printf("\n");
2306 }
2307
2308 /*
2309 * printTargetProps
2310 *
2311 * Prints the properties for a target
2312 *
2313 */
2314 static void
2315 printTargetProps(stmfTargetProperties *targetProps)
2316 {
2317 (void) printf(PROPS_FORMAT, "Operational Status");
2318 switch (targetProps->status) {
2319 case STMF_TARGET_PORT_ONLINE:
2320 (void) printf("Online");
2321 break;
2322 case STMF_TARGET_PORT_OFFLINE:
2323 (void) printf("Offline");
2324 break;
2325 case STMF_TARGET_PORT_ONLINING:
2326 (void) printf("Onlining");
2327 break;
2328 case STMF_TARGET_PORT_OFFLINING:
2329 (void) printf("Offlining");
2330 break;
2331 default:
2332 (void) printf("unknown");
2333 break;
2334 }
2335 (void) printf("\n");
2336 (void) printf(PROPS_FORMAT, "Provider Name");
2337 if (targetProps->providerName[0] != 0) {
2338 (void) printf("%s", targetProps->providerName);
2339 }
2340 (void) printf("\n");
2341 (void) printf(PROPS_FORMAT, "Alias");
2342 if (targetProps->alias[0] != 0) {
2343 (void) printf("%s", targetProps->alias);
2344 } else {
2345 (void) printf("-");
2346 }
2347 (void) printf("\n");
2348 (void) printf(PROPS_FORMAT, "Protocol");
2349 switch (targetProps->protocol) {
2350 case STMF_PROTOCOL_FIBRE_CHANNEL:
2351 (void) printf("%s", "Fibre Channel");
2352 break;
2353 case STMF_PROTOCOL_ISCSI:
2354 (void) printf("%s", "iSCSI");
2355 break;
2356 case STMF_PROTOCOL_SRP:
2357 (void) printf("%s", "SRP");
2358 break;
2359 case STMF_PROTOCOL_SAS:
2360 (void) printf("%s", "SAS");
2361 break;
2362 default:
2363 (void) printf("%s", "unknown");
2364 break;
2365 }
2366
2367 (void) printf("\n");
2368 }
2369
2370 /*
2371 * printSessionProps
2372 *
2373 * Prints the session data
2374 *
2375 */
2376 static void
2377 printSessionProps(stmfSessionList *sessionList)
2378 {
2379 int i;
2380 char *cTime;
2381 wchar_t initiator[STMF_IDENT_LENGTH + 1];
2382
2383 (void) printf(PROPS_FORMAT, "Sessions");
2384 (void) printf("%d\n", sessionList->cnt);
2385 for (i = 0; i < sessionList->cnt; i++) {
2386 (void) mbstowcs(initiator,
2387 (char *)sessionList->session[i].initiator.ident,
2388 STMF_IDENT_LENGTH);
2389 initiator[STMF_IDENT_LENGTH] = 0;
2390 (void) printf(LVL3_FORMAT, "Initiator: ");
2391 (void) printf("%ws\n", initiator);
2392 (void) printf(LVL4_FORMAT, "Alias: ");
2393 if (sessionList->session[i].alias[0] != 0) {
2394 (void) printf("%s", sessionList->session[i].alias);
2395 } else {
2396 (void) printf("-");
2397 }
2398 (void) printf("\n");
2399 (void) printf(LVL4_FORMAT, "Logged in since: ");
2400 cTime = ctime(&(sessionList->session[i].creationTime));
2401 if (cTime != NULL) {
2402 (void) printf("%s", cTime);
2403 } else {
2404 (void) printf("unknown\n");
2405 }
2406 }
2407 }
2408
2409 static int
2410 getStmfState(stmfState *state)
2411 {
2412 int ret;
2413
2414 ret = stmfGetState(state);
2415 switch (ret) {
2416 case STMF_STATUS_SUCCESS:
2417 break;
2418 case STMF_ERROR_PERM:
2419 (void) fprintf(stderr, "%s: %s\n", cmdName,
2420 gettext("permission denied"));
2421 break;
2422 case STMF_ERROR_SERVICE_NOT_FOUND:
2423 (void) fprintf(stderr, "%s: %s\n", cmdName,
2424 gettext("STMF service not found"));
2425 break;
2426 case STMF_ERROR_BUSY:
2427 (void) fprintf(stderr, "%s: %s\n", cmdName,
2428 gettext("resource busy"));
2429 break;
2430 case STMF_ERROR_SERVICE_DATA_VERSION:
2431 (void) fprintf(stderr, "%s: %s\n", cmdName,
2432 gettext("STMF service version incorrect"));
2433 break;
2434 default:
2435 (void) fprintf(stderr, "%s: %s: %d\n", cmdName,
2436 gettext("unknown error"), ret);
2437 break;
2438 }
2439 return (ret);
2440 }
2441
2442 /*
2443 * listStateFunc
2444 *
2445 * List the operational and config state of the stmf service
2446 *
2447 */
2448 /*ARGSUSED*/
2449 static int
2450 listStateFunc(int operandLen, char *operands[], cmdOptions_t *options,
2451 void *args)
2452 {
2453 int ret;
2454 stmfState state;
2455 boolean_t aluaEnabled;
2456 uint32_t node;
2457
2458 if ((ret = getStmfState(&state)) != STMF_STATUS_SUCCESS)
2459 return (ret);
2460
2461 (void) printf("%-18s: ", "Operational Status");
2462 switch (state.operationalState) {
2463 case STMF_SERVICE_STATE_ONLINE:
2464 (void) printf("online");
2465 break;
2466 case STMF_SERVICE_STATE_OFFLINE:
2467 (void) printf("offline");
2468 break;
2469 case STMF_SERVICE_STATE_ONLINING:
2470 (void) printf("onlining");
2471 break;
2472 case STMF_SERVICE_STATE_OFFLINING:
2473 (void) printf("offlining");
2474 break;
2475 default:
2476 (void) printf("unknown");
2477 break;
2478 }
2479 (void) printf("\n");
2480 (void) printf("%-18s: ", "Config Status");
2481 switch (state.configState) {
2482 case STMF_CONFIG_STATE_NONE:
2483 (void) printf("uninitialized");
2484 break;
2485 case STMF_CONFIG_STATE_INIT:
2486 (void) printf("initializing");
2487 break;
2488 case STMF_CONFIG_STATE_INIT_DONE:
2489 (void) printf("initialized");
2490 break;
2491 default:
2492 (void) printf("unknown");
2493 break;
2494 }
2495 (void) printf("\n");
2496 ret = stmfGetAluaState(&aluaEnabled, &node);
2497 switch (ret) {
2498 case STMF_STATUS_SUCCESS:
2499 break;
2500 case STMF_ERROR_PERM:
2501 (void) fprintf(stderr, "%s: %s\n", cmdName,
2502 gettext("permission denied"));
2503 break;
2504 case STMF_ERROR_BUSY:
2505 (void) fprintf(stderr, "%s: %s\n", cmdName,
2506 gettext("resource busy"));
2507 break;
2508 default:
2509 (void) fprintf(stderr, "%s: %s: %d\n", cmdName,
2510 gettext("unknown error"), ret);
2511 break;
2512 }
2513 (void) printf("%-18s: ", "ALUA Status");
2514 if (ret == STMF_STATUS_SUCCESS) {
2515 if (aluaEnabled == B_TRUE) {
2516 (void) printf("enabled");
2517 } else {
2518 (void) printf("disabled");
2519 }
2520 } else {
2521 (void) printf("unknown");
2522 }
2523
2524 (void) printf("\n");
2525 (void) printf("%-18s: ", "ALUA Node");
2526 if (ret == STMF_STATUS_SUCCESS) {
2527 (void) printf("%d", node);
2528 } else {
2529 (void) printf("unknown");
2530 }
2531 (void) printf("\n");
2532 return (ret);
2533 }
2534
2535 /*
2536 * listTargetFunc
2537 *
2538 * list the targets and optionally their properties
2539 *
2540 */
2541 /*ARGSUSED*/
2542 static int
2543 listTargetFunc(int operandLen, char *operands[], cmdOptions_t *options,
2544 void *args)
2545 {
2546 cmdOptions_t *optionList = options;
2547 int ret = 0;
2548 int stmfRet;
2549 int i, j;
2550 int outerLoop;
2551 stmfSessionList *sessionList;
2552 stmfDevid devid;
2553 boolean_t operandEntered, found, verbose = B_FALSE;
2554 stmfDevidList *targetList;
2555 wchar_t targetIdent[STMF_IDENT_LENGTH + 1];
2556 stmfTargetProperties targetProps;
2557
2558 if ((stmfRet = stmfGetTargetList(&targetList)) != STMF_STATUS_SUCCESS) {
2559 switch (stmfRet) {
2560 case STMF_ERROR_NOT_FOUND:
2561 ret = 0;
2562 break;
2563 case STMF_ERROR_SERVICE_OFFLINE:
2564 (void) fprintf(stderr, "%s: %s\n", cmdName,
2565 gettext("STMF service offline"));
2566 break;
2567 case STMF_ERROR_BUSY:
2568 (void) fprintf(stderr, "%s: %s\n", cmdName,
2569 gettext("resource busy"));
2570 break;
2571 case STMF_ERROR_SERVICE_DATA_VERSION:
2572 (void) fprintf(stderr, "%s: %s\n", cmdName,
2573 gettext("STMF service version incorrect"));
2574 break;
2575 case STMF_ERROR_PERM:
2576 (void) fprintf(stderr, "%s: %s\n", cmdName,
2577 gettext("permission denied"));
2578 break;
2579 default:
2580 (void) fprintf(stderr, "%s: %s\n", cmdName,
2581 gettext("unknown error"));
2582 break;
2583 }
2584 return (1);
2585 }
2586
2587 for (; optionList->optval; optionList++) {
2588 switch (optionList->optval) {
2589 case 'v':
2590 verbose = B_TRUE;
2591 break;
2592 }
2593 }
2594
2595 if (operandLen > 0) {
2596 outerLoop = operandLen;
2597 operandEntered = B_TRUE;
2598 } else {
2599 outerLoop = 1;
2600 operandEntered = B_FALSE;
2601 }
2602
2603 for (i = 0; i < outerLoop; i++) {
2604 if (operandEntered) {
2605 bzero(&devid, sizeof (devid));
2606 (void) parseDevid(operands[i], &devid);
2607 }
2608 for (found = B_FALSE, j = 0; j < targetList->cnt; j++) {
2609 if (operandEntered) {
2610 if (bcmp(&devid, &(targetList->devid[j]),
2611 sizeof (devid)) == 0) {
2612 found = B_TRUE;
2613 }
2614 }
2615 if ((found && operandEntered) || !operandEntered) {
2616 (void) mbstowcs(targetIdent,
2617 (char *)targetList->devid[j].ident,
2618 STMF_IDENT_LENGTH);
2619 targetIdent[STMF_IDENT_LENGTH] = 0;
2620 (void) printf("Target: %ws\n", targetIdent);
2621 if (verbose) {
2622 stmfRet = stmfGetTargetProperties(
2623 &(targetList->devid[j]),
2624 &targetProps);
2625 if (stmfRet == STMF_STATUS_SUCCESS) {
2626 printTargetProps(&targetProps);
2627 } else {
2628 (void) fprintf(stderr, "%s:",
2629 cmdName);
2630 (void) fprintf(stderr, "%s\n",
2631 gettext(" get properties"
2632 " failed"));
2633 }
2634 stmfRet = stmfGetSessionList(
2635 &(targetList->devid[j]),
2636 &sessionList);
2637 if (stmfRet == STMF_STATUS_SUCCESS) {
2638 printSessionProps(sessionList);
2639 } else {
2640 (void) fprintf(stderr, "%s:",
2641 cmdName);
2642 (void) fprintf(stderr, "%s\n",
2643 gettext(" get session info"
2644 " failed"));
2645 }
2646 }
2647 if (found && operandEntered) {
2648 break;
2649 }
2650 }
2651
2652 }
2653 if (operandEntered && !found) {
2654 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2655 operands[i], "not found");
2656 ret = 1;
2657 }
2658 }
2659 return (ret);
2660 }
2661
2662 /*
2663 * listViewFunc
2664 *
2665 * list the view entries for the specified logical unit
2666 *
2667 */
2668 /*ARGSUSED*/
2669 static int
2670 listViewFunc(int operandLen, char *operands[], cmdOptions_t *options,
2671 void *args)
2672 {
2673 stmfViewEntryList *viewEntryList;
2674 stmfGuid inGuid;
2675 unsigned int guid[sizeof (stmfGuid)];
2676 int ret = 0;
2677 int stmfRet;
2678 int i, j, outerLoop;
2679 boolean_t found = B_TRUE;
2680 boolean_t operandEntered;
2681 uint16_t outputLuNbr;
2682 wchar_t groupName[sizeof (stmfGroupName)];
2683 char sGuid[GUID_INPUT + 1];
2684
2685
2686 for (; options->optval; options++) {
2687 switch (options->optval) {
2688 case 'l':
2689 if (strlen(options->optarg) != GUID_INPUT) {
2690 (void) fprintf(stderr,
2691 "%s: %s: %s%d%s\n",
2692 cmdName, options->optarg,
2693 gettext("must be "), GUID_INPUT,
2694 gettext(" hexadecimal digits"
2695 " long"));
2696 return (1);
2697 }
2698 bcopy(options->optarg, sGuid, GUID_INPUT);
2699 break;
2700 default:
2701 (void) fprintf(stderr, "%s: %c: %s\n",
2702 cmdName, options->optval,
2703 gettext("unknown option"));
2704 return (1);
2705 }
2706 }
2707
2708 if (operandLen > 0) {
2709 outerLoop = operandLen;
2710 operandEntered = B_TRUE;
2711 } else {
2712 outerLoop = 1;
2713 operandEntered = B_FALSE;
2714 }
2715
2716 for (i = 0; i < 32; i++)
2717 sGuid[i] = tolower(sGuid[i]);
2718 sGuid[i] = 0;
2719
2720 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
2721 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
2722 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11],
2723 &guid[12], &guid[13], &guid[14], &guid[15]);
2724
2725 for (i = 0; i < sizeof (stmfGuid); i++) {
2726 inGuid.guid[i] = guid[i];
2727 }
2728
2729 if ((stmfRet = stmfGetViewEntryList(&inGuid, &viewEntryList))
2730 != STMF_STATUS_SUCCESS) {
2731
2732 switch (stmfRet) {
2733 case STMF_ERROR_BUSY:
2734 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2735 sGuid, gettext("resource busy"));
2736 break;
2737 case STMF_ERROR_SERVICE_NOT_FOUND:
2738 (void) fprintf(stderr, "%s: %s\n", cmdName,
2739 gettext("STMF service not found"));
2740 break;
2741 case STMF_ERROR_SERVICE_DATA_VERSION:
2742 (void) fprintf(stderr, "%s: %s\n", cmdName,
2743 gettext("STMF service version incorrect"));
2744 break;
2745 case STMF_ERROR_PERM:
2746 (void) fprintf(stderr, "%s: %s\n", cmdName,
2747 gettext("permission denied"));
2748 break;
2749 default:
2750 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2751 sGuid, gettext("unknown error"));
2752 break;
2753 }
2754 return (1);
2755 }
2756
2757 if (viewEntryList->cnt == 0) {
2758 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2759 sGuid, gettext("no views found"));
2760 return (1);
2761 }
2762
2763 for (i = 0; i < outerLoop; i++) {
2764 for (found = B_FALSE, j = 0; j < viewEntryList->cnt; j++) {
2765 if (operandEntered) {
2766 if (atoi(operands[i]) ==
2767 viewEntryList->ve[j].veIndex) {
2768 found = B_TRUE;
2769 }
2770 }
2771 if ((found && operandEntered) || !operandEntered) {
2772 (void) printf("View Entry: %d\n",
2773 viewEntryList->ve[j].veIndex);
2774 (void) printf(VIEW_FORMAT, "Host group");
2775 if (viewEntryList->ve[j].allHosts) {
2776 (void) printf("All\n");
2777 } else {
2778 (void) mbstowcs(groupName,
2779 viewEntryList->ve[j].hostGroup,
2780 sizeof (stmfGroupName) - 1);
2781 groupName[sizeof (stmfGroupName) - 1]
2782 = 0;
2783 (void) printf("%ws\n", groupName);
2784 }
2785 (void) printf(VIEW_FORMAT, "Target group");
2786 if (viewEntryList->ve[j].allTargets) {
2787 (void) printf("All\n");
2788 } else {
2789 (void) mbstowcs(groupName,
2790 viewEntryList->ve[j].targetGroup,
2791 sizeof (stmfGroupName) - 1);
2792 groupName[sizeof (stmfGroupName) - 1]
2793 = 0;
2794 (void) printf("%ws\n", groupName);
2795 }
2796 outputLuNbr = ((viewEntryList->ve[j].luNbr[0] &
2797 0x3F) << 8) | viewEntryList->ve[j].luNbr[1];
2798 (void) printf(VIEW_FORMAT, "LUN");
2799 (void) printf("%d\n", outputLuNbr);
2800 if (found && operandEntered) {
2801 break;
2802 }
2803 }
2804 }
2805 if (operandEntered && !found) {
2806 (void) fprintf(stderr, "%s: %s, %s: %s\n", cmdName,
2807 sGuid, operands[i], gettext("not found"));
2808 ret = 1;
2809 }
2810 }
2811
2812 return (ret);
2813 }
2814
2815
2816 /*
2817 * onlineOfflineLu
2818 *
2819 * Purpose: Online or offline a logical unit
2820 *
2821 * lu - logical unit to online or offline
2822 *
2823 * state - ONLINE_LU
2824 * OFFLINE_LU
2825 */
2826 static int
2827 onlineOfflineLu(char *lu, int state)
2828 {
2829 char sGuid[GUID_INPUT + 1];
2830 stmfGuid inGuid;
2831 unsigned int guid[sizeof (stmfGuid)];
2832 int i;
2833 int ret = 0, stmfRet;
2834 stmfLogicalUnitProperties luProps;
2835
2836 if (strlen(lu) != GUID_INPUT) {
2837 (void) fprintf(stderr, "%s: %s: %s %d %s\n", cmdName, lu,
2838 gettext("must be"), GUID_INPUT,
2839 gettext("hexadecimal digits long"));
2840 return (1);
2841 }
2842
2843 bcopy(lu, sGuid, GUID_INPUT);
2844
2845 for (i = 0; i < 32; i++)
2846 sGuid[i] = tolower(sGuid[i]);
2847 sGuid[i] = 0;
2848
2849 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
2850 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
2851 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11],
2852 &guid[12], &guid[13], &guid[14], &guid[15]);
2853
2854 for (i = 0; i < sizeof (stmfGuid); i++) {
2855 inGuid.guid[i] = guid[i];
2856 }
2857
2858 if (state == ONLINE_LU) {
2859 ret = stmfOnlineLogicalUnit(&inGuid);
2860 } else if (state == OFFLINE_LU) {
2861 ret = stmfOfflineLogicalUnit(&inGuid);
2862 } else {
2863 return (STMFADM_FAILURE);
2864 }
2865 if (ret != STMF_STATUS_SUCCESS) {
2866 switch (ret) {
2867 case STMF_ERROR_PERM:
2868 (void) fprintf(stderr, "%s: %s\n", cmdName,
2869 gettext("permission denied"));
2870 break;
2871 case STMF_ERROR_SERVICE_NOT_FOUND:
2872 (void) fprintf(stderr, "%s: %s\n", cmdName,
2873 gettext("STMF service not found"));
2874 break;
2875 case STMF_ERROR_BUSY:
2876 (void) fprintf(stderr, "%s: %s\n", cmdName,
2877 gettext("resource busy"));
2878 break;
2879 case STMF_ERROR_NOT_FOUND:
2880 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
2881 lu, gettext("not found"));
2882 break;
2883 case STMF_ERROR_SERVICE_DATA_VERSION:
2884 (void) fprintf(stderr, "%s: %s\n", cmdName,
2885 gettext("STMF service version incorrect"));
2886 break;
2887 default:
2888 (void) fprintf(stderr, "%s: %s\n", cmdName,
2889 gettext("unknown error"));
2890 break;
2891 }
2892 } else {
2893 struct timespec ts = {0};
2894 unsigned int count = 0;
2895 uint32_t ret_state;
2896
2897 ret_state = (state == ONLINE_LU) ?
2898 STMF_LOGICAL_UNIT_ONLINING : STMF_LOGICAL_UNIT_OFFLINING;
2899 ts.tv_nsec = DELAYED_EXEC_WAIT_INTERVAL;
2900
2901 /* CONSTCOND */
2902 while (1) {
2903 stmfRet = stmfGetLogicalUnitProperties(&inGuid,
2904 &luProps);
2905 if (stmfRet == STMF_STATUS_SUCCESS)
2906 ret_state = luProps.status;
2907
2908 if ((state == ONLINE_LU &&
2909 ret_state == STMF_LOGICAL_UNIT_ONLINE) ||
2910 (state == OFFLINE_LU &&
2911 ret_state == STMF_LOGICAL_UNIT_OFFLINE))
2912 return (STMFADM_SUCCESS);
2913
2914 if ((state == ONLINE_LU &&
2915 ret_state == STMF_LOGICAL_UNIT_OFFLINE) ||
2916 (state == OFFLINE_LU &&
2917 ret_state == STMF_LOGICAL_UNIT_ONLINE))
2918 return (STMFADM_FAILURE);
2919
2920 if (++count == DELAYED_EXEC_WAIT_MAX) {
2921 (void) fprintf(stderr, "%s: %s\n", cmdName,
2922 gettext("Logical Unit state change request "
2923 "submitted. Waiting for completion "
2924 "timed out"));
2925 return (STMFADM_FAILURE);
2926 }
2927 (void) nanosleep(&ts, NULL);
2928 }
2929 }
2930 return (STMFADM_FAILURE);
2931 }
2932
2933 /*
2934 * onlineLuFunc
2935 *
2936 * Purpose: Online a logical unit
2937 *
2938 */
2939 /*ARGSUSED*/
2940 static int
2941 onlineLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
2942 void *args)
2943 {
2944 int ret;
2945 stmfState state;
2946
2947 ret = getStmfState(&state);
2948 if (ret != STMF_STATUS_SUCCESS)
2949 return (ret);
2950 if (state.operationalState == STMF_SERVICE_STATE_OFFLINE ||
2951 state.operationalState == STMF_SERVICE_STATE_OFFLINING) {
2952 (void) fprintf(stderr, "%s: %s\n", cmdName,
2953 gettext("STMF service is offline"));
2954 return (1);
2955 }
2956 return (onlineOfflineLu(operands[0], ONLINE_LU));
2957 }
2958
2959 /*
2960 * offlineLuFunc
2961 *
2962 * Purpose: Offline a logical unit
2963 *
2964 */
2965 /*ARGSUSED*/
2966 static int
2967 offlineLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
2968 void *args)
2969 {
2970 return (onlineOfflineLu(operands[0], OFFLINE_LU));
2971 }
2972
2973 /*
2974 * onlineOfflineTarget
2975 *
2976 * Purpose: Online or offline a target
2977 *
2978 * target - target to online or offline
2979 *
2980 * state - ONLINE_TARGET
2981 * OFFLINE_TARGET
2982 */
2983 static int
2984 onlineOfflineTarget(char *target, int state)
2985 {
2986 int ret = 0, stmfRet = 0;
2987 stmfDevid devid;
2988 stmfTargetProperties targetProps;
2989
2990 if (parseDevid(target, &devid) != 0) {
2991 (void) fprintf(stderr, "%s: %s: %s\n",
2992 cmdName, target, gettext("unrecognized device id"));
2993 return (1);
2994 }
2995 if (state == ONLINE_TARGET) {
2996 ret = stmfOnlineTarget(&devid);
2997 } else if (state == OFFLINE_TARGET) {
2998 ret = stmfOfflineTarget(&devid);
2999 } else {
3000 return (STMFADM_FAILURE);
3001 }
3002 if (ret != STMF_STATUS_SUCCESS) {
3003 switch (ret) {
3004 case STMF_ERROR_PERM:
3005 (void) fprintf(stderr, "%s: %s\n", cmdName,
3006 gettext("permission denied"));
3007 break;
3008 case STMF_ERROR_SERVICE_NOT_FOUND:
3009 (void) fprintf(stderr, "%s: %s\n", cmdName,
3010 gettext("STMF service not found"));
3011 break;
3012 case STMF_ERROR_BUSY:
3013 (void) fprintf(stderr, "%s: %s\n", cmdName,
3014 gettext("resource busy"));
3015 break;
3016 case STMF_ERROR_NOT_FOUND:
3017 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3018 target, gettext("not found"));
3019 break;
3020 case STMF_ERROR_SERVICE_DATA_VERSION:
3021 (void) fprintf(stderr, "%s: %s\n", cmdName,
3022 gettext("STMF service version incorrect"));
3023 break;
3024 default:
3025 (void) fprintf(stderr, "%s: %s\n", cmdName,
3026 gettext("unknown error"));
3027 break;
3028 }
3029 } else {
3030 struct timespec ts = {0};
3031 unsigned int count = 0;
3032 uint32_t ret_state;
3033
3034 ret_state = (state == ONLINE_TARGET) ?
3035 STMF_TARGET_PORT_ONLINING : STMF_TARGET_PORT_OFFLINING;
3036 ts.tv_nsec = DELAYED_EXEC_WAIT_INTERVAL;
3037
3038 /* CONSTCOND */
3039 while (1) {
3040 stmfRet = stmfGetTargetProperties(&devid, &targetProps);
3041 if (stmfRet == STMF_STATUS_SUCCESS)
3042 ret_state = targetProps.status;
3043
3044 if ((state == ONLINE_TARGET &&
3045 ret_state == STMF_TARGET_PORT_ONLINE) ||
3046 (state == OFFLINE_TARGET &&
3047 ret_state == STMF_TARGET_PORT_OFFLINE)) {
3048 return (STMFADM_SUCCESS);
3049 }
3050
3051 if ((state == ONLINE_TARGET &&
3052 ret_state == STMF_TARGET_PORT_OFFLINE) ||
3053 (state == OFFLINE_TARGET &&
3054 ret_state == STMF_TARGET_PORT_ONLINE)) {
3055 return (STMFADM_FAILURE);
3056 }
3057
3058 if (++count == DELAYED_EXEC_WAIT_MAX) {
3059 (void) fprintf(stderr, "%s: %s\n", cmdName,
3060 gettext("Target state change request "
3061 "submitted. Waiting for completion "
3062 "timed out."));
3063 return (STMFADM_FAILURE);
3064 }
3065 (void) nanosleep(&ts, NULL);
3066 }
3067 }
3068 return (STMFADM_FAILURE);
3069 }
3070
3071 /*
3072 * onlineTargetFunc
3073 *
3074 * Purpose: Online a target
3075 *
3076 */
3077 /*ARGSUSED*/
3078 static int
3079 onlineTargetFunc(int operandLen, char *operands[], cmdOptions_t *options,
3080 void *args)
3081 {
3082 int ret;
3083 stmfState state;
3084
3085 ret = getStmfState(&state);
3086 if (ret != STMF_STATUS_SUCCESS)
3087 return (ret);
3088 if (state.operationalState == STMF_SERVICE_STATE_OFFLINE ||
3089 state.operationalState == STMF_SERVICE_STATE_OFFLINING) {
3090 (void) fprintf(stderr, "%s: %s\n", cmdName,
3091 gettext("STMF service is offline"));
3092 return (1);
3093 }
3094 return (onlineOfflineTarget(operands[0], ONLINE_TARGET));
3095 }
3096
3097 /*
3098 * offlineTargetFunc
3099 *
3100 * Purpose: Offline a target
3101 *
3102 */
3103 /*ARGSUSED*/
3104 static int
3105 offlineTargetFunc(int operandLen, char *operands[], cmdOptions_t *options,
3106 void *args)
3107 {
3108 return (onlineOfflineTarget(operands[0], OFFLINE_TARGET));
3109 }
3110
3111
3112 /*ARGSUSED*/
3113 static int
3114 removeHostGroupMemberFunc(int operandLen, char *operands[],
3115 cmdOptions_t *options, void *args)
3116 {
3117 int i;
3118 int ret = 0;
3119 int stmfRet;
3120 stmfGroupName groupName = {0};
3121 stmfDevid devid;
3122 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
3123
3124 for (; options->optval; options++) {
3125 switch (options->optval) {
3126 case 'g':
3127 (void) mbstowcs(groupNamePrint, options->optarg,
3128 sizeof (stmfGroupName) - 1);
3129 bcopy(options->optarg, groupName,
3130 strlen(options->optarg));
3131 break;
3132 default:
3133 (void) fprintf(stderr, "%s: %c: %s\n",
3134 cmdName, options->optval,
3135 gettext("unknown option"));
3136 return (1);
3137 }
3138 }
3139
3140 for (i = 0; i < operandLen; i++) {
3141 if (parseDevid(operands[i], &devid) != 0) {
3142 (void) fprintf(stderr, "%s: %s: %s\n",
3143 cmdName, operands[i],
3144 gettext("unrecognized device id"));
3145 ret++;
3146 continue;
3147 }
3148 stmfRet = stmfRemoveFromHostGroup(&groupName, &devid);
3149 switch (stmfRet) {
3150 case STMF_STATUS_SUCCESS:
3151 break;
3152 case STMF_ERROR_MEMBER_NOT_FOUND:
3153 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3154 operands[i], gettext("not found"));
3155 ret++;
3156 break;
3157 case STMF_ERROR_GROUP_NOT_FOUND:
3158 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
3159 groupNamePrint, gettext("not found"));
3160 ret++;
3161 break;
3162 case STMF_ERROR_BUSY:
3163 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3164 operands[i], "resource busy");
3165 ret++;
3166 break;
3167 case STMF_ERROR_SERVICE_NOT_FOUND:
3168 (void) fprintf(stderr, "%s: %s\n", cmdName,
3169 gettext("STMF service not found"));
3170 ret++;
3171 break;
3172 case STMF_ERROR_SERVICE_DATA_VERSION:
3173 (void) fprintf(stderr, "%s: %s\n", cmdName,
3174 gettext("STMF service version incorrect"));
3175 ret++;
3176 break;
3177 case STMF_ERROR_PERM:
3178 (void) fprintf(stderr, "%s: %s\n", cmdName,
3179 gettext("permission denied"));
3180 ret++;
3181 break;
3182 default:
3183 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3184 operands[i], gettext("unknown error"));
3185 ret++;
3186 break;
3187 }
3188 }
3189
3190 return (ret);
3191 }
3192
3193 /*
3194 * removeTargetGroupMemberFunc
3195 *
3196 * Removes one or more members from a target group
3197 *
3198 */
3199 /*ARGSUSED*/
3200 static int
3201 removeTargetGroupMemberFunc(int operandLen, char *operands[],
3202 cmdOptions_t *options, void *args)
3203 {
3204 int i;
3205 int ret = 0;
3206 int stmfRet;
3207 stmfGroupName groupName = {0};
3208 stmfDevid devid;
3209 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0};
3210
3211 for (; options->optval; options++) {
3212 switch (options->optval) {
3213 case 'g':
3214 (void) mbstowcs(groupNamePrint, options->optarg,
3215 sizeof (stmfGroupName) - 1);
3216 bcopy(options->optarg, groupName,
3217 strlen(options->optarg));
3218 break;
3219 default:
3220 (void) fprintf(stderr, "%s: %c: %s\n",
3221 cmdName, options->optval,
3222 gettext("unknown option"));
3223 return (1);
3224 }
3225 }
3226
3227 for (i = 0; i < operandLen; i++) {
3228 if (parseDevid(operands[i], &devid) != 0) {
3229 (void) fprintf(stderr, "%s: %s: %s\n",
3230 cmdName, operands[i],
3231 gettext("unrecognized device id"));
3232 ret++;
3233 continue;
3234 }
3235 stmfRet = stmfRemoveFromTargetGroup(&groupName, &devid);
3236 switch (stmfRet) {
3237 case STMF_STATUS_SUCCESS:
3238 break;
3239 case STMF_ERROR_MEMBER_NOT_FOUND:
3240 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3241 operands[i], gettext("not found"));
3242 ret++;
3243 break;
3244 case STMF_ERROR_GROUP_NOT_FOUND:
3245 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName,
3246 groupNamePrint, gettext("not found"));
3247 ret++;
3248 break;
3249 case STMF_ERROR_BUSY:
3250 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3251 operands[i], gettext("resource busy"));
3252 ret++;
3253 break;
3254 case STMF_ERROR_SERVICE_NOT_FOUND:
3255 (void) fprintf(stderr, "%s: %s\n", cmdName,
3256 gettext("STMF service not found"));
3257 ret++;
3258 break;
3259 case STMF_ERROR_PERM:
3260 (void) fprintf(stderr, "%s: %s\n", cmdName,
3261 gettext("permission denied"));
3262 ret++;
3263 break;
3264 case STMF_ERROR_SERVICE_DATA_VERSION:
3265 (void) fprintf(stderr, "%s: %s\n", cmdName,
3266 gettext("STMF service version incorrect"));
3267 ret++;
3268 break;
3269 case STMF_ERROR_TG_ONLINE:
3270 (void) fprintf(stderr, "%s: %s\n", cmdName,
3271 gettext("STMF target must be offline"));
3272 ret++;
3273 break;
3274 default:
3275 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3276 operands[i], gettext("unknown error"));
3277 ret++;
3278 break;
3279 }
3280 }
3281
3282 return (ret);
3283 }
3284
3285 /*
3286 * removeViewFunc
3287 *
3288 * Removes one or more view entries from a logical unit
3289 *
3290 */
3291 /*ARGSUSED*/
3292 static int
3293 removeViewFunc(int operandLen, char *operands[], cmdOptions_t *options,
3294 void *args)
3295 {
3296 char sGuid[GUID_INPUT + 1];
3297 stmfViewEntryList *viewEntryList;
3298 stmfGuid inGuid;
3299 uint32_t count;
3300 unsigned int guid[sizeof (stmfGuid)];
3301 char *endPtr;
3302 uint32_t veNbr;
3303 int i;
3304 boolean_t all = B_FALSE;
3305 boolean_t luInput = B_FALSE;
3306 int ret = 0;
3307 int stmfRet;
3308
3309 /* Note: 'l' is required */
3310 for (; options->optval; options++) {
3311 switch (options->optval) {
3312 case 'l':
3313 if (strlen(options->optarg) != GUID_INPUT) {
3314 (void) fprintf(stderr,
3315 "%s: %s: %s %d %s\n",
3316 cmdName, options->optarg,
3317 gettext("must be"), GUID_INPUT,
3318 gettext("hexadecimal digits long"));
3319 return (1);
3320 }
3321 bcopy(options->optarg, sGuid, GUID_INPUT);
3322 luInput = B_TRUE;
3323 break;
3324 case 'a':
3325 /* removing all view entries for this GUID */
3326 all = B_TRUE;
3327 break;
3328 default:
3329 (void) fprintf(stderr, "%s: %c: %s\n",
3330 cmdName, options->optval,
3331 "unknown option");
3332 return (1);
3333 }
3334 }
3335
3336 if (!all && operandLen == 0) {
3337 (void) fprintf(stderr, "%s: %s\n", cmdName,
3338 gettext("no view entries specified"));
3339 return (1);
3340 }
3341
3342 if (!luInput) {
3343 (void) fprintf(stderr, "%s: %s\n", cmdName,
3344 gettext("logical unit (-l) not specified"));
3345 return (1);
3346 }
3347
3348 for (i = 0; i < 32; i++)
3349 sGuid[i] = tolower(sGuid[i]);
3350 sGuid[i] = 0;
3351
3352 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
3353 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
3354 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11],
3355 &guid[12], &guid[13], &guid[14], &guid[15]);
3356
3357 for (i = 0; i < sizeof (stmfGuid); i++) {
3358 inGuid.guid[i] = guid[i];
3359 }
3360
3361 if ((stmfRet = stmfGetViewEntryList(&inGuid, &viewEntryList))
3362 != STMF_STATUS_SUCCESS) {
3363
3364 switch (stmfRet) {
3365 case STMF_ERROR_BUSY:
3366 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3367 sGuid, gettext("resource busy"));
3368 break;
3369 case STMF_ERROR_SERVICE_NOT_FOUND:
3370 (void) fprintf(stderr, "%s: %s\n", cmdName,
3371 gettext("STMF service not found"));
3372 break;
3373 case STMF_ERROR_SERVICE_DATA_VERSION:
3374 (void) fprintf(stderr, "%s: %s\n", cmdName,
3375 gettext("STMF service version incorrect"));
3376 break;
3377 case STMF_ERROR_PERM:
3378 (void) fprintf(stderr, "%s: %s\n", cmdName,
3379 gettext("permission denied"));
3380 break;
3381 default:
3382 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3383 sGuid, gettext("unknown error"));
3384 break;
3385 }
3386 return (1);
3387 }
3388
3389 if (viewEntryList->cnt == 0) {
3390 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3391 sGuid, gettext("no views found"));
3392 return (1);
3393 }
3394
3395 if (all) {
3396 count = viewEntryList->cnt;
3397 } else {
3398 count = operandLen;
3399 }
3400
3401 for (i = 0; i < count; i++) {
3402 if (all) {
3403 veNbr = viewEntryList->ve[i].veIndex;
3404 } else {
3405 endPtr = NULL;
3406 veNbr = strtol(operands[i], &endPtr, 10);
3407 if (endPtr && *endPtr != 0) {
3408 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3409 operands[i], gettext("invalid input"));
3410 continue;
3411 }
3412 }
3413 stmfRet = stmfRemoveViewEntry(&inGuid, veNbr);
3414 switch (stmfRet) {
3415 case STMF_STATUS_SUCCESS:
3416 break;
3417 case STMF_ERROR_NOT_FOUND:
3418 (void) fprintf(stderr, "%s: %s: %d: %s\n",
3419 cmdName, sGuid, veNbr,
3420 gettext("not found"));
3421 ret++;
3422 break;
3423 case STMF_ERROR_BUSY:
3424 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
3425 sGuid, gettext("resource busy"));
3426 ret++;
3427 break;
3428 case STMF_ERROR_SERVICE_NOT_FOUND:
3429 (void) fprintf(stderr, "%s: %s\n", cmdName,
3430 gettext("STMF service not found"));
3431 ret++;
3432 break;
3433 case STMF_ERROR_CONFIG_NONE:
3434 (void) fprintf(stderr, "%s: %s\n", cmdName,
3435 gettext("STMF service is not initialized"));
3436 ret++;
3437 break;
3438 case STMF_ERROR_SERVICE_DATA_VERSION:
3439 (void) fprintf(stderr, "%s: %s\n", cmdName,
3440 gettext("STMF service version incorrect"));
3441 ret++;
3442 break;
3443 default:
3444 (void) fprintf(stderr, "%s: %s, %d: %s",
3445 cmdName, sGuid, veNbr,
3446 gettext("unknown error"));
3447 ret++;
3448 break;
3449 }
3450 }
3451
3452 return (ret);
3453 }
3454
3455 /*
3456 * input:
3457 * execFullName - exec name of program (argv[0])
3458 *
3459 * copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net
3460 * (changed name to lowerCamelCase to keep consistent with this file)
3461 *
3462 * Returns:
3463 * command name portion of execFullName
3464 */
3465 static char *
3466 getExecBasename(char *execFullname)
3467 {
3468 char *lastSlash, *execBasename;
3469
3470 /* guard against '/' at end of command invocation */
3471 for (;;) {
3472 lastSlash = strrchr(execFullname, '/');
3473 if (lastSlash == NULL) {
3474 execBasename = execFullname;
3475 break;
3476 } else {
3477 execBasename = lastSlash + 1;
3478 if (*execBasename == '\0') {
3479 *lastSlash = '\0';
3480 continue;
3481 }
3482 break;
3483 }
3484 }
3485 return (execBasename);
3486 }
3487
3488 int
3489 main(int argc, char *argv[])
3490 {
3491 synTables_t synTables;
3492 char versionString[VERSION_STRING_MAX_LEN];
3493 int ret;
3494 int funcRet;
3495 void *subcommandArgs = NULL;
3496
3497 (void) setlocale(LC_ALL, "");
3498 (void) textdomain(TEXT_DOMAIN);
3499 /* set global command name */
3500 cmdName = getExecBasename(argv[0]);
3501
3502 (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s",
3503 VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
3504 synTables.versionString = versionString;
3505 synTables.longOptionTbl = &longOptions[0];
3506 synTables.subCommandPropsTbl = &subcommands[0];
3507
3508 ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
3509 if (ret != 0) {
3510 return (ret);
3511 }
3512
3513 return (funcRet);
3514 } /* end main */