1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <stdlib.h>
  27 #include <stdio.h>
  28 #include <strings.h>
  29 #include <sys/types.h>
  30 #include <unistd.h>
  31 #include <wchar.h>
  32 #include <libintl.h>
  33 #include <errno.h>
  34 #include <time.h>
  35 #include <string.h>
  36 #include <assert.h>
  37 #include <getopt.h>
  38 #include <cmdparse.h>
  39 #include <libstmf.h>
  40 #include <signal.h>
  41 #include <pthread.h>
  42 #include <locale.h>
  43 
  44 static char *getExecBasename(char *);
  45 static int setLuStandbyFunc(int, char **, cmdOptions_t *, void *);
  46 static int disableAluaFunc(int, char **, cmdOptions_t *, void *);
  47 static int enableAluaFunc(int, char **, cmdOptions_t *, void *);
  48 
  49 #define OPERANDSTRING_LU            "LU-name"
  50 #define OPERANDSTRING_NODE_ID       "node ID (0 or 1)"
  51 
  52 #define VERSION_STRING_MAJOR        "1"
  53 #define VERSION_STRING_MINOR        "0"
  54 #define VERSION_STRING_MAX_LEN      10
  55 
  56 #define GUID_INPUT                  32
  57 
  58 /* tables set up based on cmdparse instructions */
  59 
  60 /* add new options here */
  61 optionTbl_t longOptions[] = {
  62         {NULL, 0, 0, 0}
  63 };
  64 
  65 /*
  66  * Add new subcommands here
  67  */
  68 subCommandProps_t subcommands[] = {
  69         {"standby", setLuStandbyFunc, NULL, NULL, NULL,
  70                 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_LU, NULL},
  71         {"disable", disableAluaFunc, NULL, NULL, NULL,
  72                 OPERAND_NONE, NULL, NULL},
  73         {"enable", enableAluaFunc, NULL, NULL, NULL,
  74                 OPERAND_MANDATORY_SINGLE, OPERANDSTRING_NODE_ID, NULL},
  75         {NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL}
  76 };
  77 
  78 /* globals */
  79 char *cmdName;
  80 
  81 /*
  82  * setLuStandbyFunc
  83  *
  84  * Purpose: set lu to standby
  85  *
  86  */
  87 /*ARGSUSED*/
  88 static int
  89 setLuStandbyFunc(int operandLen, char *operands[], cmdOptions_t *options,
  90     void *args)
  91 {
  92         char sGuid[GUID_INPUT + 1];
  93         stmfGuid inGuid;
  94         unsigned int guid[sizeof (stmfGuid)];
  95         int i;
  96         int ret = 0;
  97 
  98         if (strlen(operands[0]) != GUID_INPUT) {
  99                 (void) fprintf(stderr, "%s: %s: %s %d %s\n", cmdName,
 100                     operands[0], gettext("must be"), GUID_INPUT,
 101                     gettext("hexadecimal digits long"));
 102                 return (1);
 103         }
 104 
 105         bcopy(operands[0], sGuid, GUID_INPUT);
 106 
 107         for (i = 0; i < GUID_INPUT; i++)
 108                 sGuid[i] = tolower(sGuid[i]);
 109         sGuid[i] = 0;
 110 
 111         (void) sscanf(sGuid, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
 112             &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
 113             &guid[6], &guid[7], &guid[8], &guid[9], &guid[10], &guid[11],
 114             &guid[12], &guid[13], &guid[14], &guid[15]);
 115 
 116         for (i = 0; i < sizeof (stmfGuid); i++) {
 117                 inGuid.guid[i] = guid[i];
 118         }
 119 
 120         ret = stmfLuStandby(&inGuid);
 121         if (ret != STMF_STATUS_SUCCESS) {
 122                 switch (ret) {
 123                         case STMF_ERROR_PERM:
 124                                 (void) fprintf(stderr, "%s: %s\n", cmdName,
 125                                     gettext("permission denied"));
 126                                 break;
 127                         case STMF_ERROR_SERVICE_NOT_FOUND:
 128                                 (void) fprintf(stderr, "%s: %s\n", cmdName,
 129                                     gettext("STMF service not found"));
 130                                 break;
 131                         case STMF_ERROR_NOT_FOUND:
 132                                 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
 133                                     operands[0], gettext("not found"));
 134                                 break;
 135                         case STMF_ERROR_SERVICE_DATA_VERSION:
 136                                 (void) fprintf(stderr, "%s: %s\n", cmdName,
 137                                     gettext("STMF service version incorrect"));
 138                                 break;
 139                         default:
 140                                 (void) fprintf(stderr, "%s: %s\n", cmdName,
 141                                     gettext("unknown error"));
 142                                 break;
 143                 }
 144         }
 145         return (ret);
 146 }
 147 
 148 /*
 149  * disableAluaFunc
 150  *
 151  * Purpose: disable alua mode
 152  *
 153  */
 154 /*ARGSUSED*/
 155 static int
 156 disableAluaFunc(int operandLen, char *operands[], cmdOptions_t *options,
 157     void *args)
 158 {
 159         return (stmfSetAluaState(B_FALSE, 0));
 160 }
 161 
 162 /*
 163  * enableAluaFunc
 164  *
 165  * Purpose: enable alua mode
 166  *
 167  */
 168 /*ARGSUSED*/
 169 static int
 170 enableAluaFunc(int operandLen, char *operands[], cmdOptions_t *options,
 171     void *args)
 172 {
 173         uint8_t node_id = 0;
 174         if (operands[0][1] == '1') {
 175                 node_id = 1;
 176         }
 177         return (stmfSetAluaState(B_TRUE, node_id));
 178 }
 179 
 180 
 181 /*
 182  * input:
 183  *  execFullName - exec name of program (argv[0])
 184  *
 185  *  copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net
 186  *  (changed name to lowerCamelCase to keep consistent with this file)
 187  *
 188  * Returns:
 189  *  command name portion of execFullName
 190  */
 191 static char *
 192 getExecBasename(char *execFullname)
 193 {
 194         char *lastSlash, *execBasename;
 195 
 196         /* guard against '/' at end of command invocation */
 197         for (;;) {
 198                 lastSlash = strrchr(execFullname, '/');
 199                 if (lastSlash == NULL) {
 200                         execBasename = execFullname;
 201                         break;
 202                 } else {
 203                         execBasename = lastSlash + 1;
 204                         if (*execBasename == '\0') {
 205                                 *lastSlash = '\0';
 206                                 continue;
 207                         }
 208                         break;
 209                 }
 210         }
 211         return (execBasename);
 212 }
 213 
 214 int
 215 main(int argc, char *argv[])
 216 {
 217         synTables_t synTables;
 218         char versionString[VERSION_STRING_MAX_LEN];
 219         int ret;
 220         int funcRet;
 221         void *subcommandArgs = NULL;
 222 
 223         (void) setlocale(LC_ALL, "");
 224         (void) textdomain(TEXT_DOMAIN);
 225         /* set global command name */
 226         cmdName = getExecBasename(argv[0]);
 227 
 228         (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s",
 229             VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
 230         synTables.versionString = versionString;
 231         synTables.longOptionTbl = &longOptions[0];
 232         synTables.subCommandPropsTbl = &subcommands[0];
 233 
 234         ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
 235         if (ret != 0) {
 236                 return (ret);
 237         }
 238 
 239         return (funcRet);
 240 } /* end main */