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