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