8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / srptadm / srptadm.c
blob90b248a12d8c307d2914df82fa7584c94fa2ecd8
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <getopt.h>
33 #include <strings.h>
34 #include <ctype.h>
35 #include <libnvpair.h>
36 #include <libintl.h>
37 #include <libgen.h>
38 #include <pwd.h>
39 #include <auth_attr.h>
40 #include <secdb.h>
41 #include <libscf.h>
42 #include <limits.h>
43 #include <locale.h>
44 #include <dirent.h>
46 #include <libstmf.h>
47 #include <libsrpt.h>
49 /* SMF service info */
50 #define STMF_SVC "svc:/system/stmf:default"
52 #define STMF_STALE(ret) {\
53 if (ret == STMF_ERROR_PROV_DATA_STALE) {\
54 (void) fprintf(stderr, "%s\n",\
55 gettext("Configuration changed during processing. "\
56 "Check the configuration, then retry this command "\
57 "if appropriate."));\
61 #define SRPTADM_CHKAUTH(sec) {\
62 if (!chkauthattr(sec, srptadm_uname)) {\
63 (void) fprintf(stderr,\
64 gettext("Error, operation requires authorization %s"),\
65 sec);\
66 (void) fprintf(stderr, "\n");\
67 return (1);\
71 #define PROPS_FORMAT " %-20s: "
73 static struct option srptadm_long[] = {
74 {"enable", no_argument, NULL, 'e'},
75 {"disable", no_argument, NULL, 'd'},
76 {"reset", no_argument, NULL, 'r'},
77 {"help", no_argument, NULL, '?'},
78 {"help", no_argument, NULL, 'h'},
79 {NULL, 0, NULL, 0}
82 static char m_def[] = "srptadm modify-defaults [-e] [-d]";
83 static char l_def[] = "srptadm list-defaults";
84 static char s_tgt[] = "srptadm modify-target [-e] [-d] [-r] <hca>";
85 static char l_tgt[] = "srptadm list-target [<hca>]";
87 /* keep the order of this enum in the same order as the 'subcmds' struct */
88 typedef enum {
89 MODIFY_DEFAULT,
90 LIST_DEFAULT,
91 MODIFY_TARGET,
92 LIST_TARGET,
93 NULL_SUBCMD /* must always be last! */
94 } srptadm_sub_t;
96 typedef struct {
97 char *name;
98 char *shortopts;
99 char *usemsg;
100 } srptadm_subcmds_t;
102 static srptadm_subcmds_t subcmds[] = {
103 {"modify-defaults", "edh?", m_def},
104 {"list-defaults", "h?", l_def},
105 {"modify-target", "edrh?", s_tgt},
106 {"list-target", "h?", l_tgt},
107 {NULL, ":h?", NULL},
110 /* used for checking if user is authorized */
111 static char *srptadm_uname = NULL;
113 /* prototypes */
114 static int get_local_hcas(char **hcaArray, int count);
115 static int print_target_props(char *hca);
116 static int list_target(char *hca);
117 static int disable_target(char *hca);
118 static int reset_target(char *hca);
119 static int list_defaults(void);
120 static int enable_target(char *hca);
121 static int set_default_state(boolean_t enabled);
124 main(int argc, char *argv[])
126 int ret = 0;
127 int idx = NULL_SUBCMD;
128 char c;
129 int newargc = argc;
130 char **newargv = NULL;
131 char *objp;
132 int srptind = 0;
133 struct passwd *pwd = NULL;
134 char *smfstate = NULL;
135 boolean_t reset = B_FALSE;
136 int dflag = 0;
137 int eflag = 0;
139 (void) setlocale(LC_ALL, "");
140 (void) textdomain(TEXT_DOMAIN);
142 if (argc < 2) {
143 ret = 1;
144 goto usage_error;
147 for (idx = 0; subcmds[idx].name != NULL; idx++) {
148 if (strcmp(argv[1], subcmds[idx].name) == 0) {
149 break;
153 /* get the caller's user name for subsequent chkauthattr() calls */
154 pwd = getpwuid(getuid());
155 if (pwd == NULL) {
156 (void) fprintf(stderr, "%s\n",
157 gettext("Could not determine callers user name."));
158 return (1);
161 srptadm_uname = strdup(pwd->pw_name);
163 /* increment past command & subcommand */
164 newargc--;
165 newargv = &(argv[1]);
167 while ((ret == 0) && (newargv)) {
168 c = getopt_long(newargc, newargv, subcmds[idx].shortopts,
169 srptadm_long, &srptind);
170 if (c == -1) {
171 break;
174 switch (c) {
175 case 0:
176 /* flag set by getopt */
177 break;
178 case 'd':
179 dflag++;
180 break;
181 case 'e':
182 eflag++;
183 break;
184 case 'r':
185 reset = B_TRUE;
186 break;
187 case '?':
189 * '?' is returned for both unrecognized
190 * options and if explicitly provided on
191 * the command line. The latter should
192 * be handled the same as -h.
194 if (strcmp(newargv[optind-1], "-?") != 0) {
195 (void) fprintf(stderr,
196 gettext("Unrecognized option %s"),
197 newargv[optind-1]);
198 (void) fprintf(stderr, "\n");
199 ret = 1;
201 goto usage_error;
202 case 'h':
203 goto usage_error;
204 case ':':
205 (void) fprintf(stderr,
206 gettext("Option %s requires an operand."),
207 newargv[optind-1]);
208 (void) fprintf(stderr, "\n");
210 /* fall through to default */
211 default:
212 ret = 1;
213 break;
217 if (ret != 0) {
218 goto usage_error;
221 /* after getopt() to allow handling of -h option */
222 if ((srptadm_sub_t)idx == NULL_SUBCMD) {
223 (void) fprintf(stderr, "%s\n",
224 gettext("Error, no subcommand specified"));
225 ret = 1;
226 goto usage_error;
229 newargc -= optind;
230 if (newargc == 0) {
231 newargv = NULL;
232 objp = NULL;
233 } else {
234 newargv = &(newargv[optind]);
235 objp = newargv[0];
238 if (objp == NULL) {
239 switch ((srptadm_sub_t)idx) {
240 case MODIFY_TARGET:
241 /* These subcommands need operands */
242 ret = 1;
243 goto usage_error;
244 default:
245 break;
249 if (newargc > 1) {
250 switch ((srptadm_sub_t)idx) {
251 case MODIFY_TARGET:
252 case LIST_TARGET:
253 /* These subcommands should have at most one operand */
254 ret = 1;
255 goto usage_error;
257 default:
258 break;
264 * Make sure STMF service is enabled before proceeding.
266 smfstate = smf_get_state(STMF_SVC);
267 if (!smfstate ||
268 (strcmp(smfstate, SCF_STATE_STRING_ONLINE) != 0)) {
269 (void) fprintf(stderr, "%s\n",
270 gettext("The STMF service must be online "
271 "before running this command."));
272 (void) fprintf(stderr,
273 gettext("Use 'svcadm enable -r %s'"), STMF_SVC);
274 (void) fprintf(stderr, "\n");
275 (void) fprintf(stderr, "%s\n",
276 gettext("to enable the service and its prerequisite "
277 "services and/or"));
278 (void) fprintf(stderr,
279 gettext("'svcs -x %s' to determine why it is not online."),
280 STMF_SVC);
281 (void) fprintf(stderr, "\n");
283 return (1);
286 switch ((srptadm_sub_t)idx) {
287 case MODIFY_DEFAULT:
288 if (eflag) {
289 ret = set_default_state(B_TRUE);
290 } else if (dflag) {
291 ret = set_default_state(B_FALSE);
292 } else {
293 ret = 1;
294 goto usage_error;
296 break;
297 case LIST_DEFAULT:
298 ret = list_defaults();
299 break;
300 case MODIFY_TARGET:
301 if (reset) {
302 ret = reset_target(objp);
303 } else if (eflag) {
304 ret = enable_target(objp);
305 } else if (dflag) {
306 ret = disable_target(objp);
307 } else {
308 ret = 1;
309 goto usage_error;
311 break;
312 case LIST_TARGET:
313 ret = list_target(objp);
314 break;
315 default:
316 ret = 1;
317 goto usage_error;
320 if (ret != 0) {
321 (void) fprintf(stderr,
322 gettext("srptadm %s failed with error %d"),
323 subcmds[idx].name, ret);
324 (void) fprintf(stderr, "\n");
326 return (ret);
328 usage_error:
329 if (subcmds[idx].name) {
330 (void) printf("%s\n", gettext(subcmds[idx].usemsg));
331 } else {
332 /* overall usage */
333 (void) printf("%s\n\n", gettext("srptadm usage:"));
334 for (idx = 0; subcmds[idx].name != NULL; idx++) {
335 if (!subcmds[idx].usemsg) {
336 continue;
338 (void) printf("\t%s\n", gettext(subcmds[idx].usemsg));
342 return (ret);
345 static int
346 set_default_state(boolean_t enabled)
348 int ret;
349 char *sec = "solaris.smf.modify.stmf";
351 SRPTADM_CHKAUTH(sec);
353 ret = srpt_SetDefaultState(enabled);
355 return (ret);
358 static int
359 enable_target(char *hca)
361 int ret;
362 char *sec = "solaris.smf.modify.stmf";
364 SRPTADM_CHKAUTH(sec);
366 ret = srpt_SetTargetState(hca, B_TRUE);
368 return (ret);
371 static int
372 disable_target(char *hca)
374 int ret;
375 char *sec = "solaris.smf.modify.stmf";
377 SRPTADM_CHKAUTH(sec);
379 ret = srpt_SetTargetState(hca, B_FALSE);
381 return (ret);
384 static int
385 reset_target(char *hca)
387 int ret;
388 char *sec = "solaris.smf.modify.stmf";
390 SRPTADM_CHKAUTH(sec);
392 ret = srpt_ResetTarget(hca);
394 return (ret);
397 static int
398 list_defaults(void)
400 int ret;
401 char *sec = "solaris.smf.read.stmf";
402 boolean_t enabled;
404 SRPTADM_CHKAUTH(sec);
406 /* only state set as default for now */
407 ret = srpt_GetDefaultState(&enabled);
409 if (ret == 0) {
410 (void) printf("%s:\n\n",
411 gettext("SRP Target Service Default Properties"));
413 (void) printf(" %s:\t",
414 gettext("Target creation enabled by default"));
416 if (enabled) {
417 (void) printf("%s\n", gettext("true"));
418 } else {
419 (void) printf("%s\n", gettext("false"));
423 return (ret);
426 static int
427 list_target(char *hca)
429 int ret;
430 char *sec = "solaris.smf.read.stmf";
431 char *hcaArr[1024]; /* way bigger than we'll ever see */
432 int i;
434 SRPTADM_CHKAUTH(sec);
436 if (hca != NULL) {
437 ret = print_target_props(hca);
438 return (ret);
441 /* get list of HCAs configured on this system, from /dev/cfg */
442 (void) memset(&hcaArr, 0, 1024 * sizeof (char *));
444 ret = get_local_hcas(hcaArr, sizeof (hcaArr));
445 if (ret == ETOOMANYREFS) {
446 (void) fprintf(stderr, "Internal error: too many HCAs\n");
447 goto done;
448 } else if (ret != 0) {
449 (void) fprintf(stderr, "Error getting list of HCAs: %d\n", ret);
450 goto done;
453 for (i = 0; i < 1024; i++) {
454 if (hcaArr[i] == NULL) {
455 break;
457 ret = print_target_props(hcaArr[i]);
460 done:
461 for (i = 0; i < 1024; i++) {
462 if (hcaArr[i] == NULL) {
463 break;
465 free(hcaArr[i]);
468 return (ret);
471 static int
472 print_target_props(char *hca)
474 int ret;
475 boolean_t enabled;
476 char buf[32];
477 char euibuf[64];
478 uint64_t hcaguid;
479 stmfDevid devid;
480 stmfTargetProperties props;
481 char *state;
483 ret = srpt_NormalizeGuid(hca, buf, sizeof (buf), &hcaguid);
484 if (ret != 0) {
485 (void) fprintf(stderr, "Invalid target HCA: %s\n",
486 hca);
487 return (ret);
490 /* only property set is enabled */
491 ret = srpt_GetTargetState(buf, &enabled);
492 if (ret != 0) {
493 (void) fprintf(stderr,
494 "Could not get enabled state for %s: %d\n",
495 buf, ret);
496 return (ret);
499 (void) printf("Target HCA %s:\n", buf);
501 (void) printf(PROPS_FORMAT, gettext("Enabled"));
503 if (enabled) {
504 (void) printf("%s\n", gettext("true"));
505 } else {
506 (void) printf("%s\n", gettext("false"));
509 state = "-";
511 (void) snprintf(euibuf, sizeof (euibuf), "eui.%016llX", hcaguid);
513 ret = stmfDevidFromIscsiName(euibuf, &devid);
514 if (ret == STMF_STATUS_SUCCESS) {
515 ret = stmfGetTargetProperties(&devid, &props);
516 if (ret == STMF_STATUS_SUCCESS) {
517 if (props.status == STMF_TARGET_PORT_ONLINE) {
518 state = "online";
519 } else {
520 state = "offline";
525 (void) printf(PROPS_FORMAT, gettext("SRP Target Name"));
526 (void) printf("%s\n", euibuf);
527 (void) printf(PROPS_FORMAT, gettext("Operational Status"));
528 (void) printf("%s\n", state);
530 (void) printf("\n");
532 return (0);
536 static int
537 get_local_hcas(char **hcaArray, int count)
539 int ret = 0;
540 char *cfgdir = "/dev/cfg";
541 DIR *dirp = NULL;
542 struct dirent *entry;
543 int idx = 0;
544 char *bufp;
546 if ((hcaArray == NULL) || (count == 0)) {
547 return (EINVAL);
550 dirp = opendir(cfgdir);
552 if (dirp == NULL) {
553 ret = errno;
554 (void) fprintf(stderr, "Could not open %s: errno %d\n",
555 cfgdir, ret);
556 return (ret);
559 while ((entry = readdir(dirp)) != NULL) {
560 bufp = &entry->d_name[0];
562 if (strncmp(bufp, "hca:", 4) != 0) {
563 continue;
566 bufp += 4;
568 hcaArray[idx] = strdup(bufp);
569 if (hcaArray[idx] == NULL) {
570 ret = ENOMEM;
571 break;
573 idx++;
575 if (idx >= count) {
576 ret = ETOOMANYREFS;
577 break;
581 return (ret);