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*9713SBill.Taylor@Sun.COM * Common Development and Distribution License (the "License").
6*9713SBill.Taylor@Sun.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 /*
22*9713SBill.Taylor@Sun.COM * Copyright 2009 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 "cfga_ib.h"
270Sstevel@tonic-gate #include "cfga_conf.h"
280Sstevel@tonic-gate #include <sys/stat.h>
290Sstevel@tonic-gate
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate * cfga_conf.c
320Sstevel@tonic-gate *
330Sstevel@tonic-gate * This file supports adding/deleting/listing services from IBCONF_FILE.
340Sstevel@tonic-gate */
350Sstevel@tonic-gate
360Sstevel@tonic-gate /*
370Sstevel@tonic-gate * function prototypes:
380Sstevel@tonic-gate */
390Sstevel@tonic-gate static ib_service_type_t ib_get_var_type(char *);
400Sstevel@tonic-gate static ib_token_t ib_lex(char *, char **);
410Sstevel@tonic-gate static void ib_find_eol();
420Sstevel@tonic-gate static int ib_get_string(char **, char *);
430Sstevel@tonic-gate static int ib_service_record_add(char *,
440Sstevel@tonic-gate ib_service_type_t);
450Sstevel@tonic-gate static ib_token_t ib_get_services(char **);
460Sstevel@tonic-gate static boolean_t ib_cmp_service();
470Sstevel@tonic-gate static void ib_free_service_recs(void);
480Sstevel@tonic-gate static int ib_cleanup_file(int);
490Sstevel@tonic-gate static int ib_init_file(char **);
500Sstevel@tonic-gate int ib_add_service(char **);
510Sstevel@tonic-gate int ib_delete_service(char **);
520Sstevel@tonic-gate int ib_list_services(struct cfga_msg *, char **);
530Sstevel@tonic-gate static cfga_ib_ret_t ib_conf_control_ioctl(char *, uint_t);
540Sstevel@tonic-gate static int ib_service_record_valid(char *);
550Sstevel@tonic-gate
560Sstevel@tonic-gate extern void cfga_msg(struct cfga_msg *, const char *);
570Sstevel@tonic-gate
580Sstevel@tonic-gate
590Sstevel@tonic-gate /* Global variables */
600Sstevel@tonic-gate
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate * supported "name=value" pairs from IBCONF_FILE
630Sstevel@tonic-gate */
640Sstevel@tonic-gate static ibcfg_var_t ibcfg_varlist[] = {
650Sstevel@tonic-gate { "name", IB_NAME },
660Sstevel@tonic-gate { "class", IB_CLASS },
670Sstevel@tonic-gate { "port-svc-list", IB_PORT_SERVICE },
680Sstevel@tonic-gate { "vppa-svc-list", IB_VPPA_SERVICE },
690Sstevel@tonic-gate { "hca-svc-list", IB_HCASVC_SERVICE },
700Sstevel@tonic-gate { NULL, IB_NONE }
710Sstevel@tonic-gate };
720Sstevel@tonic-gate
730Sstevel@tonic-gate static char ibconf_file[] = IBCONF_FILE; /* file being read */
740Sstevel@tonic-gate static int ibcfg_linenum = 1; /* track line#s */
750Sstevel@tonic-gate static int ibcfg_cntr = 0; /* current char read */
760Sstevel@tonic-gate static int ibcfg_brec = 0; /* beginning of rec */
770Sstevel@tonic-gate static int bvpparec = 0; /* begin of vppa rec */
780Sstevel@tonic-gate static int bportrec = 0; /* begin of port rec */
790Sstevel@tonic-gate static int bhcarec = 0; /* begin of HCA rec */
800Sstevel@tonic-gate static int ibcfg_btoken = 0; /* begin of new token */
810Sstevel@tonic-gate static mutex_t ibcfg_lock = DEFAULTMUTEX; /* lock for the file */
820Sstevel@tonic-gate static int ibcfg_fd = -1; /* file descriptor */
830Sstevel@tonic-gate static int ibcfg_tmpfd = 0; /* tmp file "fd" */
840Sstevel@tonic-gate static char *file_buf = (char *)NULL; /* read file into buf */
850Sstevel@tonic-gate static char *tmpnamef = (char *)NULL; /* tmp file name */
860Sstevel@tonic-gate static boolean_t wrote_tmp = B_FALSE; /* tmp file write in */
870Sstevel@tonic-gate /* progress indicator */
880Sstevel@tonic-gate static struct stat ibcfg_st; /* file stat struct */
890Sstevel@tonic-gate
900Sstevel@tonic-gate static int ibcfg_nport_services; /* # of PORT services */
910Sstevel@tonic-gate static int ibcfg_nvppa_services; /* # of VPPA services */
920Sstevel@tonic-gate static int ibcfg_nhca_services; /* # of HCA services */
930Sstevel@tonic-gate static ib_svc_rec_t *ibcfg_vppa_head; /* VPPA service recs */
940Sstevel@tonic-gate static ib_svc_rec_t *ibcfg_port_head; /* PORT service recs */
950Sstevel@tonic-gate static ib_svc_rec_t *ibcfg_hca_head; /* HCA service recs */
960Sstevel@tonic-gate
970Sstevel@tonic-gate extern char *service_name; /* service name */
980Sstevel@tonic-gate extern ib_service_type_t service_type; /* service type */
990Sstevel@tonic-gate
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate * Function:
1030Sstevel@tonic-gate * ib_get_var_type
1040Sstevel@tonic-gate * Input:
1050Sstevel@tonic-gate * str - A parsed string from IBCONF_FILE
1060Sstevel@tonic-gate * Output:
1070Sstevel@tonic-gate * NONE
1080Sstevel@tonic-gate * Returns:
1090Sstevel@tonic-gate * Service type
1100Sstevel@tonic-gate * Description:
1110Sstevel@tonic-gate * Returns the field from the token
1120Sstevel@tonic-gate */
1130Sstevel@tonic-gate static ib_service_type_t
ib_get_var_type(char * str)1140Sstevel@tonic-gate ib_get_var_type(char *str)
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate register ibcfg_var_t *cfgvar;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate cfgvar = &ibcfg_varlist[0];
1190Sstevel@tonic-gate while (cfgvar->type != IB_NONE) {
1200Sstevel@tonic-gate if (strcasecmp(cfgvar->name, str) == NULL)
1210Sstevel@tonic-gate break;
1220Sstevel@tonic-gate else
1230Sstevel@tonic-gate cfgvar++;
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate return (cfgvar->type);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate /*
1300Sstevel@tonic-gate * Function:
1310Sstevel@tonic-gate * ib_lex
1320Sstevel@tonic-gate * Input:
1330Sstevel@tonic-gate * NONE
1340Sstevel@tonic-gate * Output:
1350Sstevel@tonic-gate * val - value just read
1360Sstevel@tonic-gate * errmsg - pointer to error message string, if there are any errors
1370Sstevel@tonic-gate * Returns:
1380Sstevel@tonic-gate * valid IB token
1390Sstevel@tonic-gate * Description:
1400Sstevel@tonic-gate * Read tokens from the IBCONF_FILE and parse them
1410Sstevel@tonic-gate */
1420Sstevel@tonic-gate /* ARGSUSED */
1430Sstevel@tonic-gate static ib_token_t
ib_lex(char * val,char ** errmsg)1440Sstevel@tonic-gate ib_lex(char *val, char **errmsg)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate int ch, oval, badquote;
1470Sstevel@tonic-gate char *cp = val;
1480Sstevel@tonic-gate ib_token_t token;
1490Sstevel@tonic-gate
150*9713SBill.Taylor@Sun.COM while ((ch = GETC(file_buf, ibcfg_cntr)) == ' ' || ch == '\t')
151*9713SBill.Taylor@Sun.COM ;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* make a note of the beginning of token */
1540Sstevel@tonic-gate ibcfg_btoken = ibcfg_cntr - 1;
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate *cp++ = (char)ch;
1570Sstevel@tonic-gate switch (ch) {
1580Sstevel@tonic-gate case '=':
1590Sstevel@tonic-gate token = EQUALS;
1600Sstevel@tonic-gate break;
1610Sstevel@tonic-gate case '&':
1620Sstevel@tonic-gate token = AMPERSAND;
1630Sstevel@tonic-gate break;
1640Sstevel@tonic-gate case '|':
1650Sstevel@tonic-gate token = BIT_OR;
1660Sstevel@tonic-gate break;
1670Sstevel@tonic-gate case '*':
1680Sstevel@tonic-gate token = STAR;
1690Sstevel@tonic-gate break;
1700Sstevel@tonic-gate case '#':
1710Sstevel@tonic-gate token = POUND;
1720Sstevel@tonic-gate break;
1730Sstevel@tonic-gate case ':':
1740Sstevel@tonic-gate token = COLON;
1750Sstevel@tonic-gate break;
1760Sstevel@tonic-gate case ';':
1770Sstevel@tonic-gate token = SEMICOLON;
1780Sstevel@tonic-gate break;
1790Sstevel@tonic-gate case ',':
1800Sstevel@tonic-gate token = COMMA;
1810Sstevel@tonic-gate break;
1820Sstevel@tonic-gate case '/':
1830Sstevel@tonic-gate token = SLASH;
1840Sstevel@tonic-gate break;
1850Sstevel@tonic-gate case ' ':
1860Sstevel@tonic-gate case '\t':
1870Sstevel@tonic-gate case '\f':
1880Sstevel@tonic-gate while ((ch = GETC(file_buf, ibcfg_cntr)) == ' ' ||
1890Sstevel@tonic-gate ch == '\t' || ch == '\f')
1900Sstevel@tonic-gate *cp++ = (char)ch;
1910Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
1920Sstevel@tonic-gate token = WHITE_SPACE;
1930Sstevel@tonic-gate break;
1940Sstevel@tonic-gate case '\n':
1950Sstevel@tonic-gate case '\r':
1960Sstevel@tonic-gate token = NEWLINE;
1970Sstevel@tonic-gate break;
1980Sstevel@tonic-gate case '"':
1990Sstevel@tonic-gate cp--;
2000Sstevel@tonic-gate badquote = 0;
2010Sstevel@tonic-gate while (!badquote && (ch = GETC(file_buf, ibcfg_cntr)) != '"') {
2020Sstevel@tonic-gate switch (ch) {
2030Sstevel@tonic-gate case '\n':
2040Sstevel@tonic-gate case -1:
2050Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
2060Sstevel@tonic-gate "Missing \"");
2070Sstevel@tonic-gate cp = val;
2080Sstevel@tonic-gate *cp++ = '\n';
2090Sstevel@tonic-gate badquote = 1;
2100Sstevel@tonic-gate /* since we consumed the newline/EOF */
2110Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
2120Sstevel@tonic-gate break;
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate case '\\':
2150Sstevel@tonic-gate ch = (char)GETC(file_buf, ibcfg_cntr);
2160Sstevel@tonic-gate if (!isdigit(ch)) {
2170Sstevel@tonic-gate /* escape the character */
2180Sstevel@tonic-gate *cp++ = (char)ch;
2190Sstevel@tonic-gate break;
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate oval = 0;
2220Sstevel@tonic-gate while (ch >= '0' && ch <= '7') {
2230Sstevel@tonic-gate ch -= '0';
2240Sstevel@tonic-gate oval = (oval << 3) + ch;
2250Sstevel@tonic-gate ch = (char)GETC(file_buf, ibcfg_cntr);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
2280Sstevel@tonic-gate /* check for character overflow? */
2290Sstevel@tonic-gate if (oval > 127) {
2300Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
2310Sstevel@tonic-gate "Character overflow detected.\n");
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate *cp++ = (char)oval;
2340Sstevel@tonic-gate break;
2350Sstevel@tonic-gate default:
2360Sstevel@tonic-gate *cp++ = (char)ch;
2370Sstevel@tonic-gate break;
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate token = STRING;
2410Sstevel@tonic-gate break;
2420Sstevel@tonic-gate default:
2430Sstevel@tonic-gate if (ch == -1) {
2440Sstevel@tonic-gate token = EOF;
2450Sstevel@tonic-gate break;
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate /*
2480Sstevel@tonic-gate * detect a lone '-' (including at the end of a line), and
2490Sstevel@tonic-gate * identify it as a 'name'
2500Sstevel@tonic-gate */
2510Sstevel@tonic-gate if (ch == '-') {
2520Sstevel@tonic-gate *cp++ = (char)(ch = GETC(file_buf, ibcfg_cntr));
2530Sstevel@tonic-gate if (iswhite(ch) || (ch == '\n')) {
2540Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
2550Sstevel@tonic-gate cp--;
2560Sstevel@tonic-gate token = NAME;
2570Sstevel@tonic-gate break;
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate } else if (isunary(ch)) {
2600Sstevel@tonic-gate *cp++ = (char)(ch = GETC(file_buf, ibcfg_cntr));
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate if (isdigit(ch)) {
2640Sstevel@tonic-gate if (ch == '0') {
2650Sstevel@tonic-gate if ((ch = GETC(file_buf, ibcfg_cntr)) == 'x') {
2660Sstevel@tonic-gate *cp++ = (char)ch;
2670Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
2680Sstevel@tonic-gate while (isxdigit(ch)) {
2690Sstevel@tonic-gate *cp++ = (char)ch;
2700Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
2710Sstevel@tonic-gate }
2720Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
2730Sstevel@tonic-gate token = HEXVAL;
2740Sstevel@tonic-gate } else {
2750Sstevel@tonic-gate goto digit;
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate } else {
2780Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
2790Sstevel@tonic-gate digit:
2800Sstevel@tonic-gate while (isdigit(ch)) {
2810Sstevel@tonic-gate *cp++ = (char)ch;
2820Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
2850Sstevel@tonic-gate token = DECVAL;
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate } else if (isalpha(ch) || ch == '\\') {
2880Sstevel@tonic-gate if (ch != '\\') {
2890Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
2900Sstevel@tonic-gate } else {
2910Sstevel@tonic-gate /*
2920Sstevel@tonic-gate * if the character was a backslash,
2930Sstevel@tonic-gate * back up so we can overwrite it with
2940Sstevel@tonic-gate * the next (i.e. escaped) character.
2950Sstevel@tonic-gate */
2960Sstevel@tonic-gate cp--;
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate while (isnamechar(ch) || ch == '\\') {
3000Sstevel@tonic-gate if (ch == '\\')
3010Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
3020Sstevel@tonic-gate *cp++ = (char)ch;
3030Sstevel@tonic-gate ch = GETC(file_buf, ibcfg_cntr);
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
3060Sstevel@tonic-gate token = NAME;
3070Sstevel@tonic-gate } else
3080Sstevel@tonic-gate return (-1);
3090Sstevel@tonic-gate break;
3100Sstevel@tonic-gate }
3110Sstevel@tonic-gate *cp = '\0';
3120Sstevel@tonic-gate return (token);
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate /*
3170Sstevel@tonic-gate * Function:
3180Sstevel@tonic-gate * ib_find_eol
3190Sstevel@tonic-gate * Input:
3200Sstevel@tonic-gate * NONE
3210Sstevel@tonic-gate * Output:
3220Sstevel@tonic-gate * NONE
3230Sstevel@tonic-gate * Returns:
3240Sstevel@tonic-gate * NONE
3250Sstevel@tonic-gate * Description:
3260Sstevel@tonic-gate * Leave NEWLINE as the next character.
3270Sstevel@tonic-gate */
3280Sstevel@tonic-gate static void
ib_find_eol()3290Sstevel@tonic-gate ib_find_eol()
3300Sstevel@tonic-gate {
3310Sstevel@tonic-gate int ch;
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate while ((ch = GETC(file_buf, ibcfg_cntr)) != -1) {
3340Sstevel@tonic-gate if (isnewline(ch)) {
3350Sstevel@tonic-gate (void) UNGETC(ibcfg_cntr);
3360Sstevel@tonic-gate break;
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate /*
3430Sstevel@tonic-gate * Function:
3440Sstevel@tonic-gate * ib_get_string
3450Sstevel@tonic-gate * Input:
3460Sstevel@tonic-gate * tchar - name of the string
3470Sstevel@tonic-gate * Output:
3480Sstevel@tonic-gate * llptr - Valid string
3490Sstevel@tonic-gate * Returns:
3500Sstevel@tonic-gate * 1 for success, NULL for errors.
3510Sstevel@tonic-gate * Description:
3520Sstevel@tonic-gate * The next item on the line is a string value. Allocate memory for
3530Sstevel@tonic-gate * it and copy the string. Return 1, and set arg ptr to newly allocated
3540Sstevel@tonic-gate * and initialized buffer, or NULL if an error occurs.
3550Sstevel@tonic-gate */
3560Sstevel@tonic-gate static int
ib_get_string(char ** llptr,char * tchar)3570Sstevel@tonic-gate ib_get_string(char **llptr, char *tchar)
3580Sstevel@tonic-gate {
3590Sstevel@tonic-gate int tlen = strlen(tchar);
3600Sstevel@tonic-gate char *cp;
3610Sstevel@tonic-gate char *start = (char *)0;
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate start = tchar;
3640Sstevel@tonic-gate /* copy string */
3650Sstevel@tonic-gate if ((cp = (char *)calloc(tlen + 1, sizeof (char))) == (char *)NULL) {
3660Sstevel@tonic-gate *llptr = NULL;
3670Sstevel@tonic-gate return (0);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate bzero(cp, tlen + 1);
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate *llptr = cp;
3720Sstevel@tonic-gate for (; tlen > 0; tlen--) {
3730Sstevel@tonic-gate /* convert some common escape sequences */
3740Sstevel@tonic-gate if (*start == '\\') {
3750Sstevel@tonic-gate switch (*(start + 1)) {
3760Sstevel@tonic-gate case 't':
3770Sstevel@tonic-gate /* tab */
3780Sstevel@tonic-gate *cp++ = '\t';
3790Sstevel@tonic-gate tlen--;
3800Sstevel@tonic-gate start += 2;
3810Sstevel@tonic-gate break;
3820Sstevel@tonic-gate case 'n':
3830Sstevel@tonic-gate /* new line */
3840Sstevel@tonic-gate *cp++ = '\n';
3850Sstevel@tonic-gate tlen--;
3860Sstevel@tonic-gate start += 2;
3870Sstevel@tonic-gate break;
3880Sstevel@tonic-gate case 'b':
3890Sstevel@tonic-gate /* back space */
3900Sstevel@tonic-gate *cp++ = '\b';
3910Sstevel@tonic-gate tlen--;
3920Sstevel@tonic-gate start += 2;
3930Sstevel@tonic-gate break;
3940Sstevel@tonic-gate default:
3950Sstevel@tonic-gate /* simply copy it */
3960Sstevel@tonic-gate *cp++ = *start++;
3970Sstevel@tonic-gate break;
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate } else {
4000Sstevel@tonic-gate *cp++ = *start++;
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate }
4030Sstevel@tonic-gate *cp = '\0';
4040Sstevel@tonic-gate return (1);
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate /*
4090Sstevel@tonic-gate * Function:
4100Sstevel@tonic-gate * ib_service_record_add
4110Sstevel@tonic-gate * Input:
4120Sstevel@tonic-gate * service - name of the service
4130Sstevel@tonic-gate * type - type of the service
4140Sstevel@tonic-gate * Output:
4150Sstevel@tonic-gate * rec - one valid service record
4160Sstevel@tonic-gate * Returns:
4170Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
4180Sstevel@tonic-gate * Description:
4190Sstevel@tonic-gate * Add one record to internal data structures
4200Sstevel@tonic-gate */
4210Sstevel@tonic-gate static int
ib_service_record_add(char * service,ib_service_type_t type)4220Sstevel@tonic-gate ib_service_record_add(char *service, ib_service_type_t type)
4230Sstevel@tonic-gate {
4240Sstevel@tonic-gate ib_svc_rec_t *tmp, *recp;
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate DPRINTF("ib_service_record_add: (%x, %s) "
4270Sstevel@tonic-gate "(#port = %d #vppa = %d #hca = %d)\n", type, service,
4280Sstevel@tonic-gate ibcfg_nport_services, ibcfg_nvppa_services,
4290Sstevel@tonic-gate ibcfg_nhca_services);
4300Sstevel@tonic-gate recp = (ib_svc_rec_t *)calloc(1, sizeof (ib_svc_rec_t));
4310Sstevel@tonic-gate if (recp == NULL)
4320Sstevel@tonic-gate return (CFGA_IB_ALLOC_FAIL);
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate recp->type = type;
4350Sstevel@tonic-gate recp->name = strdup((char *)service);
4360Sstevel@tonic-gate if (type == IB_PORT_SERVICE) {
4370Sstevel@tonic-gate if (ibcfg_port_head) {
4380Sstevel@tonic-gate for (tmp = ibcfg_port_head; tmp->next != NULL; )
4390Sstevel@tonic-gate tmp = tmp->next;
4400Sstevel@tonic-gate tmp->next = recp;
4410Sstevel@tonic-gate } else
4420Sstevel@tonic-gate ibcfg_port_head = recp;
4430Sstevel@tonic-gate ibcfg_nport_services++;
4440Sstevel@tonic-gate } else if (type == IB_VPPA_SERVICE) {
4450Sstevel@tonic-gate if (ibcfg_vppa_head) {
4460Sstevel@tonic-gate for (tmp = ibcfg_vppa_head; tmp->next != NULL; )
4470Sstevel@tonic-gate tmp = tmp->next;
4480Sstevel@tonic-gate tmp->next = recp;
4490Sstevel@tonic-gate } else
4500Sstevel@tonic-gate ibcfg_vppa_head = recp;
4510Sstevel@tonic-gate ibcfg_nvppa_services++;
4520Sstevel@tonic-gate } else if (type == IB_HCASVC_SERVICE) {
4530Sstevel@tonic-gate if (ibcfg_hca_head) {
4540Sstevel@tonic-gate for (tmp = ibcfg_hca_head; tmp->next != NULL; )
4550Sstevel@tonic-gate tmp = tmp->next;
4560Sstevel@tonic-gate tmp->next = recp;
4570Sstevel@tonic-gate } else
4580Sstevel@tonic-gate ibcfg_hca_head = recp;
4590Sstevel@tonic-gate ibcfg_nhca_services++;
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate return (CFGA_IB_OK);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate /*
4670Sstevel@tonic-gate * Function:
4680Sstevel@tonic-gate * ib_get_services
4690Sstevel@tonic-gate * Input:
4700Sstevel@tonic-gate * errmsg - Error message filled in case of a failure
4710Sstevel@tonic-gate * Output:
4720Sstevel@tonic-gate * rec - one valid service record
4730Sstevel@tonic-gate * Returns:
4740Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
4750Sstevel@tonic-gate * Description:
4760Sstevel@tonic-gate * Fetch one record from the IBCONF_FILE
4770Sstevel@tonic-gate */
4780Sstevel@tonic-gate static ib_token_t
ib_get_services(char ** errmsg)4790Sstevel@tonic-gate ib_get_services(char **errmsg)
4800Sstevel@tonic-gate {
4810Sstevel@tonic-gate char tokval[MAXLINESIZE];
4820Sstevel@tonic-gate char *llptr;
4830Sstevel@tonic-gate boolean_t sor = B_TRUE;
4840Sstevel@tonic-gate ib_token_t token;
4850Sstevel@tonic-gate ib_service_type_t cfgvar;
4860Sstevel@tonic-gate ib_parse_state_t parse_state = IB_NEWVAR;
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate token = ib_lex(tokval, errmsg);
4890Sstevel@tonic-gate while ((token != EOF) && (token != SEMICOLON)) {
4900Sstevel@tonic-gate if (token == STAR || token == POUND) {
4910Sstevel@tonic-gate /* skip comments */
4920Sstevel@tonic-gate ib_find_eol();
4930Sstevel@tonic-gate } else if (token == NEWLINE) {
4940Sstevel@tonic-gate ibcfg_linenum++;
4950Sstevel@tonic-gate } else if (token == NAME || token == STRING) {
4960Sstevel@tonic-gate if (parse_state == IB_NEWVAR) {
4970Sstevel@tonic-gate cfgvar = ib_get_var_type(tokval);
4980Sstevel@tonic-gate if (cfgvar == IB_NONE) {
4990Sstevel@tonic-gate parse_state = IB_ERROR;
5000Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5010Sstevel@tonic-gate "Syntax Error: Invalid type %s",
5020Sstevel@tonic-gate tokval);
5030Sstevel@tonic-gate } else {
5040Sstevel@tonic-gate /* Note the beginning of the entry */
5050Sstevel@tonic-gate if (sor) {
5060Sstevel@tonic-gate ibcfg_brec = ibcfg_btoken;
5070Sstevel@tonic-gate sor = B_FALSE;
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate parse_state = IB_CONFIG_VAR;
5100Sstevel@tonic-gate if (cfgvar == IB_PORT_SERVICE)
5110Sstevel@tonic-gate bportrec = ibcfg_cntr + 1;
5120Sstevel@tonic-gate else if (cfgvar == IB_VPPA_SERVICE)
5130Sstevel@tonic-gate bvpparec = ibcfg_cntr + 1;
5140Sstevel@tonic-gate else if (cfgvar == IB_HCASVC_SERVICE)
5150Sstevel@tonic-gate bhcarec = ibcfg_cntr + 1;
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate } else if (parse_state == IB_VAR_VALUE) {
5190Sstevel@tonic-gate llptr = NULL;
5200Sstevel@tonic-gate if (ib_get_string(&llptr, tokval)) {
5210Sstevel@tonic-gate if ((cfgvar == IB_PORT_SERVICE) ||
5220Sstevel@tonic-gate (cfgvar == IB_VPPA_SERVICE) ||
5230Sstevel@tonic-gate (cfgvar == IB_HCASVC_SERVICE)) {
5240Sstevel@tonic-gate if (ib_service_record_valid(
525*9713SBill.Taylor@Sun.COM llptr) &&
526*9713SBill.Taylor@Sun.COM ib_service_record_add(
527*9713SBill.Taylor@Sun.COM (char *)llptr, cfgvar) !=
528*9713SBill.Taylor@Sun.COM CFGA_IB_OK) {
529*9713SBill.Taylor@Sun.COM return (E_O_F);
5300Sstevel@tonic-gate } else {
5310Sstevel@tonic-gate parse_state =
532*9713SBill.Taylor@Sun.COM IB_CONFIG_VAR;
5330Sstevel@tonic-gate }
5340Sstevel@tonic-gate } else if ((cfgvar == IB_NAME) ||
5350Sstevel@tonic-gate (cfgvar == IB_CLASS)) {
5360Sstevel@tonic-gate free((char *)llptr);
5370Sstevel@tonic-gate parse_state = IB_NEWVAR;
5380Sstevel@tonic-gate } else {
5390Sstevel@tonic-gate free((char *)llptr);
5400Sstevel@tonic-gate parse_state = IB_ERROR;
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate } else {
5430Sstevel@tonic-gate parse_state = IB_ERROR;
5440Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5450Sstevel@tonic-gate "Syntax Error: Invalid value %s "
5460Sstevel@tonic-gate "for type: %s\n", tokval,
5470Sstevel@tonic-gate ibcfg_varlist[cfgvar].name);
5480Sstevel@tonic-gate }
5490Sstevel@tonic-gate } else if (parse_state == IB_ERROR) {
5500Sstevel@tonic-gate /* just skip */
5510Sstevel@tonic-gate DPRINTF("ib_get_services: ERROR\n");
5520Sstevel@tonic-gate } else {
5530Sstevel@tonic-gate parse_state = IB_ERROR;
5540Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5550Sstevel@tonic-gate "Syntax Error: at %s", tokval);
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate } else if (token == COMMA || token == EQUALS) {
5580Sstevel@tonic-gate if (parse_state == IB_CONFIG_VAR) {
5590Sstevel@tonic-gate if (cfgvar == IB_NONE) {
5600Sstevel@tonic-gate parse_state = IB_ERROR;
5610Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5620Sstevel@tonic-gate "Syntax Error: unexpected '='");
5630Sstevel@tonic-gate } else {
5640Sstevel@tonic-gate parse_state = IB_VAR_VALUE;
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate } else if (parse_state != IB_ERROR) {
5670Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5680Sstevel@tonic-gate "Syntax Error: unexpected '='");
5690Sstevel@tonic-gate parse_state = IB_ERROR;
5700Sstevel@tonic-gate }
5710Sstevel@tonic-gate } else {
5720Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
5730Sstevel@tonic-gate "Syntax Error: at: %s", tokval);
5740Sstevel@tonic-gate parse_state = IB_ERROR;
5750Sstevel@tonic-gate }
5760Sstevel@tonic-gate token = ib_lex(tokval, errmsg);
5770Sstevel@tonic-gate if (ib_get_var_type(tokval) != IB_NONE)
5780Sstevel@tonic-gate parse_state = IB_NEWVAR;
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate return (token);
5810Sstevel@tonic-gate }
5820Sstevel@tonic-gate
5830Sstevel@tonic-gate /*
5840Sstevel@tonic-gate * Function:
5850Sstevel@tonic-gate * ib_cmp_service
5860Sstevel@tonic-gate * Input:
5870Sstevel@tonic-gate * NONE
5880Sstevel@tonic-gate * Output:
5890Sstevel@tonic-gate * NONE
5900Sstevel@tonic-gate * Returns:
5910Sstevel@tonic-gate * B_TRUE if this service is already seen. B_FALSE if not.
5920Sstevel@tonic-gate * Description:
5930Sstevel@tonic-gate * Compare the service just read from the services already seen.
5940Sstevel@tonic-gate * Check if this service was already seen or not.
5950Sstevel@tonic-gate */
5960Sstevel@tonic-gate static boolean_t
ib_cmp_service()5970Sstevel@tonic-gate ib_cmp_service()
5980Sstevel@tonic-gate {
5990Sstevel@tonic-gate ib_svc_rec_t *recp;
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate DPRINTF("ib_cmp_service: (%x, %s) "
6020Sstevel@tonic-gate "(#port = %d #vppa = %d #hca = %d)\n", service_type,
6030Sstevel@tonic-gate service_name, ibcfg_nport_services, ibcfg_nvppa_services,
6040Sstevel@tonic-gate ibcfg_nhca_services);
6050Sstevel@tonic-gate
6060Sstevel@tonic-gate for (recp = ibcfg_port_head; recp != NULL; recp = recp->next) {
6070Sstevel@tonic-gate DPRINTF("ib_cmp_service:P usvc = %s, usvc_name = %s\n",
6080Sstevel@tonic-gate service_name, recp->name ? recp->name : "NONE");
6090Sstevel@tonic-gate if (recp->name && strcmp(recp->name, service_name) == 0)
6100Sstevel@tonic-gate return (B_TRUE);
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate for (recp = ibcfg_vppa_head; recp != NULL; recp = recp->next) {
6130Sstevel@tonic-gate DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
6140Sstevel@tonic-gate recp->type, recp->name ? recp->name : "NONE");
6150Sstevel@tonic-gate if (recp->name && strcmp(recp->name, service_name) == 0)
6160Sstevel@tonic-gate return (B_TRUE);
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate for (recp = ibcfg_hca_head; recp != NULL; recp = recp->next) {
6190Sstevel@tonic-gate DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
6200Sstevel@tonic-gate recp->type, recp->name ? recp->name : "NONE");
6210Sstevel@tonic-gate if (recp->name && strcmp(recp->name, service_name) == 0)
6220Sstevel@tonic-gate return (B_TRUE);
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate
6250Sstevel@tonic-gate return (B_FALSE);
6260Sstevel@tonic-gate }
6270Sstevel@tonic-gate
6280Sstevel@tonic-gate
6290Sstevel@tonic-gate /*
6300Sstevel@tonic-gate * Function:
6310Sstevel@tonic-gate * ib_free_service_recs
6320Sstevel@tonic-gate * Input:
6330Sstevel@tonic-gate * NONE
6340Sstevel@tonic-gate * Output:
6350Sstevel@tonic-gate * NONE
6360Sstevel@tonic-gate * Returns:
6370Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
6380Sstevel@tonic-gate * Description:
6390Sstevel@tonic-gate * Free the service records allocated in ib_get_services
6400Sstevel@tonic-gate */
6410Sstevel@tonic-gate static void
ib_free_service_recs(void)6420Sstevel@tonic-gate ib_free_service_recs(void)
6430Sstevel@tonic-gate {
6440Sstevel@tonic-gate ib_svc_rec_t *tmp, *recp;
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate DPRINTF("ib_free_service_recs: "
6470Sstevel@tonic-gate "#port_services = %d, #vppa_services = %d, #hca_services = %d\n",
6480Sstevel@tonic-gate ibcfg_nport_services, ibcfg_nvppa_services, ibcfg_nhca_services);
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate for (recp = ibcfg_port_head; recp != NULL; ) {
6510Sstevel@tonic-gate if (recp && strlen(recp->name))
6520Sstevel@tonic-gate S_FREE(recp->name);
6530Sstevel@tonic-gate tmp = recp;
6540Sstevel@tonic-gate recp = recp->next;
6550Sstevel@tonic-gate S_FREE(tmp);
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate for (recp = ibcfg_vppa_head; recp != NULL; ) {
6590Sstevel@tonic-gate if (recp && strlen(recp->name))
6600Sstevel@tonic-gate S_FREE(recp->name);
6610Sstevel@tonic-gate tmp = recp;
6620Sstevel@tonic-gate recp = recp->next;
6630Sstevel@tonic-gate S_FREE(tmp);
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate
6660Sstevel@tonic-gate for (recp = ibcfg_hca_head; recp != NULL; ) {
6670Sstevel@tonic-gate if (recp && strlen(recp->name))
6680Sstevel@tonic-gate S_FREE(recp->name);
6690Sstevel@tonic-gate tmp = recp;
6700Sstevel@tonic-gate recp = recp->next;
6710Sstevel@tonic-gate S_FREE(tmp);
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate }
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate
6760Sstevel@tonic-gate /*
6770Sstevel@tonic-gate * Function:
6780Sstevel@tonic-gate * ib_cleanup_file
6790Sstevel@tonic-gate * Input:
6800Sstevel@tonic-gate * rval - error return value
6810Sstevel@tonic-gate * Output:
6820Sstevel@tonic-gate * NONE
6830Sstevel@tonic-gate * Returns:
6840Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
6850Sstevel@tonic-gate * Description:
6860Sstevel@tonic-gate * Cleanup IBCONF_FILE etc.
6870Sstevel@tonic-gate */
6880Sstevel@tonic-gate static int
ib_cleanup_file(int rval)6890Sstevel@tonic-gate ib_cleanup_file(int rval)
6900Sstevel@tonic-gate {
6910Sstevel@tonic-gate int rv = rval;
6920Sstevel@tonic-gate
6930Sstevel@tonic-gate ib_free_service_recs();
6940Sstevel@tonic-gate if (lockf(ibcfg_fd, F_ULOCK, 0) == -1) {
6950Sstevel@tonic-gate DPRINTF("ib_cleanup_file: unlock file %s failed\n",
6960Sstevel@tonic-gate ibconf_file);
6970Sstevel@tonic-gate rv = CFGA_IB_UNLOCK_FILE_ERR;
6980Sstevel@tonic-gate }
6990Sstevel@tonic-gate S_FREE(file_buf);
7000Sstevel@tonic-gate close(ibcfg_fd);
7010Sstevel@tonic-gate ibcfg_fd = -1;
7020Sstevel@tonic-gate if (ibcfg_tmpfd && wrote_tmp == B_TRUE) {
7030Sstevel@tonic-gate DPRINTF("ib_cleanup_file: tmpfile %s being renamed to %s\n",
7040Sstevel@tonic-gate tmpnamef, IBCONF_FILE);
7050Sstevel@tonic-gate close(ibcfg_tmpfd);
7060Sstevel@tonic-gate rename((const char *)tmpnamef, (const char *)IBCONF_FILE);
7070Sstevel@tonic-gate unlink(tmpnamef);
7080Sstevel@tonic-gate }
7090Sstevel@tonic-gate (void) mutex_unlock(&ibcfg_lock);
7100Sstevel@tonic-gate return (rv);
7110Sstevel@tonic-gate }
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate
7140Sstevel@tonic-gate /*
7150Sstevel@tonic-gate * Function:
7160Sstevel@tonic-gate * ib_init_file
7170Sstevel@tonic-gate * Input:
7180Sstevel@tonic-gate * NONE
7190Sstevel@tonic-gate * Output:
7200Sstevel@tonic-gate * errmsg - Error message filled in case of a failure
7210Sstevel@tonic-gate * Returns:
7220Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
7230Sstevel@tonic-gate * Description:
7240Sstevel@tonic-gate * Initialize IBCONF_FILE for reading
7250Sstevel@tonic-gate */
7260Sstevel@tonic-gate static int
ib_init_file(char ** errmsg)7270Sstevel@tonic-gate ib_init_file(char **errmsg)
7280Sstevel@tonic-gate {
7290Sstevel@tonic-gate (void) mutex_lock(&ibcfg_lock);
7300Sstevel@tonic-gate
7310Sstevel@tonic-gate if (*errmsg == (char *)NULL) {
7320Sstevel@tonic-gate if ((*errmsg = calloc(MAXPATHLEN, 1)) == (char *)NULL) {
7330Sstevel@tonic-gate (void) mutex_unlock(&ibcfg_lock);
7340Sstevel@tonic-gate DPRINTF("ib_init_file: calloc errmsg failed\n");
7350Sstevel@tonic-gate return (CFGA_IB_CONFIG_FILE_ERR);
7360Sstevel@tonic-gate }
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate /* Open the .conf file */
7400Sstevel@tonic-gate if ((ibcfg_fd = open(ibconf_file, O_RDWR, 0666)) == -1) {
7410Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
7420Sstevel@tonic-gate "failed to open %s file\n", ibconf_file);
7430Sstevel@tonic-gate (void) mutex_unlock(&ibcfg_lock);
7440Sstevel@tonic-gate return (CFGA_IB_CONFIG_FILE_ERR);
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate /* Lock the file so that another cfgadm instance doesn't modify it */
7480Sstevel@tonic-gate if (lockf(ibcfg_fd, F_TLOCK, 0) == -1) {
7490Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
7500Sstevel@tonic-gate "failed to lock %s file\n", ibconf_file);
7510Sstevel@tonic-gate close(ibcfg_fd);
7520Sstevel@tonic-gate ibcfg_fd = -1;
7530Sstevel@tonic-gate (void) mutex_unlock(&ibcfg_lock);
7540Sstevel@tonic-gate return (CFGA_IB_LOCK_FILE_ERR);
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate if (fstat(ibcfg_fd, &ibcfg_st) != 0) {
7580Sstevel@tonic-gate DPRINTF("ib_init_file: failed to fstat %s file\n", ibconf_file);
7590Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
7600Sstevel@tonic-gate }
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate /* Allocate a buffer for the file */
7630Sstevel@tonic-gate if ((file_buf = (char *)malloc(ibcfg_st.st_size)) == NULL) {
7640Sstevel@tonic-gate DPRINTF("ib_init_file: failed to fstat %s file\n",
7650Sstevel@tonic-gate ibconf_file);
7660Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate /* Check if size matches */
7700Sstevel@tonic-gate if (ibcfg_st.st_size != read(ibcfg_fd, file_buf, ibcfg_st.st_size)) {
7710Sstevel@tonic-gate DPRINTF("ib_init_file: failed to read %s file\n", ibconf_file);
7720Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate /*
7760Sstevel@tonic-gate * These variables need to be reinitialized here as they may
7770Sstevel@tonic-gate * have been modified by a previous thread that called this
7780Sstevel@tonic-gate * function
7790Sstevel@tonic-gate */
7800Sstevel@tonic-gate ibcfg_linenum = 1;
7810Sstevel@tonic-gate ibcfg_cntr = 0;
7820Sstevel@tonic-gate ibcfg_brec = 0;
7830Sstevel@tonic-gate ibcfg_btoken = 0;
7840Sstevel@tonic-gate
7850Sstevel@tonic-gate ibcfg_nport_services = 0;
7860Sstevel@tonic-gate ibcfg_nvppa_services = 0;
7870Sstevel@tonic-gate ibcfg_nhca_services = 0;
7880Sstevel@tonic-gate ibcfg_port_head = (ib_svc_rec_t *)NULL;
7890Sstevel@tonic-gate ibcfg_vppa_head = (ib_svc_rec_t *)NULL;
7900Sstevel@tonic-gate ibcfg_hca_head = (ib_svc_rec_t *)NULL;
7910Sstevel@tonic-gate return (CFGA_IB_OK);
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate /*
7960Sstevel@tonic-gate * Function:
7970Sstevel@tonic-gate * ib_add_service
7980Sstevel@tonic-gate * Input:
7990Sstevel@tonic-gate * NONE
8000Sstevel@tonic-gate * Output:
8010Sstevel@tonic-gate * errmsg - Error message filled in case of a failure
8020Sstevel@tonic-gate * Returns:
8030Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
8040Sstevel@tonic-gate * Description:
8050Sstevel@tonic-gate * open IBCONF_FILE and add "service_name".
8060Sstevel@tonic-gate */
8070Sstevel@tonic-gate int
ib_add_service(char ** errmsg)8080Sstevel@tonic-gate ib_add_service(char **errmsg)
8090Sstevel@tonic-gate {
8100Sstevel@tonic-gate int rval;
8110Sstevel@tonic-gate char *sbuf;
8120Sstevel@tonic-gate boolean_t found = B_FALSE;
8130Sstevel@tonic-gate ib_token_t token = NEWLINE;
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate DPRINTF("ib_add_service: type = %x, service_name=%s\n", service_type,
8160Sstevel@tonic-gate service_name);
8170Sstevel@tonic-gate if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
8180Sstevel@tonic-gate DPRINTF("ib_add_service: initializing file failed\n");
8190Sstevel@tonic-gate return (rval);
8200Sstevel@tonic-gate }
8210Sstevel@tonic-gate
8220Sstevel@tonic-gate /* Start reading the file */
8230Sstevel@tonic-gate while (token != EOF) {
8240Sstevel@tonic-gate token = ib_get_services(errmsg);
8250Sstevel@tonic-gate found = ib_cmp_service();
8260Sstevel@tonic-gate if (found == B_TRUE) {
8270Sstevel@tonic-gate DPRINTF("ib_add_service: token=%x, found=%x\n",
8280Sstevel@tonic-gate token, found);
8290Sstevel@tonic-gate break;
8300Sstevel@tonic-gate }
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate /* Service shouldn't already exist while adding */
8340Sstevel@tonic-gate if (found) {
8350Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN, "service entry %s exists ",
8360Sstevel@tonic-gate service_name);
8370Sstevel@tonic-gate DPRINTF("ib_add_service: invalid add operation\n");
8380Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
8390Sstevel@tonic-gate }
8400Sstevel@tonic-gate
8410Sstevel@tonic-gate DPRINTF("!FOUND and adding\n");
8420Sstevel@tonic-gate switch (service_type) {
8430Sstevel@tonic-gate case IB_PORT_SERVICE :
8440Sstevel@tonic-gate ibcfg_brec = bportrec;
8450Sstevel@tonic-gate break;
8460Sstevel@tonic-gate case IB_VPPA_SERVICE :
8470Sstevel@tonic-gate ibcfg_brec = bvpparec;
8480Sstevel@tonic-gate break;
8490Sstevel@tonic-gate case IB_HCASVC_SERVICE :
8500Sstevel@tonic-gate ibcfg_brec = bhcarec;
8510Sstevel@tonic-gate break;
8520Sstevel@tonic-gate default :
8530Sstevel@tonic-gate DPRINTF("ib_add_service: invalid add operation\n");
8540Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR));
8550Sstevel@tonic-gate }
8560Sstevel@tonic-gate
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate if ((sbuf = (char *)calloc(12, sizeof (char))) == NULL) {
8590Sstevel@tonic-gate DPRINTF("ib_add_service: failed to calloc sbuf %s file\n",
8600Sstevel@tonic-gate ibconf_file);
8610Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
8620Sstevel@tonic-gate }
8630Sstevel@tonic-gate if (file_buf[ibcfg_brec] == '"' && file_buf[ibcfg_brec + 1] == '"') {
8640Sstevel@tonic-gate (void) snprintf(sbuf, 9, "%s", service_name);
8650Sstevel@tonic-gate ibcfg_brec += 1;
8660Sstevel@tonic-gate } else
8670Sstevel@tonic-gate (void) snprintf(sbuf, 9, "\"%s\", ", service_name);
8680Sstevel@tonic-gate
8690Sstevel@tonic-gate
8700Sstevel@tonic-gate /* Seek to the beginning of the file */
8710Sstevel@tonic-gate if (lseek(ibcfg_fd, ibcfg_brec, SEEK_SET) == -1) {
8720Sstevel@tonic-gate DPRINTF("ib_add_service: lseek %s file failed\n", ibconf_file);
8730Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8740Sstevel@tonic-gate }
8750Sstevel@tonic-gate
8760Sstevel@tonic-gate /* Add service to w/ IBNEX */
8770Sstevel@tonic-gate if (ib_conf_control_ioctl(service_name, IBNEX_CONF_ENTRY_ADD)) {
8780Sstevel@tonic-gate DPRINTF("ib_add_service: ioctl add failed %d\n", errno);
8790Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN, "failed to add "
8800Sstevel@tonic-gate "%s service incore ", service_name);
8810Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
8820Sstevel@tonic-gate }
8830Sstevel@tonic-gate
8840Sstevel@tonic-gate /* Write the modified file */
8850Sstevel@tonic-gate if (write(ibcfg_fd, sbuf, strlen(sbuf)) == -1) {
8860Sstevel@tonic-gate DPRINTF("ib_add_service: write %s file failed\n", ibconf_file);
8870Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8880Sstevel@tonic-gate }
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate /* Write the rest of the file as it was */
8910Sstevel@tonic-gate if (write(ibcfg_fd, file_buf + ibcfg_brec,
8920Sstevel@tonic-gate ibcfg_st.st_size - ibcfg_brec) == -1) {
8930Sstevel@tonic-gate DPRINTF("ib_add_service: write %s file failed 2\n",
8940Sstevel@tonic-gate ibconf_file);
8950Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate
8980Sstevel@tonic-gate return (ib_cleanup_file(rval));
8990Sstevel@tonic-gate }
9000Sstevel@tonic-gate
9010Sstevel@tonic-gate
9020Sstevel@tonic-gate /*
9030Sstevel@tonic-gate * Function:
9040Sstevel@tonic-gate * ib_delete_service
9050Sstevel@tonic-gate * Input:
9060Sstevel@tonic-gate * NONE
9070Sstevel@tonic-gate * Output:
9080Sstevel@tonic-gate * errmsg - Error message filled in case of a failure
9090Sstevel@tonic-gate * Returns:
9100Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
9110Sstevel@tonic-gate * Description:
9120Sstevel@tonic-gate * open ib.conf file and delete "service_name"
9130Sstevel@tonic-gate */
9140Sstevel@tonic-gate int
ib_delete_service(char ** errmsg)9150Sstevel@tonic-gate ib_delete_service(char **errmsg)
9160Sstevel@tonic-gate {
9170Sstevel@tonic-gate int rval;
9180Sstevel@tonic-gate int num_svcs;
9190Sstevel@tonic-gate int skip_len;
9200Sstevel@tonic-gate int sbuf_len;
9210Sstevel@tonic-gate int tot_len;
9220Sstevel@tonic-gate char tmp[12];
9230Sstevel@tonic-gate char *sbuf = (char *)NULL;
9240Sstevel@tonic-gate boolean_t found = B_FALSE;
9250Sstevel@tonic-gate ib_token_t token = NEWLINE;
9260Sstevel@tonic-gate ib_svc_rec_t *recp;
9270Sstevel@tonic-gate
9280Sstevel@tonic-gate DPRINTF("ib_delete_service: type = %x, service_name=%s\n",
9290Sstevel@tonic-gate service_type, service_name);
9300Sstevel@tonic-gate if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
9310Sstevel@tonic-gate DPRINTF("ib_delete_service: initializing file failed\n");
9320Sstevel@tonic-gate return (rval);
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate /* Start reading the file */
9360Sstevel@tonic-gate while (token != EOF) {
9370Sstevel@tonic-gate token = ib_get_services(errmsg);
9380Sstevel@tonic-gate found = ib_cmp_service(); /* search for a match */
9390Sstevel@tonic-gate if (found == B_TRUE) {
9400Sstevel@tonic-gate DPRINTF("ib_delete_service: token=%x, found=%x\n",
9410Sstevel@tonic-gate token, found);
9420Sstevel@tonic-gate break;
9430Sstevel@tonic-gate }
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate
9460Sstevel@tonic-gate /* No service found, return */
9470Sstevel@tonic-gate if (!found) {
9480Sstevel@tonic-gate DPRINTF("ib_delete_service: invalid delete operation\n");
9490Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN, "service entry %s "
9500Sstevel@tonic-gate "does not exist ", service_name);
9510Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_NO_EXIST_ERR));
9520Sstevel@tonic-gate }
9530Sstevel@tonic-gate
9540Sstevel@tonic-gate DPRINTF("FOUND and deleting \n");
9550Sstevel@tonic-gate
9560Sstevel@tonic-gate switch (service_type) {
9570Sstevel@tonic-gate case IB_PORT_SERVICE :
9580Sstevel@tonic-gate ibcfg_brec = bportrec;
9590Sstevel@tonic-gate num_svcs = ibcfg_nport_services;
9600Sstevel@tonic-gate break;
9610Sstevel@tonic-gate case IB_VPPA_SERVICE :
9620Sstevel@tonic-gate ibcfg_brec = bvpparec;
9630Sstevel@tonic-gate num_svcs = ibcfg_nvppa_services;
9640Sstevel@tonic-gate break;
9650Sstevel@tonic-gate case IB_HCASVC_SERVICE :
9660Sstevel@tonic-gate ibcfg_brec = bhcarec;
9670Sstevel@tonic-gate num_svcs = ibcfg_nhca_services;
9680Sstevel@tonic-gate break;
9690Sstevel@tonic-gate default :
9700Sstevel@tonic-gate DPRINTF("ib_delete_service: invalid delete "
9710Sstevel@tonic-gate "operation\n");
9720Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR));
9730Sstevel@tonic-gate }
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate if ((sbuf = (char *)calloc(num_svcs * 8, sizeof (char))) == NULL) {
9760Sstevel@tonic-gate DPRINTF("ib_delete_service: sbuf alloc failed %s\n",
9770Sstevel@tonic-gate ibconf_file);
9780Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
9790Sstevel@tonic-gate }
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate if (num_svcs == 1) {
982*9713SBill.Taylor@Sun.COM (void) snprintf(sbuf, 9, "\"\"");
983*9713SBill.Taylor@Sun.COM sbuf_len = 2;
984*9713SBill.Taylor@Sun.COM skip_len = 0;
9850Sstevel@tonic-gate } else {
9860Sstevel@tonic-gate if (service_type == IB_PORT_SERVICE) {
9870Sstevel@tonic-gate for (recp = ibcfg_port_head; recp; recp = recp->next) {
9880Sstevel@tonic-gate if (strcmp(recp->name, service_name) == 0)
9890Sstevel@tonic-gate continue;
9900Sstevel@tonic-gate (void) snprintf(tmp, 9, "\"%s\", ", recp->name);
9910Sstevel@tonic-gate (void) strcat(sbuf, tmp);
9920Sstevel@tonic-gate }
9930Sstevel@tonic-gate
9940Sstevel@tonic-gate } else if (service_type == IB_VPPA_SERVICE) {
9950Sstevel@tonic-gate for (recp = ibcfg_vppa_head; recp; recp = recp->next) {
9960Sstevel@tonic-gate if (strcmp(recp->name, service_name) == 0)
9970Sstevel@tonic-gate continue;
9980Sstevel@tonic-gate (void) snprintf(tmp, 9, "\"%s\", ", recp->name);
9990Sstevel@tonic-gate (void) strcat(sbuf, tmp);
10000Sstevel@tonic-gate }
10010Sstevel@tonic-gate } else {
10020Sstevel@tonic-gate for (recp = ibcfg_hca_head; recp; recp = recp->next) {
10030Sstevel@tonic-gate if (strcmp(recp->name, service_name) == 0)
10040Sstevel@tonic-gate continue;
10050Sstevel@tonic-gate (void) snprintf(tmp, 9, "\"%s\", ", recp->name);
10060Sstevel@tonic-gate (void) strcat(sbuf, tmp);
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate }
10090Sstevel@tonic-gate skip_len = 4;
1010*9713SBill.Taylor@Sun.COM sbuf_len = strlen(sbuf);
1011*9713SBill.Taylor@Sun.COM sbuf[sbuf_len - 2] = '\0';
1012*9713SBill.Taylor@Sun.COM sbuf_len -= 2;
10130Sstevel@tonic-gate }
10140Sstevel@tonic-gate
10150Sstevel@tonic-gate tot_len = strlen(service_name) + skip_len;
10160Sstevel@tonic-gate
10170Sstevel@tonic-gate tmpnamef = tmpnam(ibconf_file);
10180Sstevel@tonic-gate DPRINTF("ib_delete_service: tmpnamef = %s\n", tmpnamef);
10190Sstevel@tonic-gate if ((ibcfg_tmpfd = creat(tmpnamef, 0666)) == -1) {
10200Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN,
10210Sstevel@tonic-gate "failed to creat %s file\n", ibconf_file);
10220Sstevel@tonic-gate DPRINTF("ib_delete_service: failed to creat tmpnamef\n");
10230Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
10240Sstevel@tonic-gate }
10250Sstevel@tonic-gate
10260Sstevel@tonic-gate /* Delete service from IBNEX */
10270Sstevel@tonic-gate if (ib_conf_control_ioctl(service_name, IBNEX_CONF_ENTRY_DEL)) {
10280Sstevel@tonic-gate DPRINTF("ib_delete_service: ioctl delete failed %d\n", errno);
10290Sstevel@tonic-gate (void) snprintf(*errmsg, MAXPATHLEN, "failed to delete "
10300Sstevel@tonic-gate "in core %s entry ", service_name);
10310Sstevel@tonic-gate close(ibcfg_tmpfd);
10320Sstevel@tonic-gate unlink(tmpnamef);
10330Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
10340Sstevel@tonic-gate }
10350Sstevel@tonic-gate
10360Sstevel@tonic-gate /* write till ibcfg_brec */
10370Sstevel@tonic-gate if (write(ibcfg_tmpfd, file_buf, ibcfg_brec) == -1) {
10380Sstevel@tonic-gate DPRINTF("ib_delete_service: write %s file failed 1\n",
10390Sstevel@tonic-gate ibconf_file);
10400Sstevel@tonic-gate close(ibcfg_tmpfd);
10410Sstevel@tonic-gate unlink(tmpnamef);
10420Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10430Sstevel@tonic-gate }
10440Sstevel@tonic-gate
10450Sstevel@tonic-gate /* write modified buffer */
10460Sstevel@tonic-gate if (write(ibcfg_tmpfd, sbuf, sbuf_len) == -1) {
10470Sstevel@tonic-gate DPRINTF("ib_delete_service: write %s file failed 2\n",
10480Sstevel@tonic-gate ibconf_file);
10490Sstevel@tonic-gate close(ibcfg_tmpfd);
10500Sstevel@tonic-gate unlink(tmpnamef);
10510Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10520Sstevel@tonic-gate }
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate /* Write the rest of the file as it was */
10550Sstevel@tonic-gate if (write(ibcfg_tmpfd, file_buf + ibcfg_brec + sbuf_len + tot_len,
1056*9713SBill.Taylor@Sun.COM ibcfg_st.st_size - ibcfg_brec - sbuf_len - tot_len) == -1) {
10570Sstevel@tonic-gate DPRINTF("ib_delete_service: write %s file failed 3\n",
10580Sstevel@tonic-gate ibconf_file);
10590Sstevel@tonic-gate close(ibcfg_tmpfd);
10600Sstevel@tonic-gate unlink(tmpnamef);
10610Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10620Sstevel@tonic-gate }
10630Sstevel@tonic-gate wrote_tmp = B_TRUE;
10640Sstevel@tonic-gate
10650Sstevel@tonic-gate /* No error encountered */
10660Sstevel@tonic-gate return (ib_cleanup_file(rval));
10670Sstevel@tonic-gate }
10680Sstevel@tonic-gate
10690Sstevel@tonic-gate
10700Sstevel@tonic-gate /*
10710Sstevel@tonic-gate * Function:
10720Sstevel@tonic-gate * ib_list_services
10730Sstevel@tonic-gate * Input:
10740Sstevel@tonic-gate * msgp - CFGADM message pointer
10750Sstevel@tonic-gate * Output:
10760Sstevel@tonic-gate * errmsg - Error message filled in case of a failure
10770Sstevel@tonic-gate * Returns:
10780Sstevel@tonic-gate * CFGA_IB_OK on success or an appropriate error
10790Sstevel@tonic-gate * Description:
10800Sstevel@tonic-gate * open IBCONF_FILE and list services.
10810Sstevel@tonic-gate */
10820Sstevel@tonic-gate int
ib_list_services(struct cfga_msg * msgp,char ** errmsg)10830Sstevel@tonic-gate ib_list_services(struct cfga_msg *msgp, char **errmsg)
10840Sstevel@tonic-gate {
10850Sstevel@tonic-gate int rval = CFGA_IB_OK;
10860Sstevel@tonic-gate char pbuf[IBCONF_SERVICE_HDR_LEN];
10870Sstevel@tonic-gate ib_token_t token = NEWLINE;
10880Sstevel@tonic-gate ib_svc_rec_t *recp;
10890Sstevel@tonic-gate
10900Sstevel@tonic-gate DPRINTF("ib_list_services:\n");
10910Sstevel@tonic-gate if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
10920Sstevel@tonic-gate DPRINTF("ib_list_services: initializing file failed\n");
10930Sstevel@tonic-gate return (rval);
10940Sstevel@tonic-gate }
10950Sstevel@tonic-gate
10960Sstevel@tonic-gate /* start reading the file */
10970Sstevel@tonic-gate while (token != EOF)
10980Sstevel@tonic-gate token = ib_get_services(errmsg);
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate DPRINTF("ib_list_services: #port_services = %d, #vppa_services = %d,"
11010Sstevel@tonic-gate " #hca_services = %d\n", ibcfg_nport_services,
11020Sstevel@tonic-gate ibcfg_nvppa_services, ibcfg_nhca_services);
11030Sstevel@tonic-gate
11040Sstevel@tonic-gate bzero(pbuf, IBCONF_SERVICE_HDR_LEN);
11050Sstevel@tonic-gate if (ibcfg_nport_services) {
11060Sstevel@tonic-gate (void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11070Sstevel@tonic-gate IBCONF_PORT_SERVICE_HDR);
11080Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11090Sstevel@tonic-gate for (recp = ibcfg_port_head; recp; recp = recp->next) {
11100Sstevel@tonic-gate DPRINTF("ib_list_services: svc_name = %s\n",
11110Sstevel@tonic-gate recp->name ? recp->name : "NONE");
11120Sstevel@tonic-gate (void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11130Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11140Sstevel@tonic-gate }
11150Sstevel@tonic-gate (void) snprintf(pbuf, 2, "\n");
11160Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11170Sstevel@tonic-gate }
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate if (ibcfg_nvppa_services) {
11200Sstevel@tonic-gate (void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11210Sstevel@tonic-gate IBCONF_VPPA_SERVICE_HDR);
11220Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11230Sstevel@tonic-gate for (recp = ibcfg_vppa_head; recp; recp = recp->next) {
11240Sstevel@tonic-gate DPRINTF("ib_list_services: svc_name = %s\n",
11250Sstevel@tonic-gate strlen(recp->name) > 0 ? recp->name : "NONE");
11260Sstevel@tonic-gate (void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11270Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11280Sstevel@tonic-gate }
11290Sstevel@tonic-gate }
11300Sstevel@tonic-gate
11310Sstevel@tonic-gate if (ibcfg_nhca_services) {
11320Sstevel@tonic-gate (void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11330Sstevel@tonic-gate IBCONF_HCA_SERVICE_HDR);
11340Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11350Sstevel@tonic-gate for (recp = ibcfg_hca_head; recp; recp = recp->next) {
11360Sstevel@tonic-gate DPRINTF("ib_list_services: svc_name = %s\n",
11370Sstevel@tonic-gate strlen(recp->name) > 0 ? recp->name : "NONE");
11380Sstevel@tonic-gate (void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11390Sstevel@tonic-gate cfga_msg(msgp, pbuf);
11400Sstevel@tonic-gate }
11410Sstevel@tonic-gate }
11420Sstevel@tonic-gate return (ib_cleanup_file(CFGA_IB_OK));
11430Sstevel@tonic-gate }
11440Sstevel@tonic-gate
11450Sstevel@tonic-gate
11460Sstevel@tonic-gate /*
11470Sstevel@tonic-gate * Function:
11480Sstevel@tonic-gate * ib_conf_control_ioctl
11490Sstevel@tonic-gate * Input:
11500Sstevel@tonic-gate * svc - Service being added/deleted
11510Sstevel@tonic-gate * cmd - Command to DEVCTL_AP_CONTROL devctl
11520Sstevel@tonic-gate * Output:
11530Sstevel@tonic-gate * NONE
11540Sstevel@tonic-gate * Returns:
11550Sstevel@tonic-gate * CFGA_IB_OK if it succeeds or an appropriate error.
11560Sstevel@tonic-gate * Description:
11570Sstevel@tonic-gate * Issues DEVCTL_AP_CONTROL devctl with cmd
11580Sstevel@tonic-gate */
11590Sstevel@tonic-gate static cfga_ib_ret_t
ib_conf_control_ioctl(char * svc,uint_t cmd)11600Sstevel@tonic-gate ib_conf_control_ioctl(char *svc, uint_t cmd)
11610Sstevel@tonic-gate {
11620Sstevel@tonic-gate int apid_fd = -1;
11630Sstevel@tonic-gate cfga_ib_ret_t rv = CFGA_IB_OK;
11640Sstevel@tonic-gate struct ibnex_ioctl_data ioctl_data;
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate DPRINTF("Service = %s len = %x, type = %x\n", svc,
11670Sstevel@tonic-gate strlen(svc), service_type);
11680Sstevel@tonic-gate
11690Sstevel@tonic-gate /* try to open the static IB ap_id */
11700Sstevel@tonic-gate if ((apid_fd = open(IB_STATIC_APID, O_RDONLY)) == -1) {
11710Sstevel@tonic-gate DPRINTF("ib_conf_control_ioctl: open failed: errno = %d\n",
11720Sstevel@tonic-gate errno);
11730Sstevel@tonic-gate /* Provides a more useful error msg */
11740Sstevel@tonic-gate rv = (errno == EBUSY) ? CFGA_IB_BUSY_ERR : CFGA_IB_OPEN_ERR;
11750Sstevel@tonic-gate return (rv);
11760Sstevel@tonic-gate }
11770Sstevel@tonic-gate
11780Sstevel@tonic-gate ioctl_data.cmd = cmd;
11790Sstevel@tonic-gate ioctl_data.misc_arg = (uint_t)service_type;
11800Sstevel@tonic-gate ioctl_data.buf = (caddr_t)svc;
11810Sstevel@tonic-gate ioctl_data.bufsiz = strlen(svc);
11820Sstevel@tonic-gate ioctl_data.ap_id = (caddr_t)IB_STATIC_APID;
11830Sstevel@tonic-gate ioctl_data.ap_id_len = strlen(IB_STATIC_APID);
11840Sstevel@tonic-gate
11850Sstevel@tonic-gate if (ioctl(apid_fd, DEVCTL_AP_CONTROL, &ioctl_data) != 0) {
11860Sstevel@tonic-gate DPRINTF("ib_conf_control_ioctl: size ioctl ERR, errno: %d\n",
11870Sstevel@tonic-gate errno);
11880Sstevel@tonic-gate rv = (errno == EBUSY) ? CFGA_IB_BUSY_ERR : CFGA_IB_IOCTL_ERR;
11890Sstevel@tonic-gate }
11900Sstevel@tonic-gate (void) close(apid_fd);
11910Sstevel@tonic-gate return (rv);
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate
11940Sstevel@tonic-gate /*
11950Sstevel@tonic-gate * This functions checks if the service name is valid. Valid
11960Sstevel@tonic-gate * service names have :
11970Sstevel@tonic-gate * 0 < strlen(name) <= 4
11980Sstevel@tonic-gate * Service name is unique
11990Sstevel@tonic-gate * Returns: 0 - Name is not valid, 1 - Name is valid
12000Sstevel@tonic-gate */
12010Sstevel@tonic-gate static int
ib_service_record_valid(char * sname)12020Sstevel@tonic-gate ib_service_record_valid(char *sname)
12030Sstevel@tonic-gate {
12040Sstevel@tonic-gate int rc = 1, len;
12050Sstevel@tonic-gate char *tmp_service_name;
12060Sstevel@tonic-gate
12070Sstevel@tonic-gate tmp_service_name = service_name;
12080Sstevel@tonic-gate service_name = strdup(sname);
12090Sstevel@tonic-gate len = strlen(sname);
12100Sstevel@tonic-gate if (len == 0 || len > 4) {
12110Sstevel@tonic-gate S_FREE(service_name);
12120Sstevel@tonic-gate service_name = tmp_service_name;
12130Sstevel@tonic-gate return (0);
12140Sstevel@tonic-gate }
12150Sstevel@tonic-gate if (ib_cmp_service() == B_TRUE)
12160Sstevel@tonic-gate rc = 0;
12170Sstevel@tonic-gate S_FREE(service_name);
12180Sstevel@tonic-gate service_name = tmp_service_name;
12190Sstevel@tonic-gate return (rc);
12200Sstevel@tonic-gate }
1221