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