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