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