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