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