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 = {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 /* 1457 * listStateFunc 1458 * 1459 * List the operational and config state of the stmf service 1460 * 1461 */ 1462 /*ARGSUSED*/ 1463 static int 1464 listStateFunc(int operandLen, char *operands[], cmdOptions_t *options, 1465 void *args) 1466 { 1467 int ret; 1468 stmfState state; 1469 1470 if ((ret = stmfGetState(&state)) != STMF_STATUS_SUCCESS) { 1471 switch (ret) { 1472 case STMF_ERROR_PERM: 1473 (void) fprintf(stderr, "%s: %s\n", cmdName, 1474 gettext("permission denied")); 1475 ret++; 1476 break; 1477 case STMF_ERROR_SERVICE_NOT_FOUND: 1478 (void) fprintf(stderr, "%s: %s\n", cmdName, 1479 gettext("STMF service not found")); 1480 ret++; 1481 break; 1482 case STMF_ERROR_BUSY: 1483 (void) fprintf(stderr, "%s: %s\n", cmdName, 1484 gettext("resource busy")); 1485 break; 1486 case STMF_ERROR_SERVICE_DATA_VERSION: 1487 (void) fprintf(stderr, "%s: %s\n", cmdName, 1488 gettext("STMF service version incorrect")); 1489 ret++; 1490 break; 1491 default: 1492 (void) fprintf(stderr, "%s: %s\n", cmdName, 1493 gettext("unknown error")); 1494 ret++; 1495 break; 1496 } 1497 return (1); 1498 } 1499 1500 (void) printf("%-18s: ", "Operational Status"); 1501 switch (state.operationalState) { 1502 case STMF_SERVICE_STATE_ONLINE: 1503 (void) printf("online"); 1504 break; 1505 case STMF_SERVICE_STATE_OFFLINE: 1506 (void) printf("offline"); 1507 break; 1508 case STMF_SERVICE_STATE_ONLINING: 1509 (void) printf("onlining"); 1510 break; 1511 case STMF_SERVICE_STATE_OFFLINING: 1512 (void) printf("offlining"); 1513 break; 1514 default: 1515 (void) printf("unknown"); 1516 break; 1517 } 1518 (void) printf("\n"); 1519 (void) printf("%-18s: ", "Config Status"); 1520 switch (state.configState) { 1521 case STMF_CONFIG_STATE_NONE: 1522 (void) printf("uninitialized"); 1523 break; 1524 case STMF_CONFIG_STATE_INIT: 1525 (void) printf("initializing"); 1526 break; 1527 case STMF_CONFIG_STATE_INIT_DONE: 1528 (void) printf("initialized"); 1529 break; 1530 default: 1531 (void) printf("unknown"); 1532 break; 1533 } 1534 (void) printf("\n"); 1535 return (0); 1536 } 1537 1538 /* 1539 * listTargetFunc 1540 * 1541 * list the targets and optionally their properties 1542 * 1543 */ 1544 /*ARGSUSED*/ 1545 static int 1546 listTargetFunc(int operandLen, char *operands[], cmdOptions_t *options, 1547 void *args) 1548 { 1549 cmdOptions_t *optionList = options; 1550 int ret = 0; 1551 int stmfRet; 1552 int i, j; 1553 int outerLoop; 1554 stmfSessionList *sessionList; 1555 stmfDevid devid; 1556 boolean_t operandEntered, found, verbose = B_FALSE; 1557 stmfDevidList *targetList; 1558 wchar_t targetIdent[STMF_IDENT_LENGTH + 1]; 1559 stmfTargetProperties targetProps; 1560 1561 if ((stmfRet = stmfGetTargetList(&targetList)) != STMF_STATUS_SUCCESS) { 1562 switch (stmfRet) { 1563 case STMF_ERROR_NOT_FOUND: 1564 ret = 0; 1565 break; 1566 case STMF_ERROR_SERVICE_OFFLINE: 1567 (void) fprintf(stderr, "%s: %s\n", cmdName, 1568 gettext("STMF service offline")); 1569 break; 1570 case STMF_ERROR_BUSY: 1571 (void) fprintf(stderr, "%s: %s\n", cmdName, 1572 gettext("resource busy")); 1573 break; 1574 case STMF_ERROR_SERVICE_DATA_VERSION: 1575 (void) fprintf(stderr, "%s: %s\n", cmdName, 1576 gettext("STMF service version incorrect")); 1577 break; 1578 case STMF_ERROR_PERM: 1579 (void) fprintf(stderr, "%s: %s\n", cmdName, 1580 gettext("permission denied")); 1581 break; 1582 default: 1583 (void) fprintf(stderr, "%s: %s\n", cmdName, 1584 gettext("unknown error")); 1585 break; 1586 } 1587 return (1); 1588 } 1589 1590 for (; optionList->optval; optionList++) { 1591 switch (optionList->optval) { 1592 case 'v': 1593 verbose = B_TRUE; 1594 break; 1595 } 1596 } 1597 1598 if (operandLen > 0) { 1599 outerLoop = operandLen; 1600 operandEntered = B_TRUE; 1601 } else { 1602 outerLoop = 1; 1603 operandEntered = B_FALSE; 1604 } 1605 1606 for (i = 0; i < outerLoop; i++) { 1607 if (operandEntered) { 1608 bzero(&devid, sizeof (devid)); 1609 (void) parseDevid(operands[i], &devid); 1610 } 1611 for (found = B_FALSE, j = 0; j < targetList->cnt; j++) { 1612 if (operandEntered) { 1613 if (bcmp(&devid, &(targetList->devid[j]), 1614 sizeof (devid)) == 0) { 1615 found = B_TRUE; 1616 } 1617 } 1618 if ((found && operandEntered) || !operandEntered) { 1619 (void) mbstowcs(targetIdent, 1620 (char *)targetList->devid[j].ident, 1621 STMF_IDENT_LENGTH); 1622 targetIdent[STMF_IDENT_LENGTH] = 0; 1623 (void) printf("Target: %ws\n", targetIdent); 1624 if (verbose) { 1625 stmfRet = stmfGetTargetProperties( 1626 &(targetList->devid[j]), 1627 &targetProps); 1628 if (stmfRet == STMF_STATUS_SUCCESS) { 1629 printTargetProps(&targetProps); 1630 } else { 1631 (void) fprintf(stderr, "%s:", 1632 cmdName); 1633 (void) fprintf(stderr, "%s\n", 1634 gettext(" get properties" 1635 " failed")); 1636 } 1637 stmfRet = stmfGetSessionList( 1638 &(targetList->devid[j]), 1639 &sessionList); 1640 if (stmfRet == STMF_STATUS_SUCCESS) { 1641 printSessionProps(sessionList); 1642 } else { 1643 (void) fprintf(stderr, "%s:", 1644 cmdName); 1645 (void) fprintf(stderr, "%s\n", 1646 gettext(" get session info" 1647 " failed")); 1648 } 1649 } 1650 if (found && operandEntered) { 1651 break; 1652 } 1653 } 1654 1655 } 1656 if (operandEntered && !found) { 1657 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1658 operands[i], "not found"); 1659 ret = 1; 1660 } 1661 } 1662 return (ret); 1663 } 1664 1665 /* 1666 * listViewFunc 1667 * 1668 * list the view entries for the specified logical unit 1669 * 1670 */ 1671 /*ARGSUSED*/ 1672 static int 1673 listViewFunc(int operandLen, char *operands[], cmdOptions_t *options, 1674 void *args) 1675 { 1676 stmfViewEntryList *viewEntryList; 1677 stmfGuid inGuid; 1678 unsigned int guid[sizeof (stmfGuid)]; 1679 int ret = 0; 1680 int stmfRet; 1681 int i, j, outerLoop; 1682 boolean_t found = B_TRUE; 1683 boolean_t operandEntered; 1684 uint16_t outputLuNbr; 1685 wchar_t groupName[sizeof (stmfGroupName)]; 1686 char sGuid[GUID_INPUT + 1]; 1687 1688 1689 for (; options->optval; options++) { 1690 switch (options->optval) { 1691 case 'l': 1692 if (strlen(options->optarg) != GUID_INPUT) { 1693 (void) fprintf(stderr, 1694 "%s: %s: %s%d%s\n", 1695 cmdName, options->optarg, 1696 gettext("must be "), GUID_INPUT, 1697 gettext(" hexadecimal digits" 1698 " long")); 1699 return (1); 1700 } 1701 bcopy(options->optarg, sGuid, GUID_INPUT); 1702 break; 1703 default: 1704 (void) fprintf(stderr, "%s: %c: %s\n", 1705 cmdName, options->optval, 1706 gettext("unknown option")); 1707 return (1); 1708 } 1709 } 1710 1711 if (operandLen > 0) { 1712 outerLoop = operandLen; 1713 operandEntered = B_TRUE; 1714 } else { 1715 outerLoop = 1; 1716 operandEntered = B_FALSE; 1717 } 1718 1719 for (i = 0; i < 32; i++) 1720 sGuid[i] = tolower(sGuid[i]); 1721 sGuid[i] = 0; 1722 1723 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1724 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], 1725 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11], 1726 &guid[12], &guid[13], &guid[14], &guid[15]); 1727 1728 for (i = 0; i < sizeof (stmfGuid); i++) { 1729 inGuid.guid[i] = guid[i]; 1730 } 1731 1732 if ((stmfRet = stmfGetViewEntryList(&inGuid, &viewEntryList)) 1733 != STMF_STATUS_SUCCESS) { 1734 1735 switch (stmfRet) { 1736 case STMF_ERROR_BUSY: 1737 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1738 sGuid, gettext("resource busy")); 1739 break; 1740 case STMF_ERROR_NOT_FOUND: 1741 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1742 sGuid, gettext("no views found")); 1743 break; 1744 case STMF_ERROR_SERVICE_NOT_FOUND: 1745 (void) fprintf(stderr, "%s: %s\n", cmdName, 1746 gettext("STMF service not found")); 1747 break; 1748 case STMF_ERROR_SERVICE_DATA_VERSION: 1749 (void) fprintf(stderr, "%s: %s\n", cmdName, 1750 gettext("STMF service version incorrect")); 1751 break; 1752 case STMF_ERROR_PERM: 1753 (void) fprintf(stderr, "%s: %s\n", cmdName, 1754 gettext("permission denied")); 1755 break; 1756 default: 1757 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1758 sGuid, gettext("unknown error")); 1759 break; 1760 } 1761 return (1); 1762 } 1763 1764 for (i = 0; i < outerLoop; i++) { 1765 for (found = B_FALSE, j = 0; j < viewEntryList->cnt; j++) { 1766 if (operandEntered) { 1767 if (atoi(operands[i]) == 1768 viewEntryList->ve[j].veIndex) { 1769 found = B_TRUE; 1770 } 1771 } 1772 if ((found && operandEntered) || !operandEntered) { 1773 (void) printf("View Entry: %d\n", 1774 viewEntryList->ve[j].veIndex); 1775 (void) printf(VIEW_FORMAT, "Host group"); 1776 if (viewEntryList->ve[j].allHosts) { 1777 (void) printf("All\n"); 1778 } else { 1779 (void) mbstowcs(groupName, 1780 viewEntryList->ve[j].hostGroup, 1781 sizeof (stmfGroupName) - 1); 1782 groupName[sizeof (stmfGroupName) - 1] 1783 = 0; 1784 (void) printf("%ws\n", groupName); 1785 } 1786 (void) printf(VIEW_FORMAT, "Target group"); 1787 if (viewEntryList->ve[j].allTargets) { 1788 (void) printf("All\n"); 1789 } else { 1790 (void) mbstowcs(groupName, 1791 viewEntryList->ve[j].targetGroup, 1792 sizeof (stmfGroupName) - 1); 1793 groupName[sizeof (stmfGroupName) - 1] 1794 = 0; 1795 (void) printf("%ws\n", groupName); 1796 } 1797 outputLuNbr = ((viewEntryList->ve[j].luNbr[0] & 1798 0x3F) << 8) | viewEntryList->ve[j].luNbr[1]; 1799 (void) printf(VIEW_FORMAT, "LUN"); 1800 (void) printf("%d\n", outputLuNbr); 1801 if (found && operandEntered) { 1802 break; 1803 } 1804 } 1805 } 1806 if (operandEntered && !found) { 1807 (void) fprintf(stderr, "%s: %s, %s: %s\n", cmdName, 1808 sGuid, operands[i], gettext("not found")); 1809 ret = 1; 1810 } 1811 } 1812 1813 return (ret); 1814 } 1815 1816 1817 /* 1818 * onlineOfflineLu 1819 * 1820 * Purpose: Online or offline a logical unit 1821 * 1822 * lu - logical unit to online or offline 1823 * 1824 * state - ONLINE_LU 1825 * OFFLINE_LU 1826 */ 1827 static int 1828 onlineOfflineLu(char *lu, int state) 1829 { 1830 char sGuid[GUID_INPUT + 1]; 1831 stmfGuid inGuid; 1832 unsigned int guid[sizeof (stmfGuid)]; 1833 int i; 1834 int ret = 0; 1835 1836 if (strlen(lu) != GUID_INPUT) { 1837 (void) fprintf(stderr, "%s: %s: %s %d %s\n", cmdName, lu, 1838 gettext("must be"), GUID_INPUT, 1839 gettext("hexadecimal digits long")); 1840 return (1); 1841 } 1842 1843 bcopy(lu, sGuid, GUID_INPUT); 1844 1845 for (i = 0; i < 32; i++) 1846 sGuid[i] = tolower(sGuid[i]); 1847 sGuid[i] = 0; 1848 1849 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1850 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], 1851 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11], 1852 &guid[12], &guid[13], &guid[14], &guid[15]); 1853 1854 for (i = 0; i < sizeof (stmfGuid); i++) { 1855 inGuid.guid[i] = guid[i]; 1856 } 1857 1858 if (state == ONLINE_LU) { 1859 ret = stmfOnlineLogicalUnit(&inGuid); 1860 } else if (state == OFFLINE_LU) { 1861 ret = stmfOfflineLogicalUnit(&inGuid); 1862 } 1863 if (ret != STMF_STATUS_SUCCESS) { 1864 switch (ret) { 1865 case STMF_ERROR_PERM: 1866 (void) fprintf(stderr, "%s: %s\n", cmdName, 1867 gettext("permission denied")); 1868 break; 1869 case STMF_ERROR_SERVICE_NOT_FOUND: 1870 (void) fprintf(stderr, "%s: %s\n", cmdName, 1871 gettext("STMF service not found")); 1872 break; 1873 case STMF_ERROR_NOT_FOUND: 1874 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1875 lu, gettext("not found")); 1876 break; 1877 case STMF_ERROR_SERVICE_DATA_VERSION: 1878 (void) fprintf(stderr, "%s: %s\n", cmdName, 1879 gettext("STMF service version incorrect")); 1880 break; 1881 default: 1882 (void) fprintf(stderr, "%s: %s\n", cmdName, 1883 gettext("unknown error")); 1884 break; 1885 } 1886 } 1887 return (ret); 1888 } 1889 1890 /* 1891 * onlineLuFunc 1892 * 1893 * Purpose: Online a logical unit 1894 * 1895 */ 1896 /*ARGSUSED*/ 1897 static int 1898 onlineLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 1899 void *args) 1900 { 1901 return (onlineOfflineLu(operands[0], ONLINE_LU)); 1902 } 1903 1904 /* 1905 * offlineLuFunc 1906 * 1907 * Purpose: Offline a logical unit 1908 * 1909 */ 1910 /*ARGSUSED*/ 1911 static int 1912 offlineLuFunc(int operandLen, char *operands[], cmdOptions_t *options, 1913 void *args) 1914 { 1915 return (onlineOfflineLu(operands[0], OFFLINE_LU)); 1916 } 1917 1918 /* 1919 * onlineOfflineTarget 1920 * 1921 * Purpose: Online or offline a target 1922 * 1923 * target - target to online or offline 1924 * 1925 * state - ONLINE_TARGET 1926 * OFFLINE_TARGET 1927 */ 1928 static int 1929 onlineOfflineTarget(char *target, int state) 1930 { 1931 int ret = 0; 1932 stmfDevid devid; 1933 1934 if (parseDevid(target, &devid) != 0) { 1935 (void) fprintf(stderr, "%s: %s: %s\n", 1936 cmdName, target, gettext("unrecognized device id")); 1937 return (1); 1938 } 1939 if (state == ONLINE_TARGET) { 1940 ret = stmfOnlineTarget(&devid); 1941 } else if (state == OFFLINE_TARGET) { 1942 ret = stmfOfflineTarget(&devid); 1943 } 1944 if (ret != STMF_STATUS_SUCCESS) { 1945 switch (ret) { 1946 case STMF_ERROR_PERM: 1947 (void) fprintf(stderr, "%s: %s\n", cmdName, 1948 gettext("permission denied")); 1949 break; 1950 case STMF_ERROR_SERVICE_NOT_FOUND: 1951 (void) fprintf(stderr, "%s: %s\n", cmdName, 1952 gettext("STMF service not found")); 1953 break; 1954 case STMF_ERROR_NOT_FOUND: 1955 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 1956 target, gettext("not found")); 1957 break; 1958 case STMF_ERROR_SERVICE_DATA_VERSION: 1959 (void) fprintf(stderr, "%s: %s\n", cmdName, 1960 gettext("STMF service version incorrect")); 1961 break; 1962 default: 1963 (void) fprintf(stderr, "%s: %s\n", cmdName, 1964 gettext("unknown error")); 1965 break; 1966 } 1967 } 1968 return (ret); 1969 } 1970 1971 /* 1972 * onlineTargetFunc 1973 * 1974 * Purpose: Online a target 1975 * 1976 */ 1977 /*ARGSUSED*/ 1978 static int 1979 onlineTargetFunc(int operandLen, char *operands[], cmdOptions_t *options, 1980 void *args) 1981 { 1982 return (onlineOfflineTarget(operands[0], ONLINE_TARGET)); 1983 } 1984 1985 /* 1986 * offlineTargetFunc 1987 * 1988 * Purpose: Offline a target 1989 * 1990 */ 1991 /*ARGSUSED*/ 1992 static int 1993 offlineTargetFunc(int operandLen, char *operands[], cmdOptions_t *options, 1994 void *args) 1995 { 1996 return (onlineOfflineTarget(operands[0], OFFLINE_TARGET)); 1997 } 1998 1999 2000 /*ARGSUSED*/ 2001 static int 2002 removeHostGroupMemberFunc(int operandLen, char *operands[], 2003 cmdOptions_t *options, void *args) 2004 { 2005 int i; 2006 int ret = 0; 2007 int stmfRet; 2008 stmfGroupName groupName = {0}; 2009 stmfDevid devid; 2010 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 2011 2012 for (; options->optval; options++) { 2013 switch (options->optval) { 2014 case 'g': 2015 (void) mbstowcs(groupNamePrint, options->optarg, 2016 sizeof (stmfGroupName) - 1); 2017 bcopy(options->optarg, groupName, 2018 strlen(options->optarg)); 2019 break; 2020 default: 2021 (void) fprintf(stderr, "%s: %c: %s\n", 2022 cmdName, options->optval, 2023 gettext("unknown option")); 2024 return (1); 2025 } 2026 } 2027 2028 for (i = 0; i < operandLen; i++) { 2029 if (parseDevid(operands[i], &devid) != 0) { 2030 (void) fprintf(stderr, "%s: %s: %s\n", 2031 cmdName, operands[i], 2032 gettext("unrecognized device id")); 2033 ret++; 2034 continue; 2035 } 2036 stmfRet = stmfRemoveFromHostGroup(&groupName, &devid); 2037 switch (stmfRet) { 2038 case STMF_STATUS_SUCCESS: 2039 break; 2040 case STMF_ERROR_MEMBER_NOT_FOUND: 2041 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2042 operands[i], gettext("not found")); 2043 ret++; 2044 break; 2045 case STMF_ERROR_GROUP_NOT_FOUND: 2046 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 2047 groupNamePrint, gettext("not found")); 2048 ret++; 2049 break; 2050 case STMF_ERROR_BUSY: 2051 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2052 operands[i], "resource busy"); 2053 ret++; 2054 break; 2055 case STMF_ERROR_SERVICE_NOT_FOUND: 2056 (void) fprintf(stderr, "%s: %s\n", cmdName, 2057 gettext("STMF service not found")); 2058 ret++; 2059 break; 2060 case STMF_ERROR_SERVICE_DATA_VERSION: 2061 (void) fprintf(stderr, "%s: %s\n", cmdName, 2062 gettext("STMF service version incorrect")); 2063 ret++; 2064 break; 2065 case STMF_ERROR_PERM: 2066 (void) fprintf(stderr, "%s: %s\n", cmdName, 2067 gettext("permission denied")); 2068 ret++; 2069 break; 2070 default: 2071 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2072 operands[i], gettext("unknown error")); 2073 ret++; 2074 break; 2075 } 2076 } 2077 2078 return (ret); 2079 } 2080 2081 /* 2082 * removeTargetGroupMemberFunc 2083 * 2084 * Removes one or more members from a target group 2085 * 2086 */ 2087 /*ARGSUSED*/ 2088 static int 2089 removeTargetGroupMemberFunc(int operandLen, char *operands[], 2090 cmdOptions_t *options, void *args) 2091 { 2092 int i; 2093 int ret = 0; 2094 int stmfRet; 2095 stmfGroupName groupName = {0}; 2096 stmfDevid devid; 2097 wchar_t groupNamePrint[sizeof (stmfGroupName)] = {0}; 2098 2099 for (; options->optval; options++) { 2100 switch (options->optval) { 2101 case 'g': 2102 (void) mbstowcs(groupNamePrint, options->optarg, 2103 sizeof (stmfGroupName) - 1); 2104 bcopy(options->optarg, groupName, 2105 strlen(options->optarg)); 2106 break; 2107 default: 2108 (void) fprintf(stderr, "%s: %c: %s\n", 2109 cmdName, options->optval, 2110 gettext("unknown option")); 2111 return (1); 2112 } 2113 } 2114 2115 for (i = 0; i < operandLen; i++) { 2116 if (parseDevid(operands[i], &devid) != 0) { 2117 (void) fprintf(stderr, "%s: %s: %s\n", 2118 cmdName, operands[i], 2119 gettext("unrecognized device id")); 2120 ret++; 2121 continue; 2122 } 2123 stmfRet = stmfRemoveFromTargetGroup(&groupName, &devid); 2124 switch (stmfRet) { 2125 case STMF_STATUS_SUCCESS: 2126 break; 2127 case STMF_ERROR_MEMBER_NOT_FOUND: 2128 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2129 operands[i], gettext("not found")); 2130 ret++; 2131 break; 2132 case STMF_ERROR_GROUP_NOT_FOUND: 2133 (void) fprintf(stderr, "%s: %ws: %s\n", cmdName, 2134 groupNamePrint, gettext("not found")); 2135 ret++; 2136 break; 2137 case STMF_ERROR_BUSY: 2138 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2139 operands[i], gettext("resource busy")); 2140 ret++; 2141 break; 2142 case STMF_ERROR_SERVICE_NOT_FOUND: 2143 (void) fprintf(stderr, "%s: %s\n", cmdName, 2144 gettext("STMF service not found")); 2145 ret++; 2146 break; 2147 case STMF_ERROR_PERM: 2148 (void) fprintf(stderr, "%s: %s\n", cmdName, 2149 gettext("permission denied")); 2150 ret++; 2151 break; 2152 case STMF_ERROR_SERVICE_DATA_VERSION: 2153 (void) fprintf(stderr, "%s: %s\n", cmdName, 2154 gettext("STMF service version incorrect")); 2155 ret++; 2156 break; 2157 default: 2158 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2159 operands[i], gettext("unknown error")); 2160 ret++; 2161 break; 2162 } 2163 } 2164 2165 return (ret); 2166 } 2167 2168 /* 2169 * removeViewFunc 2170 * 2171 * Removes one or more view entries from a logical unit 2172 * 2173 */ 2174 /*ARGSUSED*/ 2175 static int 2176 removeViewFunc(int operandLen, char *operands[], cmdOptions_t *options, 2177 void *args) 2178 { 2179 char sGuid[GUID_INPUT + 1]; 2180 stmfViewEntryList *viewEntryList; 2181 stmfGuid inGuid; 2182 uint32_t count; 2183 unsigned int guid[sizeof (stmfGuid)]; 2184 char *endPtr; 2185 uint32_t veNbr; 2186 int i; 2187 boolean_t all = B_FALSE; 2188 boolean_t luInput = B_FALSE; 2189 int ret = 0; 2190 int stmfRet; 2191 2192 /* Note: 'l' is required */ 2193 for (; options->optval; options++) { 2194 switch (options->optval) { 2195 case 'l': 2196 if (strlen(options->optarg) != GUID_INPUT) { 2197 (void) fprintf(stderr, 2198 "%s: %s: %s %d %s\n", 2199 cmdName, options->optarg, 2200 gettext("must be"), GUID_INPUT, 2201 gettext("hexadecimal digits long")); 2202 return (1); 2203 } 2204 bcopy(options->optarg, sGuid, GUID_INPUT); 2205 luInput = B_TRUE; 2206 break; 2207 case 'a': 2208 /* removing all view entries for this GUID */ 2209 all = B_TRUE; 2210 break; 2211 default: 2212 (void) fprintf(stderr, "%s: %c: %s\n", 2213 cmdName, options->optval, 2214 "unknown option"); 2215 return (1); 2216 } 2217 } 2218 2219 if (!all && operandLen == 0) { 2220 (void) fprintf(stderr, "%s: %s\n", cmdName, 2221 gettext("no view entries specified")); 2222 return (1); 2223 } 2224 2225 if (!luInput) { 2226 (void) fprintf(stderr, "%s: %s\n", cmdName, 2227 gettext("logical unit (-l) not specified")); 2228 return (1); 2229 } 2230 2231 for (i = 0; i < 32; i++) 2232 sGuid[i] = tolower(sGuid[i]); 2233 sGuid[i] = 0; 2234 2235 (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 2236 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5], 2237 &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11], 2238 &guid[12], &guid[13], &guid[14], &guid[15]); 2239 2240 for (i = 0; i < sizeof (stmfGuid); i++) { 2241 inGuid.guid[i] = guid[i]; 2242 } 2243 2244 if ((stmfRet = stmfGetViewEntryList(&inGuid, &viewEntryList)) 2245 != STMF_STATUS_SUCCESS) { 2246 2247 switch (stmfRet) { 2248 case STMF_ERROR_BUSY: 2249 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2250 sGuid, gettext("resource busy")); 2251 break; 2252 case STMF_ERROR_NOT_FOUND: 2253 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2254 sGuid, gettext("no views found")); 2255 break; 2256 case STMF_ERROR_SERVICE_NOT_FOUND: 2257 (void) fprintf(stderr, "%s: %s\n", cmdName, 2258 gettext("STMF service not found")); 2259 break; 2260 case STMF_ERROR_SERVICE_DATA_VERSION: 2261 (void) fprintf(stderr, "%s: %s\n", cmdName, 2262 gettext("STMF service version incorrect")); 2263 break; 2264 case STMF_ERROR_PERM: 2265 (void) fprintf(stderr, "%s: %s\n", cmdName, 2266 gettext("permission denied")); 2267 break; 2268 default: 2269 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2270 sGuid, gettext("unknown error")); 2271 break; 2272 } 2273 return (1); 2274 } 2275 2276 if (all) { 2277 count = viewEntryList->cnt; 2278 } else { 2279 count = operandLen; 2280 } 2281 2282 for (i = 0; i < count; i++) { 2283 if (all) { 2284 veNbr = viewEntryList->ve[i].veIndex; 2285 } else { 2286 endPtr = NULL; 2287 veNbr = strtol(operands[i], &endPtr, 10); 2288 if (endPtr && *endPtr != 0) { 2289 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2290 operands[i], gettext("invalid input")); 2291 continue; 2292 } 2293 } 2294 stmfRet = stmfRemoveViewEntry(&inGuid, veNbr); 2295 switch (stmfRet) { 2296 case STMF_STATUS_SUCCESS: 2297 break; 2298 case STMF_ERROR_NOT_FOUND: 2299 (void) fprintf(stderr, "%s: %s: %d: %s\n", 2300 cmdName, sGuid, veNbr, 2301 gettext("not found")); 2302 ret++; 2303 break; 2304 case STMF_ERROR_BUSY: 2305 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, 2306 sGuid, gettext("resource busy")); 2307 ret++; 2308 break; 2309 case STMF_ERROR_SERVICE_NOT_FOUND: 2310 (void) fprintf(stderr, "%s: %s\n", cmdName, 2311 gettext("STMF service not found")); 2312 ret++; 2313 break; 2314 case STMF_ERROR_CONFIG_NONE: 2315 (void) fprintf(stderr, "%s: %s\n", cmdName, 2316 gettext("STMF service is not initialized")); 2317 ret++; 2318 break; 2319 case STMF_ERROR_SERVICE_DATA_VERSION: 2320 (void) fprintf(stderr, "%s: %s\n", cmdName, 2321 gettext("STMF service version incorrect")); 2322 ret++; 2323 break; 2324 default: 2325 (void) fprintf(stderr, "%s: %s, %d: %s", 2326 cmdName, sGuid, veNbr, 2327 gettext("unknown error")); 2328 ret++; 2329 break; 2330 } 2331 } 2332 2333 return (ret); 2334 } 2335 2336 /* 2337 * input: 2338 * execFullName - exec name of program (argv[0]) 2339 * 2340 * copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net 2341 * (changed name to lowerCamelCase to keep consistent with this file) 2342 * 2343 * Returns: 2344 * command name portion of execFullName 2345 */ 2346 static char * 2347 getExecBasename(char *execFullname) 2348 { 2349 char *lastSlash, *execBasename; 2350 2351 /* guard against '/' at end of command invocation */ 2352 for (;;) { 2353 lastSlash = strrchr(execFullname, '/'); 2354 if (lastSlash == NULL) { 2355 execBasename = execFullname; 2356 break; 2357 } else { 2358 execBasename = lastSlash + 1; 2359 if (*execBasename == '\0') { 2360 *lastSlash = '\0'; 2361 continue; 2362 } 2363 break; 2364 } 2365 } 2366 return (execBasename); 2367 } 2368 2369 int 2370 main(int argc, char *argv[]) 2371 { 2372 synTables_t synTables; 2373 char versionString[VERSION_STRING_MAX_LEN]; 2374 int ret; 2375 int funcRet; 2376 void *subcommandArgs = NULL; 2377 2378 (void) setlocale(LC_ALL, ""); 2379 (void) textdomain(TEXT_DOMAIN); 2380 /* set global command name */ 2381 cmdName = getExecBasename(argv[0]); 2382 2383 (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s", 2384 VERSION_STRING_MAJOR, VERSION_STRING_MINOR); 2385 synTables.versionString = versionString; 2386 synTables.longOptionTbl = &longOptions[0]; 2387 synTables.subCommandPropsTbl = &subcommands[0]; 2388 2389 ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet); 2390 if (ret != 0) { 2391 return (ret); 2392 } 2393 2394 return (funcRet); 2395 } /* end main */ 2396