xref: /onnv-gate/usr/src/lib/cfgadm_plugins/sbd/common/cfga.c (revision 12004:93f274d4a367)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*12004Sjiang.liu@intel.com  * Common Development and Distribution License (the "License").
6*12004Sjiang.liu@intel.com  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
220Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <ctype.h>
270Sstevel@tonic-gate #include <stdio.h>
280Sstevel@tonic-gate #include <stdlib.h>
290Sstevel@tonic-gate #include <string.h>
300Sstevel@tonic-gate #include <unistd.h>
310Sstevel@tonic-gate #include <macros.h>
320Sstevel@tonic-gate #include <libdevinfo.h>
330Sstevel@tonic-gate #define	CFGA_PLUGIN_LIB
340Sstevel@tonic-gate #include <config_admin.h>
350Sstevel@tonic-gate #include "ap.h"
360Sstevel@tonic-gate 
370Sstevel@tonic-gate int cfga_version = CFGA_HSL_V2;
380Sstevel@tonic-gate 
390Sstevel@tonic-gate /*ARGSUSED*/
400Sstevel@tonic-gate cfga_err_t
cfga_change_state(cfga_cmd_t cfga_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)410Sstevel@tonic-gate cfga_change_state(
420Sstevel@tonic-gate 	cfga_cmd_t cfga_cmd,
430Sstevel@tonic-gate 	const char *ap_id,
440Sstevel@tonic-gate 	const char *options,
450Sstevel@tonic-gate 	struct cfga_confirm *confp,
460Sstevel@tonic-gate 	struct cfga_msg *msgp,
470Sstevel@tonic-gate 	char **errstring,
480Sstevel@tonic-gate 	cfga_flags_t flags)
490Sstevel@tonic-gate {
500Sstevel@tonic-gate 	int cmd;
510Sstevel@tonic-gate 	const char *name;
520Sstevel@tonic-gate 	apd_t *a;
530Sstevel@tonic-gate 	cfga_err_t rc;
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	if ((rc = ap_state_cmd(cfga_cmd, &cmd)) != CFGA_OK)
560Sstevel@tonic-gate 		return (rc);
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
610Sstevel@tonic-gate 		return (rc);
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	name = ap_cmd_name(cmd);
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	if ((rc = ap_cmd_parse(a, name, options, NULL)) == CFGA_OK)
660Sstevel@tonic-gate 		rc = ap_cmd_seq(a, cmd);
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	apd_free(a);
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	return (rc);
710Sstevel@tonic-gate }
720Sstevel@tonic-gate 
730Sstevel@tonic-gate /*
740Sstevel@tonic-gate  * Check if this is a valid -x command.
750Sstevel@tonic-gate  */
760Sstevel@tonic-gate static int
private_func(const char * function)770Sstevel@tonic-gate private_func(const char *function)
780Sstevel@tonic-gate {
790Sstevel@tonic-gate 	char **f;
800Sstevel@tonic-gate 	static char *
810Sstevel@tonic-gate 	private_funcs[] = {
820Sstevel@tonic-gate 		"assign",
830Sstevel@tonic-gate 		"unassign",
840Sstevel@tonic-gate 		"poweron",
850Sstevel@tonic-gate 		"poweroff",
860Sstevel@tonic-gate 		"passthru",
870Sstevel@tonic-gate 		"errtest",
880Sstevel@tonic-gate 		NULL
890Sstevel@tonic-gate 	};
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	for (f = private_funcs; *f != NULL; f++)
920Sstevel@tonic-gate 		if (strcmp(*f, function) == 0)
930Sstevel@tonic-gate 			break;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	return (*f == NULL ? CFGA_INVAL : CFGA_OK);
960Sstevel@tonic-gate }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate /*ARGSUSED*/
990Sstevel@tonic-gate cfga_err_t
cfga_private_func(const char * function,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)1000Sstevel@tonic-gate cfga_private_func(
1010Sstevel@tonic-gate 	const char *function,
1020Sstevel@tonic-gate 	const char *ap_id,
1030Sstevel@tonic-gate 	const char *options,
1040Sstevel@tonic-gate 	struct cfga_confirm *confp,
1050Sstevel@tonic-gate 	struct cfga_msg *msgp,
1060Sstevel@tonic-gate 	char **errstring,
1070Sstevel@tonic-gate 	cfga_flags_t flags)
1080Sstevel@tonic-gate {
1090Sstevel@tonic-gate 	int cmd;
1100Sstevel@tonic-gate 	apd_t *a;
1110Sstevel@tonic-gate 	cfga_err_t rc;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	DBG("cfga_private_func(%s)\n", ap_id);
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
1180Sstevel@tonic-gate 		return (rc);
1190Sstevel@tonic-gate 	else if ((rc = private_func(function)) != CFGA_OK)  {
1200Sstevel@tonic-gate 		ap_err(a, ERR_CMD_INVAL, function);
1210Sstevel@tonic-gate 		goto done;
1220Sstevel@tonic-gate 	} else if ((rc = ap_cmd_parse(a, function, options, &cmd)) != CFGA_OK)
1230Sstevel@tonic-gate 		goto done;
1240Sstevel@tonic-gate 	else if (cmd == CMD_ERRTEST)
1250Sstevel@tonic-gate 		rc = ap_test_err(a, options);
1260Sstevel@tonic-gate 	else
1270Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
1280Sstevel@tonic-gate done:
1290Sstevel@tonic-gate 	apd_free(a);
1300Sstevel@tonic-gate 	return (rc);
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate /*ARGSUSED*/
1350Sstevel@tonic-gate cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)1360Sstevel@tonic-gate cfga_test(
1370Sstevel@tonic-gate 	const char *ap_id,
1380Sstevel@tonic-gate 	const char *options,
1390Sstevel@tonic-gate 	struct cfga_msg *msgp,
1400Sstevel@tonic-gate 	char **errstring,
1410Sstevel@tonic-gate 	cfga_flags_t flags)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate 	int cmd;
1440Sstevel@tonic-gate 	const char *f;
1450Sstevel@tonic-gate 	apd_t *a;
1460Sstevel@tonic-gate 	cfga_err_t rc;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	DBG("cfga_test(%s)\n", ap_id);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	f = "test";
1510Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	/*
1540Sstevel@tonic-gate 	 * A test that is not sequenced by a change
1550Sstevel@tonic-gate 	 * state operation should be forced.
1560Sstevel@tonic-gate 	 */
1570Sstevel@tonic-gate 	flags |= CFGA_FLAG_FORCE;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, NULL)) == NULL)
1600Sstevel@tonic-gate 		return (rc);
1610Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, &cmd)) != CFGA_OK)
1620Sstevel@tonic-gate 		goto done;
1630Sstevel@tonic-gate 	else
1640Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
1650Sstevel@tonic-gate done:
1660Sstevel@tonic-gate 	apd_free(a);
1670Sstevel@tonic-gate 	return (rc);
1680Sstevel@tonic-gate }
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate /*ARGSUSED*/
1710Sstevel@tonic-gate cfga_err_t
cfga_list_ext(const char * ap_id,cfga_list_data_t ** ap_id_list,int * nlist,const char * options,const char * listopts,char ** errstring,cfga_flags_t flags)1720Sstevel@tonic-gate cfga_list_ext(
1730Sstevel@tonic-gate 	const char *ap_id,
1740Sstevel@tonic-gate 	cfga_list_data_t **ap_id_list,
1750Sstevel@tonic-gate 	int *nlist,
1760Sstevel@tonic-gate 	const char *options,
1770Sstevel@tonic-gate 	const char *listopts,
1780Sstevel@tonic-gate 	char **errstring,
1790Sstevel@tonic-gate 	cfga_flags_t flags)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate 	int i;
1820Sstevel@tonic-gate 	int apcnt;
1830Sstevel@tonic-gate 	const char *f;
1840Sstevel@tonic-gate 	apd_t *a;
1850Sstevel@tonic-gate 	size_t szl, szp;
1860Sstevel@tonic-gate 	cfga_list_data_t *aplist, *ap;
1870Sstevel@tonic-gate 	cfga_err_t rc;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	aplist = NULL;
1920Sstevel@tonic-gate 	f = ap_cmd_name(CMD_STATUS);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	DBG("cfga_list_ext(%s %x)\n", ap_id, flags);
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, NULL, NULL)) == NULL)
1970Sstevel@tonic-gate 		return (rc);
1980Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, NULL)) != CFGA_OK)
1990Sstevel@tonic-gate 		goto done;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	apcnt = ap_cnt(a);
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	DBG("apcnt=%d\n", apcnt);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	if ((aplist = calloc(apcnt, sizeof (*aplist))) == NULL) {
2060Sstevel@tonic-gate 		rc = CFGA_LIB_ERROR;
2070Sstevel@tonic-gate 		ap_err(a, ERR_CMD_FAIL, CMD_STATUS);
2080Sstevel@tonic-gate 		goto done;
2090Sstevel@tonic-gate 	}
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	ap = aplist;
2120Sstevel@tonic-gate 	szl = sizeof (ap->ap_log_id);
2130Sstevel@tonic-gate 	szp = sizeof (ap->ap_phys_id);
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate 	/*
2160Sstevel@tonic-gate 	 * Initialize the AP specified directly by the caller.
2170Sstevel@tonic-gate 	 * The target ID for the 0th element already includes
2180Sstevel@tonic-gate 	 * the (potential) dynamic portion. The dynamic portion
2190Sstevel@tonic-gate 	 * does need to be appended to the path to form the
2200Sstevel@tonic-gate 	 * physical apid for components.
2210Sstevel@tonic-gate 	 */
2220Sstevel@tonic-gate 	(void) strncpy(ap->ap_log_id, a->target, szl - 1);
2230Sstevel@tonic-gate 	(void) snprintf(ap->ap_phys_id, szp, "%s%s%s", a->path,
2240Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? "::" : "",
2250Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? a->cid : "");
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	DBG("ap_phys_id=%s ap_log_id=%s\n", ap->ap_phys_id, ap->ap_log_id);
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	if (a->tgt == AP_BOARD) {
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 		ap_init(a, ap++);
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 		/*
2350Sstevel@tonic-gate 		 * Initialize the components, if any.
2360Sstevel@tonic-gate 		 */
2370Sstevel@tonic-gate 		for (i = 0; i < apcnt - 1; i++, ap++) {
2380Sstevel@tonic-gate 			char dyn[MAXPATHLEN];
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 			ap_cm_id(a, i, dyn, sizeof (dyn));
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 			(void) snprintf(ap->ap_log_id, szl, "%s::%s",
243*12004Sjiang.liu@intel.com 			    a->target, dyn);
2440Sstevel@tonic-gate 			(void) snprintf(ap->ap_phys_id, szp, "%s::%s",
245*12004Sjiang.liu@intel.com 			    a->path, dyn);
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 			ap_cm_init(a, ap, i);
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 			DBG("ap_phys_id=%s ap_log_id=%s\n",
250*12004Sjiang.liu@intel.com 			    ap->ap_phys_id, ap->ap_log_id);
2510Sstevel@tonic-gate 		}
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	} else
2540Sstevel@tonic-gate 		ap_cm_init(a, ap, 0);
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	apd_free(a);
2570Sstevel@tonic-gate 	*ap_id_list = aplist;
2580Sstevel@tonic-gate 	*nlist = apcnt;
2590Sstevel@tonic-gate 	return (CFGA_OK);
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate done:
2620Sstevel@tonic-gate 	s_free(aplist);
2630Sstevel@tonic-gate 	apd_free(a);
2640Sstevel@tonic-gate 	return (rc);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate /*ARGSUSED*/
2680Sstevel@tonic-gate cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)2690Sstevel@tonic-gate cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate 	return (ap_help(msgp, options, flags));
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate /*
2760Sstevel@tonic-gate  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
2770Sstevel@tonic-gate  */
278