1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 */ 26 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <strings.h> 30 #include <sys/types.h> 31 #include <unistd.h> 32 #include <wchar.h> 33 #include <libintl.h> 34 #include <errno.h> 35 #include <time.h> 36 #include <string.h> 37 #include <assert.h> 38 #include <getopt.h> 39 #include <cmdparse.h> 40 #include <stmfadm.h> 41 #include <libstmf.h> 42 #include <signal.h> 43 #include <pthread.h> 44 #include <locale.h> 45 46 static int addHostGroupMemberFunc(int, char **, cmdOptions_t *, void *); 47 static int addTargetGroupMemberFunc(int, char **, cmdOptions_t *, void *); 48 static int addViewFunc(int, char **, cmdOptions_t *, void *); 49 static int createHostGroupFunc(int, char **, cmdOptions_t *, void *); 50 static int createLuFunc(int, char **, cmdOptions_t *, void *); 51 static int modifyLuFunc(int, char **, cmdOptions_t *, void *); 52 static int importLuFunc(int, char **, cmdOptions_t *, void *); 53 static int deleteLuFunc(int, char **, cmdOptions_t *, void *); 54 static int createTargetGroupFunc(int, char **, cmdOptions_t *, void *); 55 static int deleteHostGroupFunc(int, char **, cmdOptions_t *, void *); 56 static int deleteTargetGroupFunc(int, char **, cmdOptions_t *, void *); 57 static int listLuFunc(int, char **, cmdOptions_t *, void *); 58 static int listTargetFunc(int, char **, cmdOptions_t *, void *); 59 static int listViewFunc(int, char **, cmdOptions_t *, void *); 60 static int listHostGroupFunc(int, char **, cmdOptions_t *, void *); 61 static int listStateFunc(int, char **, cmdOptions_t *, void *); 62 static int listTargetGroupFunc(int, char **, cmdOptions_t *, void *); 63 static int offlineTargetFunc(int, char **, cmdOptions_t *, void *); 64 static int offlineLuFunc(int, char **, cmdOptions_t *, void *); 65 static int onlineTargetFunc(int, char **, cmdOptions_t *, void *); 66 static int onlineLuFunc(int, char **, cmdOptions_t *, void *); 67 static int onlineOfflineTarget(char *, int); 68 static int onlineOfflineLu(char *, int); 69 static int removeHostGroupMemberFunc(int, char **, cmdOptions_t *, void *); 70 static int removeTargetGroupMemberFunc(int, char **, cmdOptions_t *, void *); 71 static int callModify(char *, stmfGuid *, uint32_t, const char *, const char *); 72 static int removeViewFunc(int, char **, cmdOptions_t *, void *); 73 static char *getExecBasename(char *); 74 static int parseDevid(char *input, stmfDevid *devid); 75 static void printGroupProps(stmfGroupProperties *groupProps); 76 static int checkScsiNameString(wchar_t *, stmfDevid *); 77 static int checkHexUpper(char *); 78 static int checkIscsiName(wchar_t *); 79 static void printLuProps(stmfLogicalUnitProperties *luProps); 80 static int printExtLuProps(stmfGuid *guid); 81 static void printGuid(stmfGuid *guid, FILE *printWhere); 82 static void printTargetProps(stmfTargetProperties *); 83 static void printSessionProps(stmfSessionList *); 84 static int setLuPropFromInput(luResource, char *); 85 static int convertCharToPropId(char *, uint32_t *); 86 87 88 89 /* 90 * MAJOR - This should only change when there is an incompatible change made 91 * to the interfaces or the output. 92 * 93 * MINOR - This should change whenever there is a new command or new feature 94 * with no incompatible change. 95 */ 96 #define VERSION_STRING_MAJOR "1" 97 #define VERSION_STRING_MINOR "0" 98 #define MAX_DEVID_INPUT 256 99 #define GUID_INPUT 32 100 #define MAX_LU_NBR 16383 101 #define ONLINE_LU 0 102 #define OFFLINE_LU 1 103 #define ONLINE_TARGET 2 104 #define OFFLINE_TARGET 3 105 #define PROPS_FORMAT " %-18s: " 106 #define VIEW_FORMAT " %-13s: " 107 #define LVL3_FORMAT " %s" 108 #define LVL4_FORMAT " %s" 109 #define DELAYED_EXEC_WAIT_INTERVAL 300 * 1000 * 1000 /* in nano sec */ 110 #define DELAYED_EXEC_WAIT_MAX 30 /* Maximum number of interval times */ 111 112 /* SCSI Name String length definitions */ 113 #define SNS_EUI_16 16 114 #define SNS_EUI_24 24 115 #define SNS_EUI_32 32 116 #define SNS_NAA_16 16 117 #define SNS_NAA_32 32 118 #define SNS_WWN_16 16 119 #define SNS_IQN_223 223 120 121 /* LU Property strings */ 122 #define GUID "GUID" 123 #define ALIAS "ALIAS" 124 #define VID "VID" 125 #define PID "PID" 126 #define META_FILE "META" 127 #define WRITE_PROTECT "WP" 128 #define WRITEBACK_CACHE_DISABLE "WCD" 129 #define COMPANY_ID "OUI" 130 #define BLOCK_SIZE "BLK" 131 #define SERIAL_NUMBER "SERIAL" 132 #define MGMT_URL "MGMT-URL" 133 #define HOST_ID "HOST-ID" 134 135 #define STMFADM_SUCCESS 0 136 #define STMFADM_FAILURE 1 137 138 #define MODIFY_HELP "\n"\ 139 "Description: Modify properties of a logical unit. \n" \ 140 "Valid properties for -p, --lu-prop are: \n" \ 141 " alias - alias for logical unit (up to 255 chars)\n" \ 142 " mgmt-url - Management URL address\n" \ 143 " wcd - write cache disabled (true, false)\n" \ 144 " wp - write protect (true, false)\n\n" \ 145 "-f alters the meaning of the operand to be a file name\n" \ 146 "rather than a LU name. This allows for modification\n" \ 147 "of a logical unit that is not yet imported into stmf\n" 148 149 #define CREATE_HELP "\n"\ 150 "Description: Create a logical unit. \n" \ 151 "Valid properties for -p, --lu-prop are: \n" \ 152 " alias - alias for logical unit (up to 255 chars)\n" \ 153 " blk - block size in bytes in 2^n\n" \ 154 " guid - 32 ascii hex characters in NAA format \n" \ 155 " host-id - host identifier to be used for GUID generation \n" \ 156 " 8 ascii hex characters\n" \ 157 " meta - separate meta data file name\n" \ 158 " mgmt-url - Management URL address\n" \ 159 " oui - organizational unique identifier\n" \ 160 " 6 ascii hex characters of valid format\n" \ 161 " pid - product identifier (up to 16 chars)\n" \ 162 " serial - serial number (up to 252 chars)\n" \ 163 " vid - vendor identifier (up to 8 chars)\n" \ 164 " wcd - write cache disabled (true, false)\n" \ 165 " wp - write protect (true, false)\n" 166 #define ADD_VIEW_HELP "\n"\ 167 "Description: Add a view entry to a logical unit. \n" \ 168 "A view entry is comprised of three elements; the \n" \ 169 "logical unit number, the target group name and the\n" \ 170 "host group name. These three elements combine together\n" \ 171 "to form a view for a given COMSTAR logical unit.\n" \ 172 "This view is realized by a client, a SCSI initiator,\n" \ 173 "via a REPORT LUNS command. \n" 174 175 176 177 /* tables set up based on cmdparse instructions */ 178 179 /* add new options here */ 180 optionTbl_t longOptions[] = { 181 {"all", no_arg, 'a', NULL}, 182 {"group-name", required_arg, 'g', "group-name"}, 183 {"keep-views", no_arg, 'k', NULL}, 184 {"lu-name", required_arg, 'l', "LU-Name"}, 185 {"lun", required_arg, 'n', "logical-unit-number"}, 186 {"lu-prop", required_arg, 'p', "logical-unit-property=value"}, 187 {"file", no_arg, 'f', "filename"}, 188 {"size", required_arg, 's', "size K/M/G/T/P"}, 189 {"target-group", required_arg, 't', "group-name"}, 190 {"host-group", required_arg, 'h', "group-name"}, 191 {"verbose", no_arg, 'v', NULL}, 192 {NULL, 0, 0, 0} 193 }; 194 195 /* 196 * Add new subcommands here 197 */ 198 subCommandProps_t subcommands[] = { 199 {"add-hg-member", addHostGroupMemberFunc, "g", "g", NULL, 200 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL}, 201 {"add-tg-member", addTargetGroupMemberFunc, "g", "g", NULL, 202 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL}, 203 {"add-view", addViewFunc, "nth", NULL, NULL, 204 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, ADD_VIEW_HELP}, 205 {"create-hg", createHostGroupFunc, NULL, NULL, NULL, 206 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL}, 207 {"create-tg", createTargetGroupFunc, NULL, NULL, NULL, 208 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL}, 209 {"create-lu", createLuFunc, "ps", NULL, NULL, OPERAND_MANDATORY_SINGLE, 210 "lu file", CREATE_HELP}, 211 {"delete-hg", deleteHostGroupFunc, NULL, NULL, NULL, 212 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL}, 213 {"modify-lu", modifyLuFunc, "psf", NULL, NULL, OPERAND_MANDATORY_SINGLE, 214 OPERANDSTRING_LU, MODIFY_HELP}, 215 {"delete-lu", deleteLuFunc, "k", NULL, NULL, 216 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_LU, NULL}, 217 {"delete-tg", deleteTargetGroupFunc, NULL, NULL, NULL, 218 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_GROUP_NAME, NULL}, 219 {"import-lu", importLuFunc, NULL, NULL, NULL, 220 OPERAND_MANDATORY_SINGLE, "file name", NULL}, 221 {"list-hg", listHostGroupFunc, "v", NULL, NULL, 222 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_GROUP_NAME, NULL}, 223 {"list-lu", listLuFunc, "v", NULL, NULL, OPERAND_OPTIONAL_MULTIPLE, 224 OPERANDSTRING_LU, NULL}, 225 {"list-state", listStateFunc, NULL, NULL, NULL, OPERAND_NONE, NULL}, 226 {"list-target", listTargetFunc, "v", NULL, NULL, 227 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_TARGET, NULL}, 228 {"list-tg", listTargetGroupFunc, "v", NULL, NULL, 229 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_GROUP_NAME, NULL}, 230 {"list-view", listViewFunc, "l", "l", NULL, 231 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_VIEW_ENTRY, NULL}, 232 {"online-lu", onlineLuFunc, NULL, NULL, NULL, 233 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, NULL}, 234 {"offline-lu", offlineLuFunc, NULL, NULL, NULL, 235 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, NULL}, 236 {"online-target", onlineTargetFunc, NULL, NULL, NULL, 237 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_TARGET, NULL}, 238 {"offline-target", offlineTargetFunc, NULL, NULL, NULL, 239 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_TARGET, NULL}, 240 {"remove-hg-member", removeHostGroupMemberFunc, "g", "g", NULL, 241 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL}, 242 {"remove-tg-member", removeTargetGroupMemberFunc, "g", "g", NULL, 243 OPERAND_MANDATORY_MULTIPLE, OPERANDSTRING_GROUP_MEMBER, NULL}, 244 {"remove-view", removeViewFunc, "la", "l", NULL, 245 OPERAND_OPTIONAL_MULTIPLE, OPERANDSTRING_VIEW_ENTRY, NULL}, 246 {NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL} 247 }; 248 249 /* globals */ 250 char *cmdName; 251 252 /* 253 * addHostGroupMemberFunc 254 * 255 * Add members to a host group 256 * 257 */ 258 /*ARGSUSED*/ 259 static int 260 addHostGroupMemberFunc(int operandLen, char *operands[], cmdOptions_t *options, 261 void *args) 262 { 263 int i; 264 int ret = 0; 265 int stmfRet; 266 stmfGroupName groupName = {0}; 267 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 268 stmfDevid devid; 269 270 for (; options->optval; options++) { 271 switch (options->optval) { 272 /* host group name */ 273 case 'g': 274 (void) mbstowcs(groupNamePrint, options->optarg, 275 sizeof (stmfGroupName) - 1); 276 bcopy(options->optarg, groupName, 277 strlen(options->optarg)); 278 break; 279 default: 280 (void) fprintf(stderr, "%s: %c: %s\n", 281 cmdName, options->optval, 282 gettext("unknown option")); 283 return (1); 284 } 285 } 286 287 for (i = 0; i < operandLen; i++) { 288 if (parseDevid(operands[i], &devid) != 0) { 289 (void) fprintf(stderr, "%s: %s: %s\n", 290 cmdName, operands[i], 291 gettext("unrecognized device id")); 292 ret++; 293 continue; 294 } 295 stmfRet = stmfAddToHostGroup(&groupName, &devid); 296 switch (stmfRet) { 297 case STMF_STATUS_SUCCESS: 298 break; 299 case STMF_ERROR_EXISTS: 300 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 301 operands[i], gettext("already exists")); 302 ret++; 303 break; 304 case STMF_ERROR_GROUP_NOT_FOUND: 305 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 306 groupNamePrint, gettext("not found")); 307 ret++; 308 break; 309 case STMF_ERROR_PERM: 310 (void) fprintf(stderr, "%s: %s\n", cmdName, 311 gettext("permission denied")); 312 ret++; 313 break; 314 case STMF_ERROR_BUSY: 315 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 316 operands[i], gettext("resource busy")); 317 ret++; 318 break; 319 case STMF_ERROR_SERVICE_NOT_FOUND: 320 (void) fprintf(stderr, "%s: %s\n", cmdName, 321 gettext("STMF service not found")); 322 ret++; 323 break; 324 case STMF_ERROR_SERVICE_DATA_VERSION: 325 (void) fprintf(stderr, "%s: %s\n", cmdName, 326 gettext("STMF service version incorrect")); 327 ret++; 328 break; 329 default: 330 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 331 operands[i], gettext("unknown error")); 332 ret++; 333 break; 334 } 335 } 336 337 return (ret); 338 } 339 340 /* 341 * addTargetGroupMemberFunc 342 * 343 * Add members to a target group 344 * 345 */ 346 /*ARGSUSED*/ 347 static int 348 addTargetGroupMemberFunc(int operandLen, char *operands[], 349 cmdOptions_t *options, void *args) 350 { 351 int i; 352 int ret = 0; 353 int stmfRet; 354 stmfGroupName groupName = {0}; 355 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 356 stmfDevid devid; 357 358 for (; options->optval; options++) { 359 switch (options->optval) { 360 /* target group name */ 361 case 'g': 362 (void) mbstowcs(groupNamePrint, options->optarg, 363 sizeof (stmfGroupName) - 1); 364 bcopy(options->optarg, groupName, 365 strlen(options->optarg)); 366 break; 367 default: 368 (void) fprintf(stderr, "%s: %c: %s\n", 369 cmdName, options->optval, 370 gettext("unknown option")); 371 return (1); 372 } 373 } 374 375 for (i = 0; i < operandLen; i++) { 376 if (parseDevid(operands[i], &devid) != 0) { 377 (void) fprintf(stderr, "%s: %s: %s\n", 378 cmdName, operands[i], 379 gettext("unrecognized device id")); 380 ret++; 381 continue; 382 } 383 stmfRet = stmfAddToTargetGroup(&groupName, &devid); 384 switch (stmfRet) { 385 case STMF_STATUS_SUCCESS: 386 break; 387 case STMF_ERROR_EXISTS: 388 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 389 operands[i], gettext("already exists")); 390 ret++; 391 break; 392 case STMF_ERROR_GROUP_NOT_FOUND: 393 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 394 groupNamePrint, gettext("not found")); 395 ret++; 396 break; 397 case STMF_ERROR_PERM: 398 (void) fprintf(stderr, "%s: %s\n", cmdName, 399 gettext("permission denied")); 400 ret++; 401 break; 402 case STMF_ERROR_BUSY: 403 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 404 operands[i], gettext("resource busy")); 405 ret++; 406 break; 407 case STMF_ERROR_SERVICE_NOT_FOUND: 408 (void) fprintf(stderr, "%s: %s\n", cmdName, 409 gettext("STMF service not found")); 410 ret++; 411 break; 412 case STMF_ERROR_SERVICE_ONLINE: 413 (void) fprintf(stderr, "%s: %s\n", cmdName, 414 gettext("STMF service must be offline")); 415 ret++; 416 break; 417 case STMF_ERROR_SERVICE_DATA_VERSION: 418 (void) fprintf(stderr, "%s: %s\n", cmdName, 419 gettext("STMF service version incorrect")); 420 ret++; 421 break; 422 case STMF_ERROR_TG_ONLINE: 423 (void) fprintf(stderr, "%s: %s\n", cmdName, 424 gettext("STMF target must be offline")); 425 ret++; 426 break; 427 default: 428 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 429 operands[i], gettext("unknown error")); 430 ret++; 431 break; 432 } 433 } 434 435 return (ret); 436 } 437 438 /* 439 * parseDevid 440 * 441 * Converts char * input to a stmfDevid 442 * 443 * input - this should be in the following format with either a 444 * wwn. iqn. or eui. representation. 445 * A name string of the format: 446 * wwn.<WWN> (FC/SAS address) 447 * iqn.<iSCSI name> (iSCSI iqn) 448 * eui.<WWN> (iSCSI eui name) 449 * 450 * devid - pointer to stmfDevid structure allocated by the caller. 451 * 452 * Returns: 453 * 0 on success 454 * non-zero on failure 455 */ 456 static int 457 parseDevid(char *input, stmfDevid *devid) 458 { 459 wchar_t inputWc[MAX_DEVID_INPUT + 1] = {0}; 460 461 /* convert to wcs */ 462 (void) mbstowcs(inputWc, input, MAX_DEVID_INPUT); 463 464 /* 465 * Check for known scsi name string formats 466 * If one is found, we're done 467 * If not, then it's a failure to parse 468 */ 469 if (checkScsiNameString(inputWc, devid) == 0) { 470 return (0); 471 } 472 473 return (-1); 474 } 475 476 /* 477 * checkScsiNameString 478 * 479 * Validates known SCSI name string formats and converts to stmfDevid 480 * format 481 * 482 * input - input SCSI name string 483 * devid - pointer to stmfDevid structure allocated by the caller 484 * on successful return, contains the devid based on input 485 * 486 * returns: 487 * 0 on success 488 * -1 on failure 489 */ 490 static int 491 checkScsiNameString(wchar_t *input, stmfDevid *devid) 492 { 493 char *mbString = NULL; 494 int mbStringLen; 495 int len; 496 int i; 497 498 /* 499 * Convert to multi-byte string 500 * 501 * This is used for either eui or naa formats 502 */ 503 mbString = calloc(1, (mbStringLen = wcstombs(mbString, input, 0)) + 1); 504 if (mbString == NULL) { 505 (void) fprintf(stderr, "%s: %s\n", 506 cmdName, "Insufficient memory\n"); 507 return (-1); 508 } 509 if (wcstombs(mbString, input, mbStringLen) == (size_t)-1) { 510 return (-1); 511 } 512 513 /* 514 * check for iqn format 515 */ 516 if (strncmp(mbString, "iqn.", 4) == 0) { 517 if ((len = strlen(mbString)) > (SNS_IQN_223)) { 518 return (-1); 519 } 520 for (i = 0; i < len; i++) { 521 mbString[i] = tolower(mbString[i]); 522 } 523 if (checkIscsiName(input + 4) != 0) { 524 return (-1); 525 } 526 } else if (strncmp(mbString, "wwn.", 4) == 0) { 527 if ((len = strlen(mbString + 4)) != SNS_WWN_16) { 528 return (-1); 529 } else if (checkHexUpper(mbString + 4) != 0) { 530 return (-1); 531 } 532 } else if (strncmp(mbString, "eui.", 4) == 0) { 533 if ((len = strlen(mbString + 4)) != SNS_EUI_16) { 534 return (-1); 535 } else if (checkHexUpper(mbString + 4) != 0) { 536 return (-1); 537 } 538 } else { 539 return (-1); 540 } 541 542 /* 543 * We have a validated name string. 544 * Go ahead and set the length and copy it. 545 */ 546 devid->identLength = strlen(mbString); 547 bzero(devid->ident, STMF_IDENT_LENGTH); 548 bcopy(mbString, devid->ident, devid->identLength); 549 550 return (0); 551 } 552 553 554 /* 555 * Checks whether the entire string is in hex and converts to upper 556 */ 557 static int 558 checkHexUpper(char *input) 559 { 560 int i; 561 562 for (i = 0; i < strlen(input); i++) { 563 if (isxdigit(input[i])) { 564 input[i] = toupper(input[i]); 565 continue; 566 } 567 return (-1); 568 } 569 570 return (0); 571 } 572 573 /* 574 * checkIscsiName 575 * 576 * Purpose: Basic string checking on name 577 */ 578 static int 579 checkIscsiName(wchar_t *input) 580 { 581 int i; 582 583 for (i = 0; input[i] != 0; i++) { 584 if (!iswalnum(input[i]) && input[i] != '-' && 585 input[i] != '.' && input[i] != ':') { 586 return (-1); 587 } 588 } 589 590 return (0); 591 } 592 593 594 /* 595 * addViewFunc 596 * 597 * Adds a view entry to a logical unit 598 * 599 */ 600 /*ARGSUSED*/ 601 static int 602 addViewFunc(int operandLen, char *operands[], cmdOptions_t *options, 603 void *args) 604 { 605 stmfViewEntry viewEntry; 606 stmfGuid inGuid; 607 unsigned int guid[sizeof (stmfGuid)]; 608 uint16_t inputLuNbr; 609 int ret = 0; 610 int stmfRet; 611 int i; 612 char sGuid[GUID_INPUT + 1]; 613 614 bzero(&viewEntry, sizeof (viewEntry)); 615 /* init view entry structure */ 616 viewEntry.allHosts = B_TRUE; 617 viewEntry.allTargets = B_TRUE; 618 viewEntry.luNbrValid = B_FALSE; 619 620 /* check input length */ 621 if (strlen(operands[0]) != GUID_INPUT) { 622 (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0], 623 gettext("must be "), GUID_INPUT, 624 gettext(" hexadecimal digits")); 625 return (1); 626 } 627 628 for (; options->optval; options++) { 629 switch (options->optval) { 630 /* logical unit number */ 631 case 'n': 632 viewEntry.luNbrValid = B_TRUE; 633 inputLuNbr = atoi(options->optarg); 634 if (inputLuNbr > MAX_LU_NBR) { 635 (void) fprintf(stderr, "%s: %d: %s\n", 636 cmdName, inputLuNbr, 637 gettext("Logical unit number" 638 " must be less than 16384")); 639 return (1); 640 } 641 viewEntry.luNbr[0] = inputLuNbr >> 8; 642 viewEntry.luNbr[1] = inputLuNbr & 0xff; 643 break; 644 /* host group */ 645 case 'h': 646 viewEntry.allHosts = B_FALSE; 647 bcopy(options->optarg, viewEntry.hostGroup, 648 strlen(options->optarg)); 649 break; 650 /* target group */ 651 case 't': 652 viewEntry.allTargets = B_FALSE; 653 bcopy(options->optarg, viewEntry.targetGroup, 654 strlen(options->optarg)); 655 break; 656 default: 657 (void) fprintf(stderr, "%s: %c: %s\n", 658 cmdName, options->optval, 659 gettext("unknown option")); 660 return (1); 661 } 662 } 663 664 /* convert to lower case for scan */ 665 for (i = 0; i < 32; i++) 666 sGuid[i] = tolower(operands[0][i]); 667 sGuid[i] = 0; 668 669 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 670 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], 671 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11], 672 &guid[12], &guid[13], &guid[14], &guid[15]); 673 674 for (i = 0; i < sizeof (stmfGuid); i++) { 675 inGuid.guid[i] = guid[i]; 676 } 677 678 /* add the view entry */ 679 stmfRet = stmfAddViewEntry(&inGuid, &viewEntry); 680 switch (stmfRet) { 681 case STMF_STATUS_SUCCESS: 682 break; 683 case STMF_ERROR_EXISTS: 684 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 685 operands[0], gettext("already exists")); 686 ret++; 687 break; 688 case STMF_ERROR_BUSY: 689 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 690 operands[0], gettext("resource busy")); 691 ret++; 692 break; 693 case STMF_ERROR_SERVICE_NOT_FOUND: 694 (void) fprintf(stderr, "%s: %s\n", cmdName, 695 gettext("STMF service not found")); 696 ret++; 697 break; 698 case STMF_ERROR_PERM: 699 (void) fprintf(stderr, "%s: %s\n", cmdName, 700 gettext("permission denied")); 701 ret++; 702 break; 703 case STMF_ERROR_LUN_IN_USE: 704 (void) fprintf(stderr, "%s: %s\n", cmdName, 705 gettext("LUN already in use")); 706 ret++; 707 break; 708 case STMF_ERROR_VE_CONFLICT: 709 (void) fprintf(stderr, "%s: %s\n", cmdName, 710 gettext("view entry exists")); 711 ret++; 712 break; 713 case STMF_ERROR_CONFIG_NONE: 714 (void) fprintf(stderr, "%s: %s\n", cmdName, 715 gettext("STMF service is not initialized")); 716 ret++; 717 break; 718 case STMF_ERROR_SERVICE_DATA_VERSION: 719 (void) fprintf(stderr, "%s: %s\n", cmdName, 720 gettext("STMF service version incorrect")); 721 ret++; 722 break; 723 case STMF_ERROR_INVALID_HG: 724 (void) fprintf(stderr, "%s: %s\n", cmdName, 725 gettext("invalid host group")); 726 ret++; 727 break; 728 case STMF_ERROR_INVALID_TG: 729 (void) fprintf(stderr, "%s: %s\n", cmdName, 730 gettext("invalid target group")); 731 ret++; 732 break; 733 default: 734 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 735 operands[0], gettext("unknown error")); 736 ret++; 737 break; 738 } 739 740 return (ret); 741 } 742 743 /* 744 * createHostGroupFunc 745 * 746 * Create a host group 747 * 748 */ 749 /*ARGSUSED*/ 750 static int 751 createHostGroupFunc(int operandLen, char *operands[], 752 cmdOptions_t *options, void *args) 753 { 754 int ret = 0; 755 int stmfRet; 756 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 757 stmfGroupName groupName = {0}; 758 759 (void) strlcpy(groupName, operands[0], sizeof (groupName)); 760 (void) mbstowcs(groupNamePrint, (char *)groupName, 761 sizeof (stmfGroupName) - 1); 762 /* call create group */ 763 stmfRet = stmfCreateHostGroup(&groupName); 764 switch (stmfRet) { 765 case STMF_STATUS_SUCCESS: 766 break; 767 case STMF_ERROR_EXISTS: 768 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 769 operands[0], gettext("already exists")); 770 ret++; 771 break; 772 case STMF_ERROR_BUSY: 773 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 774 operands[0], gettext("resource busy")); 775 ret++; 776 break; 777 case STMF_ERROR_SERVICE_NOT_FOUND: 778 (void) fprintf(stderr, "%s: %s\n", cmdName, 779 gettext("STMF service not found")); 780 ret++; 781 break; 782 case STMF_ERROR_PERM: 783 (void) fprintf(stderr, "%s: %s\n", cmdName, 784 gettext("permission denied")); 785 ret++; 786 break; 787 case STMF_ERROR_SERVICE_DATA_VERSION: 788 (void) fprintf(stderr, "%s: %s\n", cmdName, 789 gettext("STMF service version incorrect")); 790 ret++; 791 break; 792 default: 793 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 794 operands[0], gettext("unknown error")); 795 ret++; 796 break; 797 } 798 799 return (ret); 800 } 801 802 /* 803 * createLuFunc 804 * 805 * Create a logical unit 806 * 807 */ 808 /*ARGSUSED*/ 809 static int 810 createLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 811 void *args) 812 { 813 luResource hdl = NULL; 814 int ret = 0; 815 int stmfRet = 0; 816 char guidAsciiBuf[33]; 817 stmfGuid createdGuid; 818 819 stmfRet = stmfCreateLuResource(STMF_DISK, &hdl); 820 821 if (stmfRet != STMF_STATUS_SUCCESS) { 822 (void) fprintf(stderr, "%s: %s\n", 823 cmdName, gettext("Failure to create lu resource\n")); 824 return (1); 825 } 826 827 for (; options->optval; options++) { 828 switch (options->optval) { 829 case 'p': 830 ret = setLuPropFromInput(hdl, options->optarg); 831 if (ret != 0) { 832 (void) stmfFreeLuResource(hdl); 833 return (1); 834 } 835 break; 836 case 's': 837 stmfRet = stmfSetLuProp(hdl, STMF_LU_PROP_SIZE, 838 options->optarg); 839 if (stmfRet != STMF_STATUS_SUCCESS) { 840 (void) fprintf(stderr, "%s: %c: %s\n", 841 cmdName, options->optval, 842 gettext("size param invalid")); 843 (void) stmfFreeLuResource(hdl); 844 return (1); 845 } 846 break; 847 default: 848 (void) fprintf(stderr, "%s: %c: %s\n", 849 cmdName, options->optval, 850 gettext("unknown option")); 851 return (1); 852 } 853 } 854 855 stmfRet = stmfSetLuProp(hdl, STMF_LU_PROP_FILENAME, operands[0]); 856 857 if (stmfRet != STMF_STATUS_SUCCESS) { 858 (void) fprintf(stderr, "%s: %s\n", 859 cmdName, gettext("could not set filename")); 860 return (1); 861 } 862 863 stmfRet = stmfCreateLu(hdl, &createdGuid); 864 switch (stmfRet) { 865 case STMF_STATUS_SUCCESS: 866 break; 867 case STMF_ERROR_BUSY: 868 case STMF_ERROR_LU_BUSY: 869 (void) fprintf(stderr, "%s: %s\n", cmdName, 870 gettext("resource busy")); 871 ret++; 872 break; 873 case STMF_ERROR_PERM: 874 (void) fprintf(stderr, "%s: %s\n", cmdName, 875 gettext("permission denied")); 876 ret++; 877 break; 878 case STMF_ERROR_FILE_IN_USE: 879 (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName, 880 operands[0], gettext("in use")); 881 ret++; 882 break; 883 case STMF_ERROR_INVALID_BLKSIZE: 884 (void) fprintf(stderr, "%s: %s\n", cmdName, 885 gettext("invalid block size")); 886 ret++; 887 break; 888 case STMF_ERROR_GUID_IN_USE: 889 (void) fprintf(stderr, "%s: %s\n", cmdName, 890 gettext("guid in use")); 891 ret++; 892 break; 893 case STMF_ERROR_META_FILE_NAME: 894 (void) fprintf(stderr, "%s: %s\n", cmdName, 895 gettext("meta file error")); 896 ret++; 897 break; 898 case STMF_ERROR_DATA_FILE_NAME: 899 (void) fprintf(stderr, "%s: %s\n", cmdName, 900 gettext("data file error")); 901 ret++; 902 break; 903 case STMF_ERROR_FILE_SIZE_INVALID: 904 (void) fprintf(stderr, "%s: %s\n", cmdName, 905 gettext("file size invalid")); 906 ret++; 907 break; 908 case STMF_ERROR_SIZE_OUT_OF_RANGE: 909 (void) fprintf(stderr, "%s: %s\n", cmdName, 910 gettext("invalid size")); 911 ret++; 912 break; 913 case STMF_ERROR_META_CREATION: 914 (void) fprintf(stderr, "%s: %s\n", cmdName, 915 gettext("could not create meta file")); 916 ret++; 917 break; 918 case STMF_ERROR_WRITE_CACHE_SET: 919 (void) fprintf(stderr, "%s: %s\n", cmdName, 920 gettext("could not set write cache")); 921 ret++; 922 break; 923 default: 924 (void) fprintf(stderr, "%s: %s\n", cmdName, 925 gettext("unknown error")); 926 ret++; 927 break; 928 } 929 930 if (ret != 0) { 931 goto done; 932 } 933 934 (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 935 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 936 "%02X%02X%02X%02X%02X%02X", 937 createdGuid.guid[0], createdGuid.guid[1], createdGuid.guid[2], 938 createdGuid.guid[3], createdGuid.guid[4], createdGuid.guid[5], 939 createdGuid.guid[6], createdGuid.guid[7], createdGuid.guid[8], 940 createdGuid.guid[9], createdGuid.guid[10], createdGuid.guid[11], 941 createdGuid.guid[12], createdGuid.guid[13], createdGuid.guid[14], 942 createdGuid.guid[15]); 943 (void) printf("Logical unit created: %s\n", guidAsciiBuf); 944 945 done: 946 (void) stmfFreeLuResource(hdl); 947 return (ret); 948 } 949 950 /* 951 * createLuFunc 952 * 953 * Create a logical unit 954 * 955 */ 956 /*ARGSUSED*/ 957 static int 958 modifyLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 959 void *args) 960 { 961 stmfGuid inGuid; 962 unsigned int guid[sizeof (stmfGuid)]; 963 int ret = 0; 964 int i; 965 char *fname = NULL; 966 char *lasts = NULL; 967 char sGuid[GUID_INPUT + 1]; 968 char *prop = NULL; 969 char *propVal = NULL; 970 boolean_t fnameUsed = B_FALSE; 971 uint32_t propId; 972 cmdOptions_t *optionStart = options; 973 974 975 for (; options->optval; options++) { 976 switch (options->optval) { 977 case 'f': 978 fnameUsed = B_TRUE; 979 fname = operands[0]; 980 break; 981 } 982 } 983 options = optionStart; 984 985 /* check input length */ 986 if (!fnameUsed && strlen(operands[0]) != GUID_INPUT) { 987 (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0], 988 gettext("must be "), GUID_INPUT, 989 gettext(" hexadecimal digits")); 990 return (1); 991 } 992 993 if (!fnameUsed) { 994 /* convert to lower case for scan */ 995 for (i = 0; i < 32; i++) 996 sGuid[i] = tolower(operands[0][i]); 997 sGuid[i] = 0; 998 (void) sscanf(sGuid, 999 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1000 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], 1001 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], 1002 &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]); 1003 1004 for (i = 0; i < sizeof (stmfGuid); i++) { 1005 inGuid.guid[i] = guid[i]; 1006 } 1007 } 1008 1009 for (; options->optval; options++) { 1010 switch (options->optval) { 1011 case 'p': 1012 prop = strtok_r(options->optarg, "=", &lasts); 1013 propVal = strtok_r(NULL, "=", &lasts); 1014 ret = convertCharToPropId(prop, &propId); 1015 if (ret != 0) { 1016 (void) fprintf(stderr, "%s: %s: %s\n", 1017 cmdName, 1018 gettext("invalid property specified"), 1019 prop); 1020 return (1); 1021 } 1022 if (propVal == NULL && 1023 propId != STMF_LU_PROP_MGMT_URL) { 1024 (void) fprintf(stderr, "%s: %s: %s\n", 1025 cmdName, options->optarg, 1026 gettext("invalid property specifier" 1027 "- prop=val\n")); 1028 return (1); 1029 } 1030 if (propVal == NULL) { 1031 ret = callModify(fname, &inGuid, propId, 1032 "", prop); 1033 } else { 1034 ret = callModify(fname, &inGuid, propId, 1035 propVal, prop); 1036 } 1037 if (ret != 0) { 1038 return (1); 1039 } 1040 break; 1041 case 's': 1042 if (callModify(fname, &inGuid, 1043 STMF_LU_PROP_SIZE, options->optarg, 1044 "size") != 0) { 1045 return (1); 1046 } 1047 break; 1048 case 'f': 1049 break; 1050 default: 1051 (void) fprintf(stderr, "%s: %c: %s\n", 1052 cmdName, options->optval, 1053 gettext("unknown option")); 1054 return (1); 1055 } 1056 } 1057 return (ret); 1058 } 1059 1060 static int 1061 callModify(char *fname, stmfGuid *luGuid, uint32_t prop, const char *propVal, 1062 const char *propString) 1063 { 1064 int ret = 0; 1065 int stmfRet = 0; 1066 1067 if (!fname) { 1068 stmfRet = stmfModifyLu(luGuid, prop, propVal); 1069 } else { 1070 stmfRet = stmfModifyLuByFname(STMF_DISK, fname, prop, 1071 propVal); 1072 } 1073 switch (stmfRet) { 1074 case STMF_STATUS_SUCCESS: 1075 break; 1076 case STMF_ERROR_BUSY: 1077 case STMF_ERROR_LU_BUSY: 1078 (void) fprintf(stderr, "%s: %s\n", cmdName, 1079 gettext("resource busy")); 1080 ret++; 1081 break; 1082 case STMF_ERROR_PERM: 1083 (void) fprintf(stderr, "%s: %s\n", cmdName, 1084 gettext("permission denied")); 1085 ret++; 1086 break; 1087 case STMF_ERROR_INVALID_BLKSIZE: 1088 (void) fprintf(stderr, "%s: %s\n", cmdName, 1089 gettext("invalid block size")); 1090 ret++; 1091 break; 1092 case STMF_ERROR_GUID_IN_USE: 1093 (void) fprintf(stderr, "%s: %s\n", cmdName, 1094 gettext("guid in use")); 1095 ret++; 1096 break; 1097 case STMF_ERROR_META_FILE_NAME: 1098 (void) fprintf(stderr, "%s: %s\n", cmdName, 1099 gettext("meta file error")); 1100 ret++; 1101 break; 1102 case STMF_ERROR_DATA_FILE_NAME: 1103 (void) fprintf(stderr, "%s: %s\n", cmdName, 1104 gettext("data file error")); 1105 ret++; 1106 break; 1107 case STMF_ERROR_FILE_SIZE_INVALID: 1108 (void) fprintf(stderr, "%s: %s\n", cmdName, 1109 gettext("file size invalid")); 1110 ret++; 1111 break; 1112 case STMF_ERROR_SIZE_OUT_OF_RANGE: 1113 (void) fprintf(stderr, "%s: %s\n", cmdName, 1114 gettext("invalid size")); 1115 ret++; 1116 break; 1117 case STMF_ERROR_META_CREATION: 1118 (void) fprintf(stderr, "%s: %s\n", cmdName, 1119 gettext("could not create meta file")); 1120 ret++; 1121 break; 1122 case STMF_ERROR_INVALID_PROP: 1123 (void) fprintf(stderr, "%s: %s\n", cmdName, 1124 gettext("invalid property for modify")); 1125 ret++; 1126 break; 1127 case STMF_ERROR_WRITE_CACHE_SET: 1128 (void) fprintf(stderr, "%s: %s\n", cmdName, 1129 gettext("could not set write cache")); 1130 ret++; 1131 break; 1132 case STMF_ERROR_ACCESS_STATE_SET: 1133 (void) fprintf(stderr, "%s: %s\n", cmdName, 1134 gettext("cannot modify while in standby mode")); 1135 ret++; 1136 break; 1137 default: 1138 (void) fprintf(stderr, "%s: %s: %s: %d\n", cmdName, 1139 gettext("could not set property"), propString, 1140 stmfRet); 1141 ret++; 1142 break; 1143 } 1144 1145 return (ret); 1146 } 1147 1148 1149 /* 1150 * importLuFunc 1151 * 1152 * Create a logical unit 1153 * 1154 */ 1155 /*ARGSUSED*/ 1156 static int 1157 importLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 1158 void *args) 1159 { 1160 int stmfRet = 0; 1161 int ret = 0; 1162 char guidAsciiBuf[33]; 1163 stmfGuid createdGuid; 1164 1165 stmfRet = stmfImportLu(STMF_DISK, operands[0], &createdGuid); 1166 switch (stmfRet) { 1167 case STMF_STATUS_SUCCESS: 1168 break; 1169 case STMF_ERROR_BUSY: 1170 case STMF_ERROR_LU_BUSY: 1171 (void) fprintf(stderr, "%s: %s\n", cmdName, 1172 gettext("resource busy")); 1173 ret++; 1174 break; 1175 case STMF_ERROR_PERM: 1176 (void) fprintf(stderr, "%s: %s\n", cmdName, 1177 gettext("permission denied")); 1178 ret++; 1179 break; 1180 case STMF_ERROR_FILE_IN_USE: 1181 (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName, 1182 operands[0], gettext("in use")); 1183 ret++; 1184 break; 1185 case STMF_ERROR_GUID_IN_USE: 1186 (void) fprintf(stderr, "%s: %s\n", cmdName, 1187 gettext("guid in use")); 1188 ret++; 1189 break; 1190 case STMF_ERROR_META_FILE_NAME: 1191 (void) fprintf(stderr, "%s: %s\n", cmdName, 1192 gettext("meta file error")); 1193 ret++; 1194 break; 1195 case STMF_ERROR_DATA_FILE_NAME: 1196 (void) fprintf(stderr, "%s: %s\n", cmdName, 1197 gettext("data file error")); 1198 ret++; 1199 break; 1200 case STMF_ERROR_META_CREATION: 1201 (void) fprintf(stderr, "%s: %s\n", cmdName, 1202 gettext("could not create meta file")); 1203 ret++; 1204 break; 1205 case STMF_ERROR_WRITE_CACHE_SET: 1206 (void) fprintf(stderr, "%s: %s\n", cmdName, 1207 gettext("could not set write cache")); 1208 ret++; 1209 break; 1210 default: 1211 (void) fprintf(stderr, "%s: %s\n", cmdName, 1212 gettext("unknown error")); 1213 ret++; 1214 break; 1215 } 1216 1217 if (ret != STMF_STATUS_SUCCESS) { 1218 goto done; 1219 } 1220 1221 (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 1222 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 1223 "%02X%02X%02X%02X%02X%02X", 1224 createdGuid.guid[0], createdGuid.guid[1], createdGuid.guid[2], 1225 createdGuid.guid[3], createdGuid.guid[4], createdGuid.guid[5], 1226 createdGuid.guid[6], createdGuid.guid[7], createdGuid.guid[8], 1227 createdGuid.guid[9], createdGuid.guid[10], createdGuid.guid[11], 1228 createdGuid.guid[12], createdGuid.guid[13], createdGuid.guid[14], 1229 createdGuid.guid[15]); 1230 (void) printf("Logical unit imported: %s\n", guidAsciiBuf); 1231 1232 done: 1233 return (ret); 1234 } 1235 1236 static int 1237 setLuPropFromInput(luResource hdl, char *optarg) 1238 { 1239 char *prop = NULL; 1240 char *propVal = NULL; 1241 char *lasts = NULL; 1242 uint32_t propId; 1243 int ret = 0; 1244 1245 prop = strtok_r(optarg, "=", &lasts); 1246 if ((propVal = strtok_r(NULL, "=", &lasts)) == NULL) { 1247 (void) fprintf(stderr, "%s: %s: %s\n", 1248 cmdName, optarg, 1249 gettext("invalid property specifier - prop=val\n")); 1250 return (1); 1251 } 1252 1253 ret = convertCharToPropId(prop, &propId); 1254 if (ret != 0) { 1255 (void) fprintf(stderr, "%s: %s: %s\n", 1256 cmdName, gettext("invalid property specified"), prop); 1257 return (1); 1258 } 1259 1260 ret = stmfSetLuProp(hdl, propId, propVal); 1261 if (ret != STMF_STATUS_SUCCESS) { 1262 (void) fprintf(stderr, "%s: %s %s: ", 1263 cmdName, gettext("unable to set"), prop); 1264 switch (ret) { 1265 case STMF_ERROR_INVALID_PROPSIZE: 1266 (void) fprintf(stderr, "invalid length\n"); 1267 break; 1268 case STMF_ERROR_INVALID_ARG: 1269 (void) fprintf(stderr, "bad format\n"); 1270 break; 1271 default: 1272 (void) fprintf(stderr, "\n"); 1273 break; 1274 } 1275 return (1); 1276 } 1277 1278 return (0); 1279 } 1280 1281 static int 1282 convertCharToPropId(char *prop, uint32_t *propId) 1283 { 1284 if (strcasecmp(prop, GUID) == 0) { 1285 *propId = STMF_LU_PROP_GUID; 1286 } else if (strcasecmp(prop, ALIAS) == 0) { 1287 *propId = STMF_LU_PROP_ALIAS; 1288 } else if (strcasecmp(prop, VID) == 0) { 1289 *propId = STMF_LU_PROP_VID; 1290 } else if (strcasecmp(prop, PID) == 0) { 1291 *propId = STMF_LU_PROP_PID; 1292 } else if (strcasecmp(prop, WRITE_PROTECT) == 0) { 1293 *propId = STMF_LU_PROP_WRITE_PROTECT; 1294 } else if (strcasecmp(prop, WRITEBACK_CACHE_DISABLE) == 0) { 1295 *propId = STMF_LU_PROP_WRITE_CACHE_DISABLE; 1296 } else if (strcasecmp(prop, BLOCK_SIZE) == 0) { 1297 *propId = STMF_LU_PROP_BLOCK_SIZE; 1298 } else if (strcasecmp(prop, SERIAL_NUMBER) == 0) { 1299 *propId = STMF_LU_PROP_SERIAL_NUM; 1300 } else if (strcasecmp(prop, COMPANY_ID) == 0) { 1301 *propId = STMF_LU_PROP_COMPANY_ID; 1302 } else if (strcasecmp(prop, META_FILE) == 0) { 1303 *propId = STMF_LU_PROP_META_FILENAME; 1304 } else if (strcasecmp(prop, MGMT_URL) == 0) { 1305 *propId = STMF_LU_PROP_MGMT_URL; 1306 } else if (strcasecmp(prop, HOST_ID) == 0) { 1307 *propId = STMF_LU_PROP_HOST_ID; 1308 } else { 1309 return (1); 1310 } 1311 return (0); 1312 } 1313 1314 /* 1315 * deleteLuFunc 1316 * 1317 * Delete a logical unit 1318 * 1319 */ 1320 /*ARGSUSED*/ 1321 static int 1322 deleteLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 1323 void *args) 1324 { 1325 int i, j; 1326 int ret = 0; 1327 int stmfRet; 1328 unsigned int inGuid[sizeof (stmfGuid)]; 1329 stmfGuid delGuid; 1330 boolean_t keepViews = B_FALSE; 1331 boolean_t viewEntriesRemoved = B_FALSE; 1332 boolean_t noLunFound = B_FALSE; 1333 boolean_t views = B_FALSE; 1334 boolean_t notValidHexNumber = B_FALSE; 1335 char sGuid[GUID_INPUT + 1]; 1336 stmfViewEntryList *viewEntryList = NULL; 1337 1338 for (; options->optval; options++) { 1339 switch (options->optval) { 1340 /* Keep views for logical unit */ 1341 case 'k': 1342 keepViews = B_TRUE; 1343 break; 1344 default: 1345 (void) fprintf(stderr, "%s: %c: %s\n", 1346 cmdName, options->optval, 1347 gettext("unknown option")); 1348 return (1); 1349 } 1350 } 1351 1352 1353 for (i = 0; i < operandLen; i++) { 1354 for (j = 0; j < GUID_INPUT; j++) { 1355 if (!isxdigit(operands[i][j])) { 1356 notValidHexNumber = B_TRUE; 1357 break; 1358 } 1359 sGuid[j] = tolower(operands[i][j]); 1360 } 1361 if ((notValidHexNumber == B_TRUE) || 1362 (strlen(operands[i]) != GUID_INPUT)) { 1363 (void) fprintf(stderr, "%s: %s: %s%d%s\n", 1364 cmdName, operands[i], gettext("must be "), 1365 GUID_INPUT, 1366 gettext(" hexadecimal digits long")); 1367 notValidHexNumber = B_FALSE; 1368 ret++; 1369 continue; 1370 } 1371 1372 sGuid[j] = 0; 1373 1374 (void) sscanf(sGuid, 1375 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1376 &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3], 1377 &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7], 1378 &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11], 1379 &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]); 1380 1381 for (j = 0; j < sizeof (stmfGuid); j++) { 1382 delGuid.guid[j] = inGuid[j]; 1383 } 1384 1385 stmfRet = stmfDeleteLu(&delGuid); 1386 switch (stmfRet) { 1387 case STMF_STATUS_SUCCESS: 1388 break; 1389 case STMF_ERROR_NOT_FOUND: 1390 noLunFound = B_TRUE; 1391 break; 1392 case STMF_ERROR_BUSY: 1393 (void) fprintf(stderr, "%s: %s\n", cmdName, 1394 gettext("resource busy")); 1395 ret++; 1396 break; 1397 case STMF_ERROR_PERM: 1398 (void) fprintf(stderr, "%s: %s\n", cmdName, 1399 gettext("permission denied")); 1400 ret++; 1401 break; 1402 default: 1403 (void) fprintf(stderr, "%s: %s\n", cmdName, 1404 gettext("unknown error")); 1405 ret++; 1406 break; 1407 } 1408 1409 if (!keepViews) { 1410 stmfRet = stmfGetViewEntryList(&delGuid, 1411 &viewEntryList); 1412 if (stmfRet == STMF_STATUS_SUCCESS) { 1413 for (j = 0; j < viewEntryList->cnt; j++) { 1414 (void) stmfRemoveViewEntry(&delGuid, 1415 viewEntryList->ve[j].veIndex); 1416 } 1417 /* check if viewEntryList is empty */ 1418 if (viewEntryList->cnt != 0) 1419 viewEntriesRemoved = B_TRUE; 1420 stmfFreeMemory(viewEntryList); 1421 } else { 1422 (void) fprintf(stderr, "%s: %s\n", cmdName, 1423 gettext("unable to remove view entries\n")); 1424 ret++; 1425 } 1426 1427 } 1428 if (keepViews) { 1429 stmfRet = stmfGetViewEntryList(&delGuid, 1430 &viewEntryList); 1431 if (stmfRet == STMF_STATUS_SUCCESS) { 1432 views = B_TRUE; 1433 stmfFreeMemory(viewEntryList); 1434 } 1435 } 1436 1437 if ((!viewEntriesRemoved && noLunFound && !views) || 1438 (!views && keepViews && noLunFound)) { 1439 (void) fprintf(stderr, "%s: %s: %s\n", 1440 cmdName, sGuid, 1441 gettext("not found")); 1442 ret++; 1443 } 1444 noLunFound = viewEntriesRemoved = views = B_FALSE; 1445 } 1446 return (ret); 1447 } 1448 1449 1450 /* 1451 * createTargetGroupFunc 1452 * 1453 * Create a target group 1454 * 1455 */ 1456 /*ARGSUSED*/ 1457 static int 1458 createTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options, 1459 void *args) 1460 { 1461 int ret = 0; 1462 int stmfRet; 1463 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 1464 stmfGroupName groupName = {0}; 1465 1466 (void) strlcpy(groupName, operands[0], sizeof (groupName)); 1467 (void) mbstowcs(groupNamePrint, (char *)groupName, 1468 sizeof (stmfGroupName) - 1); 1469 /* call create group */ 1470 stmfRet = stmfCreateTargetGroup(&groupName); 1471 switch (stmfRet) { 1472 case STMF_STATUS_SUCCESS: 1473 break; 1474 case STMF_ERROR_EXISTS: 1475 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1476 groupNamePrint, gettext("already exists")); 1477 ret++; 1478 break; 1479 case STMF_ERROR_BUSY: 1480 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1481 groupNamePrint, gettext("resource busy")); 1482 ret++; 1483 break; 1484 case STMF_ERROR_PERM: 1485 (void) fprintf(stderr, "%s: %s\n", cmdName, 1486 gettext("permission denied")); 1487 ret++; 1488 break; 1489 case STMF_ERROR_SERVICE_NOT_FOUND: 1490 (void) fprintf(stderr, "%s: %s\n", cmdName, 1491 gettext("STMF service not found")); 1492 ret++; 1493 break; 1494 case STMF_ERROR_SERVICE_DATA_VERSION: 1495 (void) fprintf(stderr, "%s: %s\n", cmdName, 1496 gettext("STMF service version incorrect")); 1497 ret++; 1498 break; 1499 default: 1500 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1501 groupNamePrint, gettext("unknown error")); 1502 ret++; 1503 break; 1504 } 1505 1506 return (ret); 1507 } 1508 1509 /* 1510 * deleteHostGroupFunc 1511 * 1512 * Delete a host group 1513 * 1514 */ 1515 /*ARGSUSED*/ 1516 static int 1517 deleteHostGroupFunc(int operandLen, char *operands[], 1518 cmdOptions_t *options, void *args) 1519 { 1520 int ret = 0; 1521 int stmfRet; 1522 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 1523 stmfGroupName groupName = {0}; 1524 1525 (void) strlcpy(groupName, operands[0], sizeof (groupName)); 1526 (void) mbstowcs(groupNamePrint, (char *)groupName, 1527 sizeof (stmfGroupName) - 1); 1528 /* call delete group */ 1529 stmfRet = stmfDeleteHostGroup(&groupName); 1530 switch (stmfRet) { 1531 case STMF_STATUS_SUCCESS: 1532 break; 1533 case STMF_ERROR_NOT_FOUND: 1534 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1535 groupNamePrint, gettext("not found")); 1536 ret++; 1537 break; 1538 case STMF_ERROR_BUSY: 1539 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1540 groupNamePrint, gettext("resource busy")); 1541 ret++; 1542 break; 1543 case STMF_ERROR_SERVICE_NOT_FOUND: 1544 (void) fprintf(stderr, "%s: %s\n", cmdName, 1545 gettext("STMF service not found")); 1546 ret++; 1547 break; 1548 case STMF_ERROR_PERM: 1549 (void) fprintf(stderr, "%s: %s\n", cmdName, 1550 gettext("permission denied")); 1551 ret++; 1552 break; 1553 case STMF_ERROR_GROUP_IN_USE: 1554 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1555 groupNamePrint, 1556 gettext("group is in use by existing view entry")); 1557 ret++; 1558 break; 1559 case STMF_ERROR_SERVICE_DATA_VERSION: 1560 (void) fprintf(stderr, "%s: %s\n", cmdName, 1561 gettext("STMF service version incorrect")); 1562 ret++; 1563 break; 1564 default: 1565 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1566 groupNamePrint, gettext("unknown error")); 1567 ret++; 1568 break; 1569 } 1570 1571 return (ret); 1572 } 1573 1574 /* 1575 * deleteTargetGroupFunc 1576 * 1577 * Delete a target group 1578 * 1579 */ 1580 /*ARGSUSED*/ 1581 static int 1582 deleteTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options, 1583 void *args) 1584 { 1585 int ret = 0; 1586 int stmfRet; 1587 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 1588 stmfGroupName groupName = {0}; 1589 1590 (void) strlcpy(groupName, operands[0], sizeof (groupName)); 1591 (void) mbstowcs(groupNamePrint, (char *)groupName, 1592 sizeof (stmfGroupName) - 1); 1593 /* call delete group */ 1594 stmfRet = stmfDeleteTargetGroup(&groupName); 1595 switch (stmfRet) { 1596 case STMF_STATUS_SUCCESS: 1597 break; 1598 case STMF_ERROR_NOT_FOUND: 1599 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1600 groupNamePrint, gettext("not found")); 1601 ret++; 1602 break; 1603 case STMF_ERROR_BUSY: 1604 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1605 groupNamePrint, gettext("resource busy")); 1606 ret++; 1607 break; 1608 case STMF_ERROR_SERVICE_NOT_FOUND: 1609 (void) fprintf(stderr, "%s: %s\n", cmdName, 1610 gettext("STMF service not found")); 1611 ret++; 1612 break; 1613 case STMF_ERROR_PERM: 1614 (void) fprintf(stderr, "%s: %s\n", cmdName, 1615 gettext("permission denied")); 1616 ret++; 1617 break; 1618 case STMF_ERROR_GROUP_IN_USE: 1619 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1620 groupNamePrint, 1621 gettext("group is in use by existing view entry")); 1622 ret++; 1623 break; 1624 case STMF_ERROR_SERVICE_DATA_VERSION: 1625 (void) fprintf(stderr, "%s: %s\n", cmdName, 1626 gettext("STMF service version incorrect")); 1627 ret++; 1628 break; 1629 default: 1630 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 1631 groupNamePrint, gettext("unknown error")); 1632 ret++; 1633 break; 1634 } 1635 1636 return (ret); 1637 } 1638 1639 /* 1640 * listHostGroupFunc 1641 * 1642 * Lists the specified host groups or all if none are specified 1643 * 1644 */ 1645 /*ARGSUSED*/ 1646 static int 1647 listHostGroupFunc(int operandLen, char *operands[], cmdOptions_t *options, 1648 void *args) 1649 { 1650 int ret = 0; 1651 int stmfRet; 1652 int i, j, outerLoop; 1653 boolean_t verbose = B_FALSE; 1654 boolean_t found = B_TRUE; 1655 boolean_t operandEntered; 1656 stmfGroupList *groupList; 1657 stmfGroupProperties *groupProps; 1658 wchar_t operandName[sizeof (stmfGroupName)]; 1659 wchar_t groupNamePrint[sizeof (stmfGroupName)]; 1660 1661 for (; options->optval; options++) { 1662 switch (options->optval) { 1663 case 'v': 1664 verbose = B_TRUE; 1665 break; 1666 default: 1667 (void) fprintf(stderr, "%s: %c: %s\n", 1668 cmdName, options->optval, 1669 gettext("unknown option")); 1670 return (1); 1671 } 1672 } 1673 1674 if (operandLen > 0) { 1675 outerLoop = operandLen; 1676 operandEntered = B_TRUE; 1677 } else { 1678 outerLoop = 1; 1679 operandEntered = B_FALSE; 1680 } 1681 1682 stmfRet = stmfGetHostGroupList(&groupList); 1683 if (stmfRet != STMF_STATUS_SUCCESS) { 1684 switch (stmfRet) { 1685 case STMF_ERROR_BUSY: 1686 (void) fprintf(stderr, "%s: %s\n", cmdName, 1687 gettext("resource busy")); 1688 break; 1689 case STMF_ERROR_SERVICE_NOT_FOUND: 1690 (void) fprintf(stderr, "%s: %s\n", cmdName, 1691 gettext("STMF service not found")); 1692 break; 1693 case STMF_ERROR_PERM: 1694 (void) fprintf(stderr, "%s: %s\n", cmdName, 1695 gettext("permission denied")); 1696 break; 1697 case STMF_ERROR_SERVICE_DATA_VERSION: 1698 (void) fprintf(stderr, "%s: %s\n", cmdName, 1699 gettext("STMF service version incorrect")); 1700 break; 1701 default: 1702 (void) fprintf(stderr, "%s: %s\n", cmdName, 1703 gettext("unknown error")); 1704 break; 1705 } 1706 return (1); 1707 } 1708 1709 for (i = 0; i < outerLoop; i++) { 1710 for (found = B_FALSE, j = 0; j < groupList->cnt; j++) { 1711 (void) mbstowcs(groupNamePrint, 1712 (char *)groupList->name[j], 1713 sizeof (stmfGroupName) - 1); 1714 groupNamePrint[sizeof (stmfGroupName) - 1] = 0; 1715 if (operandEntered) { 1716 (void) mbstowcs(operandName, operands[i], 1717 sizeof (stmfGroupName) - 1); 1718 operandName[sizeof (stmfGroupName) - 1] = 0; 1719 if (wcscmp(operandName, groupNamePrint) 1720 == 0) { 1721 found = B_TRUE; 1722 } 1723 } 1724 if ((found && operandEntered) || !operandEntered) { 1725 (void) printf("Host Group: %ws\n", 1726 groupNamePrint); 1727 if (verbose) { 1728 stmfRet = stmfGetHostGroupMembers( 1729 &(groupList->name[j]), &groupProps); 1730 if (stmfRet != STMF_STATUS_SUCCESS) { 1731 return (1); 1732 } 1733 printGroupProps(groupProps); 1734 } 1735 if (found && operandEntered) { 1736 break; 1737 } 1738 } 1739 1740 } 1741 if (operandEntered && !found) { 1742 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1743 operands[i], gettext("not found")); 1744 ret = 1; 1745 } 1746 } 1747 return (ret); 1748 } 1749 1750 /* 1751 * printGroupProps 1752 * 1753 * Prints group members for target or host groups 1754 * 1755 */ 1756 static void 1757 printGroupProps(stmfGroupProperties *groupProps) 1758 { 1759 int i; 1760 wchar_t memberIdent[sizeof (groupProps->name[0].ident) + 1] = {0}; 1761 1762 1763 for (i = 0; i < groupProps->cnt; i++) { 1764 (void) mbstowcs(memberIdent, (char *)groupProps->name[i].ident, 1765 sizeof (groupProps->name[0].ident)); 1766 (void) printf("\tMember: %ws\n", memberIdent); 1767 } 1768 } 1769 1770 /* 1771 * listTargetGroupFunc 1772 * 1773 * Lists the specified target groups or all if none are specified 1774 * 1775 */ 1776 /*ARGSUSED*/ 1777 static int 1778 listTargetGroupFunc(int operandLen, char *operands[], cmdOptions_t *options, 1779 void *args) 1780 { 1781 int ret = 0; 1782 int stmfRet; 1783 int i, j, outerLoop; 1784 boolean_t verbose = B_FALSE; 1785 boolean_t found = B_TRUE; 1786 boolean_t operandEntered; 1787 stmfGroupList *groupList; 1788 stmfGroupProperties *groupProps; 1789 wchar_t operandName[sizeof (stmfGroupName)]; 1790 wchar_t groupNamePrint[sizeof (stmfGroupName)]; 1791 1792 for (; options->optval; options++) { 1793 switch (options->optval) { 1794 case 'v': 1795 verbose = B_TRUE; 1796 break; 1797 default: 1798 (void) fprintf(stderr, "%s: %c: %s\n", 1799 cmdName, options->optval, 1800 gettext("unknown option")); 1801 return (1); 1802 } 1803 } 1804 1805 if (operandLen > 0) { 1806 outerLoop = operandLen; 1807 operandEntered = B_TRUE; 1808 } else { 1809 outerLoop = 1; 1810 operandEntered = B_FALSE; 1811 } 1812 1813 stmfRet = stmfGetTargetGroupList(&groupList); 1814 if (stmfRet != STMF_STATUS_SUCCESS) { 1815 switch (stmfRet) { 1816 case STMF_ERROR_BUSY: 1817 (void) fprintf(stderr, "%s: %s\n", cmdName, 1818 gettext("resource busy")); 1819 break; 1820 case STMF_ERROR_SERVICE_NOT_FOUND: 1821 (void) fprintf(stderr, "%s: %s\n", cmdName, 1822 gettext("STMF service not found")); 1823 break; 1824 case STMF_ERROR_SERVICE_DATA_VERSION: 1825 (void) fprintf(stderr, "%s: %s\n", cmdName, 1826 gettext("STMF service version incorrect")); 1827 break; 1828 case STMF_ERROR_PERM: 1829 (void) fprintf(stderr, "%s: %s\n", cmdName, 1830 gettext("permission denied")); 1831 break; 1832 default: 1833 (void) fprintf(stderr, "%s: %s\n", cmdName, 1834 gettext("unknown error")); 1835 break; 1836 } 1837 return (1); 1838 } 1839 1840 for (i = 0; i < outerLoop; i++) { 1841 for (found = B_FALSE, j = 0; j < groupList->cnt; j++) { 1842 (void) mbstowcs(groupNamePrint, 1843 (char *)groupList->name[j], 1844 sizeof (stmfGroupName) - 1); 1845 groupNamePrint[sizeof (stmfGroupName) - 1] = 0; 1846 if (operandEntered) { 1847 (void) mbstowcs(operandName, operands[i], 1848 sizeof (stmfGroupName) - 1); 1849 operandName[sizeof (stmfGroupName) - 1] = 0; 1850 if (wcscmp(operandName, groupNamePrint) 1851 == 0) { 1852 found = B_TRUE; 1853 } 1854 } 1855 if ((found && operandEntered) || !operandEntered) { 1856 (void) printf("Target Group: %ws\n", 1857 groupNamePrint); 1858 if (verbose) { 1859 stmfRet = stmfGetTargetGroupMembers( 1860 &(groupList->name[j]), &groupProps); 1861 if (stmfRet != STMF_STATUS_SUCCESS) { 1862 return (1); 1863 } 1864 printGroupProps(groupProps); 1865 } 1866 if (found && operandEntered) { 1867 break; 1868 } 1869 } 1870 1871 } 1872 if (operandEntered && !found) { 1873 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1874 operands[i], gettext("not found")); 1875 ret = 1; 1876 } 1877 } 1878 return (ret); 1879 } 1880 1881 /* 1882 * listLuFunc 1883 * 1884 * List the logical units and optionally the properties 1885 * 1886 */ 1887 /*ARGSUSED*/ 1888 static int 1889 listLuFunc(int operandLen, char *operands[], cmdOptions_t *options, void *args) 1890 { 1891 cmdOptions_t *optionList = options; 1892 boolean_t operandEntered; 1893 int i, j; 1894 int ret = 0; 1895 int stmfRet; 1896 int outerLoop; 1897 unsigned int inGuid[sizeof (stmfGuid)]; 1898 stmfGuid cmpGuid; 1899 boolean_t verbose = B_FALSE; 1900 boolean_t found; 1901 char sGuid[GUID_INPUT + 1]; 1902 stmfGuidList *luList; 1903 stmfLogicalUnitProperties luProps; 1904 boolean_t invalidInput = B_FALSE; 1905 stmfViewEntryList *viewEntryList; 1906 1907 for (; optionList->optval; optionList++) { 1908 switch (optionList->optval) { 1909 case 'v': 1910 verbose = B_TRUE; 1911 break; 1912 } 1913 } 1914 1915 if ((stmfRet = stmfGetLogicalUnitList(&luList)) 1916 != STMF_STATUS_SUCCESS) { 1917 switch (stmfRet) { 1918 case STMF_ERROR_SERVICE_NOT_FOUND: 1919 (void) fprintf(stderr, "%s: %s\n", cmdName, 1920 gettext("STMF service not found")); 1921 break; 1922 case STMF_ERROR_BUSY: 1923 (void) fprintf(stderr, "%s: %s\n", cmdName, 1924 gettext("resource busy")); 1925 break; 1926 case STMF_ERROR_PERM: 1927 (void) fprintf(stderr, "%s: %s\n", cmdName, 1928 gettext("permission denied")); 1929 break; 1930 case STMF_ERROR_SERVICE_DATA_VERSION: 1931 (void) fprintf(stderr, "%s: %s\n", cmdName, 1932 gettext("STMF service version incorrect")); 1933 break; 1934 default: 1935 (void) fprintf(stderr, "%s: %s\n", cmdName, 1936 gettext("list failed")); 1937 break; 1938 } 1939 return (1); 1940 } 1941 1942 if (operandLen > 0) { 1943 operandEntered = B_TRUE; 1944 outerLoop = operandLen; 1945 } else { 1946 operandEntered = B_FALSE; 1947 outerLoop = 1; 1948 } 1949 1950 1951 for (invalidInput = B_FALSE, i = 0; i < outerLoop; i++) { 1952 if (operandEntered) { 1953 if (strlen(operands[i]) != GUID_INPUT) { 1954 invalidInput = B_TRUE; 1955 } else { 1956 for (j = 0; j < GUID_INPUT; j++) { 1957 if (!isxdigit(operands[i][j])) { 1958 invalidInput = B_TRUE; 1959 break; 1960 } 1961 } 1962 } 1963 if (invalidInput) { 1964 (void) fprintf(stderr, "%s: %s: %s%d%s\n", 1965 cmdName, operands[i], gettext("must be "), 1966 GUID_INPUT, 1967 gettext(" hexadecimal digits long")); 1968 invalidInput = B_FALSE; 1969 continue; 1970 } 1971 1972 for (j = 0; j < GUID_INPUT; j++) { 1973 sGuid[j] = tolower(operands[i][j]); 1974 } 1975 sGuid[j] = 0; 1976 1977 (void) sscanf(sGuid, 1978 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1979 &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3], 1980 &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7], 1981 &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11], 1982 &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]); 1983 1984 for (j = 0; j < sizeof (stmfGuid); j++) { 1985 cmpGuid.guid[j] = inGuid[j]; 1986 } 1987 } 1988 1989 for (found = B_FALSE, j = 0; j < luList->cnt; j++) { 1990 if (operandEntered) { 1991 if (bcmp(luList->guid[j].guid, cmpGuid.guid, 1992 sizeof (stmfGuid)) == 0) { 1993 found = B_TRUE; 1994 } 1995 } 1996 if ((found && operandEntered) || !operandEntered) { 1997 (void) printf("LU Name: "); 1998 printGuid(&luList->guid[j], stdout); 1999 (void) printf("\n"); 2000 2001 if (verbose) { 2002 stmfRet = stmfGetLogicalUnitProperties( 2003 &(luList->guid[j]), &luProps); 2004 if (stmfRet == STMF_STATUS_SUCCESS) { 2005 printLuProps(&luProps); 2006 } else { 2007 (void) fprintf(stderr, "%s:", 2008 cmdName); 2009 printGuid(&luList->guid[j], 2010 stderr); 2011 (void) fprintf(stderr, "%s\n", 2012 gettext(" get properties " 2013 "failed")); 2014 } 2015 stmfRet = stmfGetViewEntryList( 2016 &(luList->guid[j]), 2017 &viewEntryList); 2018 (void) printf(PROPS_FORMAT, 2019 "View Entry Count"); 2020 if (stmfRet == STMF_STATUS_SUCCESS) { 2021 (void) printf("%d", 2022 viewEntryList->cnt); 2023 } else { 2024 (void) printf("unknown"); 2025 } 2026 (void) printf("\n"); 2027 ret = printExtLuProps( 2028 &(luList->guid[j])); 2029 } 2030 if (found && operandEntered) { 2031 break; 2032 } 2033 } 2034 2035 } 2036 if (operandEntered && !found) { 2037 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2038 operands[i], gettext("not found")); 2039 ret = 1; 2040 } 2041 } 2042 2043 return (ret); 2044 } 2045 2046 static void 2047 printGuid(stmfGuid *guid, FILE *stream) 2048 { 2049 int i; 2050 for (i = 0; i < 16; i++) { 2051 (void) fprintf(stream, "%02X", guid->guid[i]); 2052 } 2053 } 2054 2055 static int 2056 printExtLuProps(stmfGuid *guid) 2057 { 2058 int stmfRet; 2059 luResource hdl = NULL; 2060 int ret = 0; 2061 char propVal[MAXNAMELEN]; 2062 size_t propValSize = sizeof (propVal); 2063 2064 if ((stmfRet = stmfGetLuResource(guid, &hdl)) 2065 != STMF_STATUS_SUCCESS) { 2066 switch (stmfRet) { 2067 case STMF_ERROR_BUSY: 2068 (void) fprintf(stderr, "%s: %s\n", cmdName, 2069 gettext("resource busy")); 2070 break; 2071 case STMF_ERROR_PERM: 2072 (void) fprintf(stderr, "%s: %s\n", cmdName, 2073 gettext("permission denied")); 2074 break; 2075 case STMF_ERROR_NOT_FOUND: 2076 /* No error here */ 2077 return (0); 2078 default: 2079 (void) fprintf(stderr, "%s: %s\n", cmdName, 2080 gettext("get extended properties failed")); 2081 break; 2082 } 2083 return (1); 2084 } 2085 2086 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_FILENAME, propVal, 2087 &propValSize); 2088 (void) printf(PROPS_FORMAT, "Data File"); 2089 if (stmfRet == STMF_STATUS_SUCCESS) { 2090 (void) printf("%s\n", propVal); 2091 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2092 (void) printf("not set\n"); 2093 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2094 (void) printf("prop unavailable in standby\n"); 2095 } else { 2096 (void) printf("<error retrieving property>\n"); 2097 ret++; 2098 } 2099 2100 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_META_FILENAME, propVal, 2101 &propValSize); 2102 (void) printf(PROPS_FORMAT, "Meta File"); 2103 if (stmfRet == STMF_STATUS_SUCCESS) { 2104 (void) printf("%s\n", propVal); 2105 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2106 (void) printf("not set\n"); 2107 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2108 (void) printf("prop unavailable in standby\n"); 2109 } else { 2110 (void) printf("<error retrieving property>\n"); 2111 ret++; 2112 } 2113 2114 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SIZE, propVal, 2115 &propValSize); 2116 (void) printf(PROPS_FORMAT, "Size"); 2117 if (stmfRet == STMF_STATUS_SUCCESS) { 2118 (void) printf("%s\n", propVal); 2119 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2120 (void) printf("not set\n"); 2121 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2122 (void) printf("prop unavailable in standby\n"); 2123 } else { 2124 (void) printf("<error retrieving property>\n"); 2125 ret++; 2126 } 2127 2128 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_BLOCK_SIZE, propVal, 2129 &propValSize); 2130 (void) printf(PROPS_FORMAT, "Block Size"); 2131 if (stmfRet == STMF_STATUS_SUCCESS) { 2132 (void) printf("%s\n", propVal); 2133 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2134 (void) printf("not set\n"); 2135 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2136 (void) printf("prop unavailable in standby\n"); 2137 } else { 2138 (void) printf("<error retrieving property>\n"); 2139 ret++; 2140 } 2141 2142 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_MGMT_URL, propVal, 2143 &propValSize); 2144 (void) printf(PROPS_FORMAT, "Management URL"); 2145 if (stmfRet == STMF_STATUS_SUCCESS) { 2146 (void) printf("%s\n", propVal); 2147 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2148 (void) printf("not set\n"); 2149 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2150 (void) printf("prop unavailable in standby\n"); 2151 } else { 2152 (void) printf("<error retrieving property>\n"); 2153 ret++; 2154 } 2155 2156 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_VID, propVal, 2157 &propValSize); 2158 (void) printf(PROPS_FORMAT, "Vendor ID"); 2159 if (stmfRet == STMF_STATUS_SUCCESS) { 2160 (void) printf("%s\n", propVal); 2161 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2162 (void) printf("not set\n"); 2163 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2164 (void) printf("prop unavailable in standby\n"); 2165 } else { 2166 (void) printf("<error retrieving property>\n"); 2167 ret++; 2168 } 2169 2170 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_PID, propVal, 2171 &propValSize); 2172 (void) printf(PROPS_FORMAT, "Product ID"); 2173 if (stmfRet == STMF_STATUS_SUCCESS) { 2174 (void) printf("%s\n", propVal); 2175 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2176 (void) printf("not set\n"); 2177 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2178 (void) printf("prop unavailable in standby\n"); 2179 } else { 2180 (void) printf("<error retrieving property>\n"); 2181 ret++; 2182 } 2183 2184 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SERIAL_NUM, propVal, 2185 &propValSize); 2186 (void) printf(PROPS_FORMAT, "Serial Num"); 2187 if (stmfRet == STMF_STATUS_SUCCESS) { 2188 (void) printf("%s\n", propVal); 2189 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2190 (void) printf("not set\n"); 2191 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2192 (void) printf("prop unavailable in standby\n"); 2193 } else { 2194 (void) printf("<error retrieving property>\n"); 2195 ret++; 2196 } 2197 2198 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_WRITE_PROTECT, propVal, 2199 &propValSize); 2200 (void) printf(PROPS_FORMAT, "Write Protect"); 2201 if (stmfRet == STMF_STATUS_SUCCESS) { 2202 (void) printf("%s\n", 2203 strcasecmp(propVal, "true") ? "Disabled" : "Enabled"); 2204 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2205 (void) printf("not set\n"); 2206 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2207 (void) printf("prop unavailable in standby\n"); 2208 } else { 2209 (void) printf("<error retrieving property>\n"); 2210 ret++; 2211 } 2212 2213 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_WRITE_CACHE_DISABLE, propVal, 2214 &propValSize); 2215 (void) printf(PROPS_FORMAT, "Writeback Cache"); 2216 if (stmfRet == STMF_STATUS_SUCCESS) { 2217 (void) printf("%s\n", 2218 strcasecmp(propVal, "true") ? "Enabled" : "Disabled"); 2219 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2220 (void) printf("not set\n"); 2221 } else if (stmfRet == STMF_ERROR_NO_PROP_STANDBY) { 2222 (void) printf("prop unavailable in standby\n"); 2223 } else { 2224 (void) printf("<error retrieving property>\n"); 2225 ret++; 2226 } 2227 2228 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal, 2229 &propValSize); 2230 (void) printf(PROPS_FORMAT, "Access State"); 2231 if (stmfRet == STMF_STATUS_SUCCESS) { 2232 if (strcmp(propVal, STMF_ACCESS_ACTIVE) == 0) { 2233 (void) printf("%s\n", "Active"); 2234 } else if (strcmp(propVal, 2235 STMF_ACCESS_ACTIVE_TO_STANDBY) == 0) { 2236 (void) printf("%s\n", "Active->Standby"); 2237 } else if (strcmp(propVal, STMF_ACCESS_STANDBY) == 0) { 2238 (void) printf("%s\n", "Standby"); 2239 } else if (strcmp(propVal, 2240 STMF_ACCESS_STANDBY_TO_ACTIVE) == 0) { 2241 (void) printf("%s\n", "Standby->Active"); 2242 } else { 2243 (void) printf("%s\n", "Unknown"); 2244 } 2245 } else if (stmfRet == STMF_ERROR_NO_PROP) { 2246 (void) printf("not set\n"); 2247 } else { 2248 (void) printf("<error retrieving property>\n"); 2249 ret++; 2250 } 2251 2252 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