xref: /onnv-gate/usr/src/cmd/srptadm/srptadm.c (revision 12075:b143b9fb49fc)
1*12075SSusan.Gleeson@Sun.COM /*
2*12075SSusan.Gleeson@Sun.COM  * CDDL HEADER START
3*12075SSusan.Gleeson@Sun.COM  *
4*12075SSusan.Gleeson@Sun.COM  * The contents of this file are subject to the terms of the
5*12075SSusan.Gleeson@Sun.COM  * Common Development and Distribution License (the "License").
6*12075SSusan.Gleeson@Sun.COM  * You may not use this file except in compliance with the License.
7*12075SSusan.Gleeson@Sun.COM  *
8*12075SSusan.Gleeson@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12075SSusan.Gleeson@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12075SSusan.Gleeson@Sun.COM  * See the License for the specific language governing permissions
11*12075SSusan.Gleeson@Sun.COM  * and limitations under the License.
12*12075SSusan.Gleeson@Sun.COM  *
13*12075SSusan.Gleeson@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12075SSusan.Gleeson@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12075SSusan.Gleeson@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12075SSusan.Gleeson@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12075SSusan.Gleeson@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12075SSusan.Gleeson@Sun.COM  *
19*12075SSusan.Gleeson@Sun.COM  * CDDL HEADER END
20*12075SSusan.Gleeson@Sun.COM  */
21*12075SSusan.Gleeson@Sun.COM /*
22*12075SSusan.Gleeson@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23*12075SSusan.Gleeson@Sun.COM  */
24*12075SSusan.Gleeson@Sun.COM #include <stdlib.h>
25*12075SSusan.Gleeson@Sun.COM #include <stdio.h>
26*12075SSusan.Gleeson@Sun.COM #include <sys/types.h>
27*12075SSusan.Gleeson@Sun.COM #include <sys/stat.h>
28*12075SSusan.Gleeson@Sun.COM #include <fcntl.h>
29*12075SSusan.Gleeson@Sun.COM #include <unistd.h>
30*12075SSusan.Gleeson@Sun.COM #include <errno.h>
31*12075SSusan.Gleeson@Sun.COM #include <string.h>
32*12075SSusan.Gleeson@Sun.COM #include <getopt.h>
33*12075SSusan.Gleeson@Sun.COM #include <strings.h>
34*12075SSusan.Gleeson@Sun.COM #include <ctype.h>
35*12075SSusan.Gleeson@Sun.COM #include <libnvpair.h>
36*12075SSusan.Gleeson@Sun.COM #include <libintl.h>
37*12075SSusan.Gleeson@Sun.COM #include <libgen.h>
38*12075SSusan.Gleeson@Sun.COM #include <pwd.h>
39*12075SSusan.Gleeson@Sun.COM #include <auth_attr.h>
40*12075SSusan.Gleeson@Sun.COM #include <secdb.h>
41*12075SSusan.Gleeson@Sun.COM #include <libscf.h>
42*12075SSusan.Gleeson@Sun.COM #include <limits.h>
43*12075SSusan.Gleeson@Sun.COM #include <locale.h>
44*12075SSusan.Gleeson@Sun.COM #include <dirent.h>
45*12075SSusan.Gleeson@Sun.COM 
46*12075SSusan.Gleeson@Sun.COM #include <libstmf.h>
47*12075SSusan.Gleeson@Sun.COM #include <libsrpt.h>
48*12075SSusan.Gleeson@Sun.COM 
49*12075SSusan.Gleeson@Sun.COM /* SMF service info */
50*12075SSusan.Gleeson@Sun.COM #define	STMF_SVC	"svc:/system/stmf:default"
51*12075SSusan.Gleeson@Sun.COM 
52*12075SSusan.Gleeson@Sun.COM #define	STMF_STALE(ret) {\
53*12075SSusan.Gleeson@Sun.COM 	if (ret == STMF_ERROR_PROV_DATA_STALE) {\
54*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "%s\n",\
55*12075SSusan.Gleeson@Sun.COM 		    gettext("Configuration changed during processing.  "\
56*12075SSusan.Gleeson@Sun.COM 		    "Check the configuration, then retry this command "\
57*12075SSusan.Gleeson@Sun.COM 		    "if appropriate."));\
58*12075SSusan.Gleeson@Sun.COM 	}\
59*12075SSusan.Gleeson@Sun.COM }
60*12075SSusan.Gleeson@Sun.COM 
61*12075SSusan.Gleeson@Sun.COM #define	SRPTADM_CHKAUTH(sec) {\
62*12075SSusan.Gleeson@Sun.COM 	if (!chkauthattr(sec, srptadm_uname)) {\
63*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr,\
64*12075SSusan.Gleeson@Sun.COM 		    gettext("Error, operation requires authorization %s"),\
65*12075SSusan.Gleeson@Sun.COM 		    sec);\
66*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "\n");\
67*12075SSusan.Gleeson@Sun.COM 		return (1);\
68*12075SSusan.Gleeson@Sun.COM 	}\
69*12075SSusan.Gleeson@Sun.COM }
70*12075SSusan.Gleeson@Sun.COM 
71*12075SSusan.Gleeson@Sun.COM #define	PROPS_FORMAT	"    %-20s: "
72*12075SSusan.Gleeson@Sun.COM 
73*12075SSusan.Gleeson@Sun.COM static struct option srptadm_long[] = {
74*12075SSusan.Gleeson@Sun.COM 	{"enable",		no_argument,		NULL, 'e'},
75*12075SSusan.Gleeson@Sun.COM 	{"disable",		no_argument,		NULL, 'd'},
76*12075SSusan.Gleeson@Sun.COM 	{"reset",		no_argument,		NULL, 'r'},
77*12075SSusan.Gleeson@Sun.COM 	{"help",		no_argument,		NULL, '?'},
78*12075SSusan.Gleeson@Sun.COM 	{"help",		no_argument,		NULL, 'h'},
79*12075SSusan.Gleeson@Sun.COM 	{NULL, 0, NULL, 0}
80*12075SSusan.Gleeson@Sun.COM };
81*12075SSusan.Gleeson@Sun.COM 
82*12075SSusan.Gleeson@Sun.COM static char m_def[] = "srptadm modify-defaults [-e] [-d]";
83*12075SSusan.Gleeson@Sun.COM static char l_def[] = "srptadm list-defaults";
84*12075SSusan.Gleeson@Sun.COM static char s_tgt[] = "srptadm modify-target [-e] [-d] [-r] <hca>";
85*12075SSusan.Gleeson@Sun.COM static char l_tgt[] = "srptadm list-target [<hca>]";
86*12075SSusan.Gleeson@Sun.COM 
87*12075SSusan.Gleeson@Sun.COM /* keep the order of this enum in the same order as the 'subcmds' struct */
88*12075SSusan.Gleeson@Sun.COM typedef enum {
89*12075SSusan.Gleeson@Sun.COM 	MODIFY_DEFAULT,
90*12075SSusan.Gleeson@Sun.COM 	LIST_DEFAULT,
91*12075SSusan.Gleeson@Sun.COM 	MODIFY_TARGET,
92*12075SSusan.Gleeson@Sun.COM 	LIST_TARGET,
93*12075SSusan.Gleeson@Sun.COM 	NULL_SUBCMD	/* must always be last! */
94*12075SSusan.Gleeson@Sun.COM } srptadm_sub_t;
95*12075SSusan.Gleeson@Sun.COM 
96*12075SSusan.Gleeson@Sun.COM typedef struct {
97*12075SSusan.Gleeson@Sun.COM 	char		*name;
98*12075SSusan.Gleeson@Sun.COM 	char		*shortopts;
99*12075SSusan.Gleeson@Sun.COM 	char		*usemsg;
100*12075SSusan.Gleeson@Sun.COM } srptadm_subcmds_t;
101*12075SSusan.Gleeson@Sun.COM 
102*12075SSusan.Gleeson@Sun.COM static srptadm_subcmds_t	subcmds[] = {
103*12075SSusan.Gleeson@Sun.COM 	{"modify-defaults", "edh?", m_def},
104*12075SSusan.Gleeson@Sun.COM 	{"list-defaults", "h?", l_def},
105*12075SSusan.Gleeson@Sun.COM 	{"modify-target", "edrh?", s_tgt},
106*12075SSusan.Gleeson@Sun.COM 	{"list-target", "h?", l_tgt},
107*12075SSusan.Gleeson@Sun.COM 	{NULL, ":h?", NULL},
108*12075SSusan.Gleeson@Sun.COM };
109*12075SSusan.Gleeson@Sun.COM 
110*12075SSusan.Gleeson@Sun.COM /* used for checking if user is authorized */
111*12075SSusan.Gleeson@Sun.COM static char *srptadm_uname = NULL;
112*12075SSusan.Gleeson@Sun.COM 
113*12075SSusan.Gleeson@Sun.COM /* prototypes */
114*12075SSusan.Gleeson@Sun.COM static int get_local_hcas(char **hcaArray, int count);
115*12075SSusan.Gleeson@Sun.COM static int print_target_props(char *hca);
116*12075SSusan.Gleeson@Sun.COM static int list_target(char *hca);
117*12075SSusan.Gleeson@Sun.COM static int disable_target(char *hca);
118*12075SSusan.Gleeson@Sun.COM static int reset_target(char *hca);
119*12075SSusan.Gleeson@Sun.COM static int list_defaults(void);
120*12075SSusan.Gleeson@Sun.COM static int enable_target(char *hca);
121*12075SSusan.Gleeson@Sun.COM static int set_default_state(boolean_t enabled);
122*12075SSusan.Gleeson@Sun.COM 
123*12075SSusan.Gleeson@Sun.COM int
main(int argc,char * argv[])124*12075SSusan.Gleeson@Sun.COM main(int argc, char *argv[])
125*12075SSusan.Gleeson@Sun.COM {
126*12075SSusan.Gleeson@Sun.COM 	int		ret = 0;
127*12075SSusan.Gleeson@Sun.COM 	int		idx = NULL_SUBCMD;
128*12075SSusan.Gleeson@Sun.COM 	char		c;
129*12075SSusan.Gleeson@Sun.COM 	int		newargc = argc;
130*12075SSusan.Gleeson@Sun.COM 	char		**newargv = NULL;
131*12075SSusan.Gleeson@Sun.COM 	char		*objp;
132*12075SSusan.Gleeson@Sun.COM 	int		srptind = 0;
133*12075SSusan.Gleeson@Sun.COM 	struct passwd	*pwd = NULL;
134*12075SSusan.Gleeson@Sun.COM 	char		*smfstate = NULL;
135*12075SSusan.Gleeson@Sun.COM 	boolean_t	reset = B_FALSE;
136*12075SSusan.Gleeson@Sun.COM 	int		dflag = 0;
137*12075SSusan.Gleeson@Sun.COM 	int		eflag = 0;
138*12075SSusan.Gleeson@Sun.COM 
139*12075SSusan.Gleeson@Sun.COM 	(void) setlocale(LC_ALL, "");
140*12075SSusan.Gleeson@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
141*12075SSusan.Gleeson@Sun.COM 
142*12075SSusan.Gleeson@Sun.COM 	if (argc < 2) {
143*12075SSusan.Gleeson@Sun.COM 		ret = 1;
144*12075SSusan.Gleeson@Sun.COM 		goto usage_error;
145*12075SSusan.Gleeson@Sun.COM 	}
146*12075SSusan.Gleeson@Sun.COM 
147*12075SSusan.Gleeson@Sun.COM 	for (idx = 0; subcmds[idx].name != NULL; idx++) {
148*12075SSusan.Gleeson@Sun.COM 		if (strcmp(argv[1], subcmds[idx].name) == 0) {
149*12075SSusan.Gleeson@Sun.COM 			break;
150*12075SSusan.Gleeson@Sun.COM 		}
151*12075SSusan.Gleeson@Sun.COM 	}
152*12075SSusan.Gleeson@Sun.COM 
153*12075SSusan.Gleeson@Sun.COM 	/* get the caller's user name for subsequent chkauthattr() calls */
154*12075SSusan.Gleeson@Sun.COM 	pwd = getpwuid(getuid());
155*12075SSusan.Gleeson@Sun.COM 	if (pwd == NULL) {
156*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "%s\n",
157*12075SSusan.Gleeson@Sun.COM 		    gettext("Could not determine callers user name."));
158*12075SSusan.Gleeson@Sun.COM 		return (1);
159*12075SSusan.Gleeson@Sun.COM 	}
160*12075SSusan.Gleeson@Sun.COM 
161*12075SSusan.Gleeson@Sun.COM 	srptadm_uname = strdup(pwd->pw_name);
162*12075SSusan.Gleeson@Sun.COM 
163*12075SSusan.Gleeson@Sun.COM 	/* increment past command & subcommand */
164*12075SSusan.Gleeson@Sun.COM 	newargc--;
165*12075SSusan.Gleeson@Sun.COM 	newargv = &(argv[1]);
166*12075SSusan.Gleeson@Sun.COM 
167*12075SSusan.Gleeson@Sun.COM 	while ((ret == 0) && (newargv)) {
168*12075SSusan.Gleeson@Sun.COM 		c = getopt_long(newargc, newargv, subcmds[idx].shortopts,
169*12075SSusan.Gleeson@Sun.COM 		    srptadm_long, &srptind);
170*12075SSusan.Gleeson@Sun.COM 		if (c == -1) {
171*12075SSusan.Gleeson@Sun.COM 			break;
172*12075SSusan.Gleeson@Sun.COM 		}
173*12075SSusan.Gleeson@Sun.COM 
174*12075SSusan.Gleeson@Sun.COM 		switch (c) {
175*12075SSusan.Gleeson@Sun.COM 			case 0:
176*12075SSusan.Gleeson@Sun.COM 				/* flag set by getopt */
177*12075SSusan.Gleeson@Sun.COM 				break;
178*12075SSusan.Gleeson@Sun.COM 			case 'd':
179*12075SSusan.Gleeson@Sun.COM 				dflag++;
180*12075SSusan.Gleeson@Sun.COM 				break;
181*12075SSusan.Gleeson@Sun.COM 			case 'e':
182*12075SSusan.Gleeson@Sun.COM 				eflag++;
183*12075SSusan.Gleeson@Sun.COM 				break;
184*12075SSusan.Gleeson@Sun.COM 			case 'r':
185*12075SSusan.Gleeson@Sun.COM 				reset = B_TRUE;
186*12075SSusan.Gleeson@Sun.COM 				break;
187*12075SSusan.Gleeson@Sun.COM 			case '?':
188*12075SSusan.Gleeson@Sun.COM 				/*
189*12075SSusan.Gleeson@Sun.COM 				 * '?' is returned for both unrecognized
190*12075SSusan.Gleeson@Sun.COM 				 * options and if explicitly provided on
191*12075SSusan.Gleeson@Sun.COM 				 * the command line.  The latter should
192*12075SSusan.Gleeson@Sun.COM 				 * be handled the same as -h.
193*12075SSusan.Gleeson@Sun.COM 				 */
194*12075SSusan.Gleeson@Sun.COM 				if (strcmp(newargv[optind-1], "-?") != 0) {
195*12075SSusan.Gleeson@Sun.COM 					(void) fprintf(stderr,
196*12075SSusan.Gleeson@Sun.COM 					    gettext("Unrecognized option %s"),
197*12075SSusan.Gleeson@Sun.COM 					    newargv[optind-1]);
198*12075SSusan.Gleeson@Sun.COM 					(void) fprintf(stderr, "\n");
199*12075SSusan.Gleeson@Sun.COM 					ret = 1;
200*12075SSusan.Gleeson@Sun.COM 				}
201*12075SSusan.Gleeson@Sun.COM 				goto usage_error;
202*12075SSusan.Gleeson@Sun.COM 			case 'h':
203*12075SSusan.Gleeson@Sun.COM 				goto usage_error;
204*12075SSusan.Gleeson@Sun.COM 			case ':':
205*12075SSusan.Gleeson@Sun.COM 				(void) fprintf(stderr,
206*12075SSusan.Gleeson@Sun.COM 				    gettext("Option %s requires an operand."),
207*12075SSusan.Gleeson@Sun.COM 				    newargv[optind-1]);
208*12075SSusan.Gleeson@Sun.COM 				(void) fprintf(stderr, "\n");
209*12075SSusan.Gleeson@Sun.COM 
210*12075SSusan.Gleeson@Sun.COM 				/* fall through to default */
211*12075SSusan.Gleeson@Sun.COM 			default:
212*12075SSusan.Gleeson@Sun.COM 				ret = 1;
213*12075SSusan.Gleeson@Sun.COM 				break;
214*12075SSusan.Gleeson@Sun.COM 		}
215*12075SSusan.Gleeson@Sun.COM 	}
216*12075SSusan.Gleeson@Sun.COM 
217*12075SSusan.Gleeson@Sun.COM 	if (ret != 0) {
218*12075SSusan.Gleeson@Sun.COM 		goto usage_error;
219*12075SSusan.Gleeson@Sun.COM 	}
220*12075SSusan.Gleeson@Sun.COM 
221*12075SSusan.Gleeson@Sun.COM 	/* after getopt() to allow handling of -h option */
222*12075SSusan.Gleeson@Sun.COM 	if ((srptadm_sub_t)idx == NULL_SUBCMD) {
223*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "%s\n",
224*12075SSusan.Gleeson@Sun.COM 		    gettext("Error, no subcommand specified"));
225*12075SSusan.Gleeson@Sun.COM 		ret = 1;
226*12075SSusan.Gleeson@Sun.COM 		goto usage_error;
227*12075SSusan.Gleeson@Sun.COM 	}
228*12075SSusan.Gleeson@Sun.COM 
229*12075SSusan.Gleeson@Sun.COM 	newargc -= optind;
230*12075SSusan.Gleeson@Sun.COM 	if (newargc == 0) {
231*12075SSusan.Gleeson@Sun.COM 		newargv = NULL;
232*12075SSusan.Gleeson@Sun.COM 		objp = NULL;
233*12075SSusan.Gleeson@Sun.COM 	} else {
234*12075SSusan.Gleeson@Sun.COM 		newargv = &(newargv[optind]);
235*12075SSusan.Gleeson@Sun.COM 		objp = newargv[0];
236*12075SSusan.Gleeson@Sun.COM 	}
237*12075SSusan.Gleeson@Sun.COM 
238*12075SSusan.Gleeson@Sun.COM 	if (objp == NULL) {
239*12075SSusan.Gleeson@Sun.COM 		switch ((srptadm_sub_t)idx) {
240*12075SSusan.Gleeson@Sun.COM 		case MODIFY_TARGET:
241*12075SSusan.Gleeson@Sun.COM 			/* These subcommands need operands */
242*12075SSusan.Gleeson@Sun.COM 			ret = 1;
243*12075SSusan.Gleeson@Sun.COM 			goto usage_error;
244*12075SSusan.Gleeson@Sun.COM 		default:
245*12075SSusan.Gleeson@Sun.COM 			break;
246*12075SSusan.Gleeson@Sun.COM 		}
247*12075SSusan.Gleeson@Sun.COM 	}
248*12075SSusan.Gleeson@Sun.COM 
249*12075SSusan.Gleeson@Sun.COM 	if (newargc > 1) {
250*12075SSusan.Gleeson@Sun.COM 		switch ((srptadm_sub_t)idx) {
251*12075SSusan.Gleeson@Sun.COM 		case MODIFY_TARGET:
252*12075SSusan.Gleeson@Sun.COM 		case LIST_TARGET:
253*12075SSusan.Gleeson@Sun.COM 			/* These subcommands should have at most one operand */
254*12075SSusan.Gleeson@Sun.COM 			ret = 1;
255*12075SSusan.Gleeson@Sun.COM 			goto usage_error;
256*12075SSusan.Gleeson@Sun.COM 
257*12075SSusan.Gleeson@Sun.COM 		default:
258*12075SSusan.Gleeson@Sun.COM 			break;
259*12075SSusan.Gleeson@Sun.COM 		}
260*12075SSusan.Gleeson@Sun.COM 	}
261*12075SSusan.Gleeson@Sun.COM 
262*12075SSusan.Gleeson@Sun.COM 
263*12075SSusan.Gleeson@Sun.COM 	/*
264*12075SSusan.Gleeson@Sun.COM 	 * Make sure STMF service is enabled before proceeding.
265*12075SSusan.Gleeson@Sun.COM 	 */
266*12075SSusan.Gleeson@Sun.COM 	smfstate = smf_get_state(STMF_SVC);
267*12075SSusan.Gleeson@Sun.COM 	if (!smfstate ||
268*12075SSusan.Gleeson@Sun.COM 	    (strcmp(smfstate, SCF_STATE_STRING_ONLINE) != 0)) {
269*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "%s\n",
270*12075SSusan.Gleeson@Sun.COM 		    gettext("The STMF service must be online "
271*12075SSusan.Gleeson@Sun.COM 		    "before running this command."));
272*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr,
273*12075SSusan.Gleeson@Sun.COM 		    gettext("Use 'svcadm enable -r %s'"), STMF_SVC);
274*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "\n");
275*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "%s\n",
276*12075SSusan.Gleeson@Sun.COM 		    gettext("to enable the service and its prerequisite "
277*12075SSusan.Gleeson@Sun.COM 		    "services and/or"));
278*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr,
279*12075SSusan.Gleeson@Sun.COM 		    gettext("'svcs -x %s' to determine why it is not online."),
280*12075SSusan.Gleeson@Sun.COM 		    STMF_SVC);
281*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "\n");
282*12075SSusan.Gleeson@Sun.COM 
283*12075SSusan.Gleeson@Sun.COM 		return (1);
284*12075SSusan.Gleeson@Sun.COM 	}
285*12075SSusan.Gleeson@Sun.COM 
286*12075SSusan.Gleeson@Sun.COM 	switch ((srptadm_sub_t)idx) {
287*12075SSusan.Gleeson@Sun.COM 		case MODIFY_DEFAULT:
288*12075SSusan.Gleeson@Sun.COM 			if (eflag) {
289*12075SSusan.Gleeson@Sun.COM 				ret = set_default_state(B_TRUE);
290*12075SSusan.Gleeson@Sun.COM 			} else if (dflag) {
291*12075SSusan.Gleeson@Sun.COM 				ret = set_default_state(B_FALSE);
292*12075SSusan.Gleeson@Sun.COM 			} else {
293*12075SSusan.Gleeson@Sun.COM 				ret = 1;
294*12075SSusan.Gleeson@Sun.COM 				goto usage_error;
295*12075SSusan.Gleeson@Sun.COM 			}
296*12075SSusan.Gleeson@Sun.COM 			break;
297*12075SSusan.Gleeson@Sun.COM 		case LIST_DEFAULT:
298*12075SSusan.Gleeson@Sun.COM 			ret = list_defaults();
299*12075SSusan.Gleeson@Sun.COM 			break;
300*12075SSusan.Gleeson@Sun.COM 		case MODIFY_TARGET:
301*12075SSusan.Gleeson@Sun.COM 			if (reset) {
302*12075SSusan.Gleeson@Sun.COM 				ret = reset_target(objp);
303*12075SSusan.Gleeson@Sun.COM 			} else if (eflag) {
304*12075SSusan.Gleeson@Sun.COM 				ret = enable_target(objp);
305*12075SSusan.Gleeson@Sun.COM 			} else if (dflag) {
306*12075SSusan.Gleeson@Sun.COM 				ret = disable_target(objp);
307*12075SSusan.Gleeson@Sun.COM 			} else {
308*12075SSusan.Gleeson@Sun.COM 				ret = 1;
309*12075SSusan.Gleeson@Sun.COM 				goto usage_error;
310*12075SSusan.Gleeson@Sun.COM 			}
311*12075SSusan.Gleeson@Sun.COM 			break;
312*12075SSusan.Gleeson@Sun.COM 		case LIST_TARGET:
313*12075SSusan.Gleeson@Sun.COM 			ret = list_target(objp);
314*12075SSusan.Gleeson@Sun.COM 			break;
315*12075SSusan.Gleeson@Sun.COM 		default:
316*12075SSusan.Gleeson@Sun.COM 			ret = 1;
317*12075SSusan.Gleeson@Sun.COM 			goto usage_error;
318*12075SSusan.Gleeson@Sun.COM 	}
319*12075SSusan.Gleeson@Sun.COM 
320*12075SSusan.Gleeson@Sun.COM 	if (ret != 0) {
321*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr,
322*12075SSusan.Gleeson@Sun.COM 		    gettext("srptadm %s failed with error %d"),
323*12075SSusan.Gleeson@Sun.COM 		    subcmds[idx].name, ret);
324*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "\n");
325*12075SSusan.Gleeson@Sun.COM 	}
326*12075SSusan.Gleeson@Sun.COM 	return (ret);
327*12075SSusan.Gleeson@Sun.COM 
328*12075SSusan.Gleeson@Sun.COM usage_error:
329*12075SSusan.Gleeson@Sun.COM 	if (subcmds[idx].name) {
330*12075SSusan.Gleeson@Sun.COM 		(void) printf("%s\n", gettext(subcmds[idx].usemsg));
331*12075SSusan.Gleeson@Sun.COM 	} else {
332*12075SSusan.Gleeson@Sun.COM 		/* overall usage */
333*12075SSusan.Gleeson@Sun.COM 		(void) printf("%s\n\n", gettext("srptadm usage:"));
334*12075SSusan.Gleeson@Sun.COM 		for (idx = 0; subcmds[idx].name != NULL; idx++) {
335*12075SSusan.Gleeson@Sun.COM 			if (!subcmds[idx].usemsg) {
336*12075SSusan.Gleeson@Sun.COM 				continue;
337*12075SSusan.Gleeson@Sun.COM 			}
338*12075SSusan.Gleeson@Sun.COM 			(void) printf("\t%s\n", gettext(subcmds[idx].usemsg));
339*12075SSusan.Gleeson@Sun.COM 		}
340*12075SSusan.Gleeson@Sun.COM 	}
341*12075SSusan.Gleeson@Sun.COM 
342*12075SSusan.Gleeson@Sun.COM 	return (ret);
343*12075SSusan.Gleeson@Sun.COM }
344*12075SSusan.Gleeson@Sun.COM 
345*12075SSusan.Gleeson@Sun.COM static int
set_default_state(boolean_t enabled)346*12075SSusan.Gleeson@Sun.COM set_default_state(boolean_t enabled)
347*12075SSusan.Gleeson@Sun.COM {
348*12075SSusan.Gleeson@Sun.COM 	int		ret;
349*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.modify.stmf";
350*12075SSusan.Gleeson@Sun.COM 
351*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
352*12075SSusan.Gleeson@Sun.COM 
353*12075SSusan.Gleeson@Sun.COM 	ret = srpt_SetDefaultState(enabled);
354*12075SSusan.Gleeson@Sun.COM 
355*12075SSusan.Gleeson@Sun.COM 	return (ret);
356*12075SSusan.Gleeson@Sun.COM }
357*12075SSusan.Gleeson@Sun.COM 
358*12075SSusan.Gleeson@Sun.COM static int
enable_target(char * hca)359*12075SSusan.Gleeson@Sun.COM enable_target(char *hca)
360*12075SSusan.Gleeson@Sun.COM {
361*12075SSusan.Gleeson@Sun.COM 	int		ret;
362*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.modify.stmf";
363*12075SSusan.Gleeson@Sun.COM 
364*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
365*12075SSusan.Gleeson@Sun.COM 
366*12075SSusan.Gleeson@Sun.COM 	ret = srpt_SetTargetState(hca, B_TRUE);
367*12075SSusan.Gleeson@Sun.COM 
368*12075SSusan.Gleeson@Sun.COM 	return (ret);
369*12075SSusan.Gleeson@Sun.COM }
370*12075SSusan.Gleeson@Sun.COM 
371*12075SSusan.Gleeson@Sun.COM static int
disable_target(char * hca)372*12075SSusan.Gleeson@Sun.COM disable_target(char *hca)
373*12075SSusan.Gleeson@Sun.COM {
374*12075SSusan.Gleeson@Sun.COM 	int		ret;
375*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.modify.stmf";
376*12075SSusan.Gleeson@Sun.COM 
377*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
378*12075SSusan.Gleeson@Sun.COM 
379*12075SSusan.Gleeson@Sun.COM 	ret = srpt_SetTargetState(hca, B_FALSE);
380*12075SSusan.Gleeson@Sun.COM 
381*12075SSusan.Gleeson@Sun.COM 	return (ret);
382*12075SSusan.Gleeson@Sun.COM }
383*12075SSusan.Gleeson@Sun.COM 
384*12075SSusan.Gleeson@Sun.COM static int
reset_target(char * hca)385*12075SSusan.Gleeson@Sun.COM reset_target(char *hca)
386*12075SSusan.Gleeson@Sun.COM {
387*12075SSusan.Gleeson@Sun.COM 	int		ret;
388*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.modify.stmf";
389*12075SSusan.Gleeson@Sun.COM 
390*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
391*12075SSusan.Gleeson@Sun.COM 
392*12075SSusan.Gleeson@Sun.COM 	ret = srpt_ResetTarget(hca);
393*12075SSusan.Gleeson@Sun.COM 
394*12075SSusan.Gleeson@Sun.COM 	return (ret);
395*12075SSusan.Gleeson@Sun.COM }
396*12075SSusan.Gleeson@Sun.COM 
397*12075SSusan.Gleeson@Sun.COM static int
list_defaults(void)398*12075SSusan.Gleeson@Sun.COM list_defaults(void)
399*12075SSusan.Gleeson@Sun.COM {
400*12075SSusan.Gleeson@Sun.COM 	int		ret;
401*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.read.stmf";
402*12075SSusan.Gleeson@Sun.COM 	boolean_t	enabled;
403*12075SSusan.Gleeson@Sun.COM 
404*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
405*12075SSusan.Gleeson@Sun.COM 
406*12075SSusan.Gleeson@Sun.COM 	/* only state set as default for now */
407*12075SSusan.Gleeson@Sun.COM 	ret = srpt_GetDefaultState(&enabled);
408*12075SSusan.Gleeson@Sun.COM 
409*12075SSusan.Gleeson@Sun.COM 	if (ret == 0) {
410*12075SSusan.Gleeson@Sun.COM 		(void) printf("%s:\n\n",
411*12075SSusan.Gleeson@Sun.COM 		    gettext("SRP Target Service Default Properties"));
412*12075SSusan.Gleeson@Sun.COM 
413*12075SSusan.Gleeson@Sun.COM 		(void) printf("    %s:\t",
414*12075SSusan.Gleeson@Sun.COM 		    gettext("Target creation enabled by default"));
415*12075SSusan.Gleeson@Sun.COM 
416*12075SSusan.Gleeson@Sun.COM 		if (enabled) {
417*12075SSusan.Gleeson@Sun.COM 			(void) printf("%s\n", gettext("true"));
418*12075SSusan.Gleeson@Sun.COM 		} else {
419*12075SSusan.Gleeson@Sun.COM 			(void) printf("%s\n", gettext("false"));
420*12075SSusan.Gleeson@Sun.COM 		}
421*12075SSusan.Gleeson@Sun.COM 	}
422*12075SSusan.Gleeson@Sun.COM 
423*12075SSusan.Gleeson@Sun.COM 	return (ret);
424*12075SSusan.Gleeson@Sun.COM }
425*12075SSusan.Gleeson@Sun.COM 
426*12075SSusan.Gleeson@Sun.COM static int
list_target(char * hca)427*12075SSusan.Gleeson@Sun.COM list_target(char *hca)
428*12075SSusan.Gleeson@Sun.COM {
429*12075SSusan.Gleeson@Sun.COM 	int		ret;
430*12075SSusan.Gleeson@Sun.COM 	char		*sec = "solaris.smf.read.stmf";
431*12075SSusan.Gleeson@Sun.COM 	char		*hcaArr[1024];	/* way bigger than we'll ever see */
432*12075SSusan.Gleeson@Sun.COM 	int		i;
433*12075SSusan.Gleeson@Sun.COM 
434*12075SSusan.Gleeson@Sun.COM 	SRPTADM_CHKAUTH(sec);
435*12075SSusan.Gleeson@Sun.COM 
436*12075SSusan.Gleeson@Sun.COM 	if (hca != NULL) {
437*12075SSusan.Gleeson@Sun.COM 		ret = print_target_props(hca);
438*12075SSusan.Gleeson@Sun.COM 		return (ret);
439*12075SSusan.Gleeson@Sun.COM 	}
440*12075SSusan.Gleeson@Sun.COM 
441*12075SSusan.Gleeson@Sun.COM 	/* get list of HCAs configured on this system, from /dev/cfg */
442*12075SSusan.Gleeson@Sun.COM 	(void) memset(&hcaArr, 0, 1024 * sizeof (char *));
443*12075SSusan.Gleeson@Sun.COM 
444*12075SSusan.Gleeson@Sun.COM 	ret = get_local_hcas(hcaArr, sizeof (hcaArr));
445*12075SSusan.Gleeson@Sun.COM 	if (ret == ETOOMANYREFS) {
446*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "Internal error:  too many HCAs\n");
447*12075SSusan.Gleeson@Sun.COM 		goto done;
448*12075SSusan.Gleeson@Sun.COM 	} else if (ret != 0) {
449*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "Error getting list of HCAs: %d\n", ret);
450*12075SSusan.Gleeson@Sun.COM 		goto done;
451*12075SSusan.Gleeson@Sun.COM 	}
452*12075SSusan.Gleeson@Sun.COM 
453*12075SSusan.Gleeson@Sun.COM 	for (i = 0; i < 1024; i++) {
454*12075SSusan.Gleeson@Sun.COM 		if (hcaArr[i] == NULL) {
455*12075SSusan.Gleeson@Sun.COM 			break;
456*12075SSusan.Gleeson@Sun.COM 		}
457*12075SSusan.Gleeson@Sun.COM 		ret = print_target_props(hcaArr[i]);
458*12075SSusan.Gleeson@Sun.COM 	}
459*12075SSusan.Gleeson@Sun.COM 
460*12075SSusan.Gleeson@Sun.COM done:
461*12075SSusan.Gleeson@Sun.COM 	for (i = 0; i < 1024; i++) {
462*12075SSusan.Gleeson@Sun.COM 		if (hcaArr[i] == NULL) {
463*12075SSusan.Gleeson@Sun.COM 			break;
464*12075SSusan.Gleeson@Sun.COM 		}
465*12075SSusan.Gleeson@Sun.COM 		free(hcaArr[i]);
466*12075SSusan.Gleeson@Sun.COM 	}
467*12075SSusan.Gleeson@Sun.COM 
468*12075SSusan.Gleeson@Sun.COM 	return (ret);
469*12075SSusan.Gleeson@Sun.COM }
470*12075SSusan.Gleeson@Sun.COM 
471*12075SSusan.Gleeson@Sun.COM static int
print_target_props(char * hca)472*12075SSusan.Gleeson@Sun.COM print_target_props(char *hca)
473*12075SSusan.Gleeson@Sun.COM {
474*12075SSusan.Gleeson@Sun.COM 	int		ret;
475*12075SSusan.Gleeson@Sun.COM 	boolean_t	enabled;
476*12075SSusan.Gleeson@Sun.COM 	char		buf[32];
477*12075SSusan.Gleeson@Sun.COM 	char		euibuf[64];
478*12075SSusan.Gleeson@Sun.COM 	uint64_t	hcaguid;
479*12075SSusan.Gleeson@Sun.COM 	stmfDevid	devid;
480*12075SSusan.Gleeson@Sun.COM 	stmfTargetProperties	props;
481*12075SSusan.Gleeson@Sun.COM 	char		*state;
482*12075SSusan.Gleeson@Sun.COM 
483*12075SSusan.Gleeson@Sun.COM 	ret = srpt_NormalizeGuid(hca, buf, sizeof (buf), &hcaguid);
484*12075SSusan.Gleeson@Sun.COM 	if (ret != 0) {
485*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "Invalid target HCA: %s\n",
486*12075SSusan.Gleeson@Sun.COM 		    hca);
487*12075SSusan.Gleeson@Sun.COM 		return (ret);
488*12075SSusan.Gleeson@Sun.COM 	}
489*12075SSusan.Gleeson@Sun.COM 
490*12075SSusan.Gleeson@Sun.COM 	/* only property set is enabled */
491*12075SSusan.Gleeson@Sun.COM 	ret = srpt_GetTargetState(buf, &enabled);
492*12075SSusan.Gleeson@Sun.COM 	if (ret != 0) {
493*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr,
494*12075SSusan.Gleeson@Sun.COM 		    "Could not get enabled state for %s: %d\n",
495*12075SSusan.Gleeson@Sun.COM 		    buf, ret);
496*12075SSusan.Gleeson@Sun.COM 		return (ret);
497*12075SSusan.Gleeson@Sun.COM 	}
498*12075SSusan.Gleeson@Sun.COM 
499*12075SSusan.Gleeson@Sun.COM 	(void) printf("Target HCA %s:\n", buf);
500*12075SSusan.Gleeson@Sun.COM 
501*12075SSusan.Gleeson@Sun.COM 	(void) printf(PROPS_FORMAT, gettext("Enabled"));
502*12075SSusan.Gleeson@Sun.COM 
503*12075SSusan.Gleeson@Sun.COM 	if (enabled) {
504*12075SSusan.Gleeson@Sun.COM 		(void) printf("%s\n", gettext("true"));
505*12075SSusan.Gleeson@Sun.COM 	} else {
506*12075SSusan.Gleeson@Sun.COM 		(void) printf("%s\n", gettext("false"));
507*12075SSusan.Gleeson@Sun.COM 	}
508*12075SSusan.Gleeson@Sun.COM 
509*12075SSusan.Gleeson@Sun.COM 	state = "-";
510*12075SSusan.Gleeson@Sun.COM 
511*12075SSusan.Gleeson@Sun.COM 	(void) snprintf(euibuf, sizeof (euibuf), "eui.%016llX", hcaguid);
512*12075SSusan.Gleeson@Sun.COM 
513*12075SSusan.Gleeson@Sun.COM 	ret = stmfDevidFromIscsiName(euibuf, &devid);
514*12075SSusan.Gleeson@Sun.COM 	if (ret == STMF_STATUS_SUCCESS) {
515*12075SSusan.Gleeson@Sun.COM 		ret = stmfGetTargetProperties(&devid, &props);
516*12075SSusan.Gleeson@Sun.COM 		if (ret == STMF_STATUS_SUCCESS) {
517*12075SSusan.Gleeson@Sun.COM 			if (props.status == STMF_TARGET_PORT_ONLINE) {
518*12075SSusan.Gleeson@Sun.COM 				state = "online";
519*12075SSusan.Gleeson@Sun.COM 			} else {
520*12075SSusan.Gleeson@Sun.COM 				state = "offline";
521*12075SSusan.Gleeson@Sun.COM 			}
522*12075SSusan.Gleeson@Sun.COM 		}
523*12075SSusan.Gleeson@Sun.COM 	}
524*12075SSusan.Gleeson@Sun.COM 
525*12075SSusan.Gleeson@Sun.COM 	(void) printf(PROPS_FORMAT, gettext("SRP Target Name"));
526*12075SSusan.Gleeson@Sun.COM 	(void) printf("%s\n", euibuf);
527*12075SSusan.Gleeson@Sun.COM 	(void) printf(PROPS_FORMAT, gettext("Operational Status"));
528*12075SSusan.Gleeson@Sun.COM 	(void) printf("%s\n", state);
529*12075SSusan.Gleeson@Sun.COM 
530*12075SSusan.Gleeson@Sun.COM 	(void) printf("\n");
531*12075SSusan.Gleeson@Sun.COM 
532*12075SSusan.Gleeson@Sun.COM 	return (0);
533*12075SSusan.Gleeson@Sun.COM }
534*12075SSusan.Gleeson@Sun.COM 
535*12075SSusan.Gleeson@Sun.COM 
536*12075SSusan.Gleeson@Sun.COM static int
get_local_hcas(char ** hcaArray,int count)537*12075SSusan.Gleeson@Sun.COM get_local_hcas(char **hcaArray, int count)
538*12075SSusan.Gleeson@Sun.COM {
539*12075SSusan.Gleeson@Sun.COM 	int		ret = 0;
540*12075SSusan.Gleeson@Sun.COM 	char		*cfgdir = "/dev/cfg";
541*12075SSusan.Gleeson@Sun.COM 	DIR		*dirp = NULL;
542*12075SSusan.Gleeson@Sun.COM 	struct dirent	*entry;
543*12075SSusan.Gleeson@Sun.COM 	int		idx = 0;
544*12075SSusan.Gleeson@Sun.COM 	char		*bufp;
545*12075SSusan.Gleeson@Sun.COM 
546*12075SSusan.Gleeson@Sun.COM 	if ((hcaArray == NULL) || (count == 0)) {
547*12075SSusan.Gleeson@Sun.COM 		return (EINVAL);
548*12075SSusan.Gleeson@Sun.COM 	}
549*12075SSusan.Gleeson@Sun.COM 
550*12075SSusan.Gleeson@Sun.COM 	dirp = opendir(cfgdir);
551*12075SSusan.Gleeson@Sun.COM 
552*12075SSusan.Gleeson@Sun.COM 	if (dirp == NULL) {
553*12075SSusan.Gleeson@Sun.COM 		ret = errno;
554*12075SSusan.Gleeson@Sun.COM 		(void) fprintf(stderr, "Could not open %s: errno %d\n",
555*12075SSusan.Gleeson@Sun.COM 		    cfgdir, ret);
556*12075SSusan.Gleeson@Sun.COM 		return (ret);
557*12075SSusan.Gleeson@Sun.COM 	}
558*12075SSusan.Gleeson@Sun.COM 
559*12075SSusan.Gleeson@Sun.COM 	while ((entry = readdir(dirp)) != NULL) {
560*12075SSusan.Gleeson@Sun.COM 		bufp = &entry->d_name[0];
561*12075SSusan.Gleeson@Sun.COM 
562*12075SSusan.Gleeson@Sun.COM 		if (strncmp(bufp, "hca:", 4) != 0) {
563*12075SSusan.Gleeson@Sun.COM 			continue;
564*12075SSusan.Gleeson@Sun.COM 		}
565*12075SSusan.Gleeson@Sun.COM 
566*12075SSusan.Gleeson@Sun.COM 		bufp += 4;
567*12075SSusan.Gleeson@Sun.COM 
568*12075SSusan.Gleeson@Sun.COM 		hcaArray[idx] = strdup(bufp);
569*12075SSusan.Gleeson@Sun.COM 		if (hcaArray[idx] == NULL) {
570*12075SSusan.Gleeson@Sun.COM 			ret = ENOMEM;
571*12075SSusan.Gleeson@Sun.COM 			break;
572*12075SSusan.Gleeson@Sun.COM 		}
573*12075SSusan.Gleeson@Sun.COM 		idx++;
574*12075SSusan.Gleeson@Sun.COM 
575*12075SSusan.Gleeson@Sun.COM 		if (idx >= count) {
576*12075SSusan.Gleeson@Sun.COM 			ret = ETOOMANYREFS;
577*12075SSusan.Gleeson@Sun.COM 			break;
578*12075SSusan.Gleeson@Sun.COM 		}
579*12075SSusan.Gleeson@Sun.COM 	}
580*12075SSusan.Gleeson@Sun.COM 
581*12075SSusan.Gleeson@Sun.COM 	return (ret);
582*12075SSusan.Gleeson@Sun.COM }
583