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