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