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