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