xref: /illumos-gate/usr/src/lib/cfgadm_plugins/sbd/common/cfga.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <macros.h>
35 #include <libdevinfo.h>
36 #define	CFGA_PLUGIN_LIB
37 #include <config_admin.h>
38 #include "ap.h"
39 
40 int cfga_version = CFGA_HSL_V2;
41 
42 /*ARGSUSED*/
43 cfga_err_t
44 cfga_change_state(
45 	cfga_cmd_t cfga_cmd,
46 	const char *ap_id,
47 	const char *options,
48 	struct cfga_confirm *confp,
49 	struct cfga_msg *msgp,
50 	char **errstring,
51 	cfga_flags_t flags)
52 {
53 	int cmd;
54 	const char *name;
55 	apd_t *a;
56 	cfga_err_t rc;
57 
58 	if ((rc = ap_state_cmd(cfga_cmd, &cmd)) != CFGA_OK)
59 		return (rc);
60 
61 	rc = CFGA_LIB_ERROR;
62 
63 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
64 		return (rc);
65 
66 	name = ap_cmd_name(cmd);
67 
68 	if ((rc = ap_cmd_parse(a, name, options, NULL)) == CFGA_OK)
69 		rc = ap_cmd_seq(a, cmd);
70 
71 	apd_free(a);
72 
73 	return (rc);
74 }
75 
76 /*
77  * Check if this is a valid -x command.
78  */
79 static int
80 private_func(const char *function)
81 {
82 	char **f;
83 	static char *
84 	private_funcs[] = {
85 		"assign",
86 		"unassign",
87 		"poweron",
88 		"poweroff",
89 		"passthru",
90 		"errtest",
91 		NULL
92 	};
93 
94 	for (f = private_funcs; *f != NULL; f++)
95 		if (strcmp(*f, function) == 0)
96 			break;
97 
98 	return (*f == NULL ? CFGA_INVAL : CFGA_OK);
99 }
100 
101 /*ARGSUSED*/
102 cfga_err_t
103 cfga_private_func(
104 	const char *function,
105 	const char *ap_id,
106 	const char *options,
107 	struct cfga_confirm *confp,
108 	struct cfga_msg *msgp,
109 	char **errstring,
110 	cfga_flags_t flags)
111 {
112 	int cmd;
113 	apd_t *a;
114 	cfga_err_t rc;
115 
116 	DBG("cfga_private_func(%s)\n", ap_id);
117 
118 	rc = CFGA_LIB_ERROR;
119 
120 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
121 		return (rc);
122 	else if ((rc = private_func(function)) != CFGA_OK)  {
123 		ap_err(a, ERR_CMD_INVAL, function);
124 		goto done;
125 	} else if ((rc = ap_cmd_parse(a, function, options, &cmd)) != CFGA_OK)
126 		goto done;
127 	else if (cmd == CMD_ERRTEST)
128 		rc = ap_test_err(a, options);
129 	else
130 		rc = ap_cmd_exec(a, cmd);
131 done:
132 	apd_free(a);
133 	return (rc);
134 }
135 
136 
137 /*ARGSUSED*/
138 cfga_err_t
139 cfga_test(
140 	const char *ap_id,
141 	const char *options,
142 	struct cfga_msg *msgp,
143 	char **errstring,
144 	cfga_flags_t flags)
145 {
146 	int cmd;
147 	const char *f;
148 	apd_t *a;
149 	cfga_err_t rc;
150 
151 	DBG("cfga_test(%s)\n", ap_id);
152 
153 	f = "test";
154 	rc = CFGA_LIB_ERROR;
155 
156 	/*
157 	 * A test that is not sequenced by a change
158 	 * state operation should be forced.
159 	 */
160 	flags |= CFGA_FLAG_FORCE;
161 
162 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, NULL)) == NULL)
163 		return (rc);
164 	else if ((rc = ap_cmd_parse(a, f, options, &cmd)) != CFGA_OK)
165 		goto done;
166 	else
167 		rc = ap_cmd_exec(a, cmd);
168 done:
169 	apd_free(a);
170 	return (rc);
171 }
172 
173 /*ARGSUSED*/
174 cfga_err_t
175 cfga_list_ext(
176 	const char *ap_id,
177 	cfga_list_data_t **ap_id_list,
178 	int *nlist,
179 	const char *options,
180 	const char *listopts,
181 	char **errstring,
182 	cfga_flags_t flags)
183 {
184 	int i;
185 	int apcnt;
186 	const char *f;
187 	apd_t *a;
188 	size_t szl, szp;
189 	cfga_list_data_t *aplist, *ap;
190 	cfga_err_t rc;
191 
192 	rc = CFGA_LIB_ERROR;
193 
194 	aplist = NULL;
195 	f = ap_cmd_name(CMD_STATUS);
196 
197 	DBG("cfga_list_ext(%s %x)\n", ap_id, flags);
198 
199 	if ((a = apd_alloc(ap_id, flags, errstring, NULL, NULL)) == NULL)
200 		return (rc);
201 	else if ((rc = ap_cmd_parse(a, f, options, NULL)) != CFGA_OK)
202 		goto done;
203 
204 	apcnt = ap_cnt(a);
205 
206 	DBG("apcnt=%d\n", apcnt);
207 
208 	if ((aplist = calloc(apcnt, sizeof (*aplist))) == NULL) {
209 		rc = CFGA_LIB_ERROR;
210 		ap_err(a, ERR_CMD_FAIL, CMD_STATUS);
211 		goto done;
212 	}
213 
214 	ap = aplist;
215 	szl = sizeof (ap->ap_log_id);
216 	szp = sizeof (ap->ap_phys_id);
217 
218 	/*
219 	 * Initialize the AP specified directly by the caller.
220 	 * The target ID for the 0th element already includes
221 	 * the (potential) dynamic portion. The dynamic portion
222 	 * does need to be appended to the path to form the
223 	 * physical apid for components.
224 	 */
225 	(void) strncpy(ap->ap_log_id, a->target, szl - 1);
226 	(void) snprintf(ap->ap_phys_id, szp, "%s%s%s", a->path,
227 	    a->tgt != AP_BOARD ? "::" : "",
228 	    a->tgt != AP_BOARD ? a->cid : "");
229 
230 
231 	DBG("ap_phys_id=%s ap_log_id=%s\n", ap->ap_phys_id, ap->ap_log_id);
232 
233 	if (a->tgt == AP_BOARD) {
234 
235 		ap_init(a, ap++);
236 
237 		/*
238 		 * Initialize the components, if any.
239 		 */
240 		for (i = 0; i < apcnt - 1; i++, ap++) {
241 			char dyn[MAXPATHLEN];
242 
243 			ap_cm_id(a, i, dyn, sizeof (dyn));
244 
245 			(void) snprintf(ap->ap_log_id, szl, "%s::%s",
246 				a->target, dyn);
247 			(void) snprintf(ap->ap_phys_id, szp, "%s::%s",
248 				a->path, dyn);
249 
250 			ap_cm_init(a, ap, i);
251 
252 			DBG("ap_phys_id=%s ap_log_id=%s\n",
253 				ap->ap_phys_id, ap->ap_log_id);
254 		}
255 
256 	} else
257 		ap_cm_init(a, ap, 0);
258 
259 	apd_free(a);
260 	*ap_id_list = aplist;
261 	*nlist = apcnt;
262 	return (CFGA_OK);
263 
264 done:
265 	s_free(aplist);
266 	apd_free(a);
267 	return (rc);
268 }
269 
270 /*ARGSUSED*/
271 cfga_err_t
272 cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
273 {
274 	return (ap_help(msgp, options, flags));
275 }
276 
277 
278 /*
279  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
280  */
281