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