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
57354SGiri.Adari@Sun.COM * Common Development and Distribution License (the "License").
67354SGiri.Adari@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*12163SRamaswamy.Tummala@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <unistd.h>
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/socket.h>
280Sstevel@tonic-gate #include <sys/sockio.h>
29*12163SRamaswamy.Tummala@Sun.COM #include <sys/stat.h>
300Sstevel@tonic-gate #include <netinet/in.h>
310Sstevel@tonic-gate #include <arpa/inet.h>
320Sstevel@tonic-gate #include <net/if.h>
330Sstevel@tonic-gate #include <stdio.h>
340Sstevel@tonic-gate #include <stdlib.h>
350Sstevel@tonic-gate #include <strings.h>
360Sstevel@tonic-gate #include <ctype.h>
370Sstevel@tonic-gate #include <errno.h>
380Sstevel@tonic-gate #include <libintl.h>
390Sstevel@tonic-gate #include <locale.h>
40*12163SRamaswamy.Tummala@Sun.COM #include <fcntl.h>
41*12163SRamaswamy.Tummala@Sun.COM #include <libdlpi.h>
42*12163SRamaswamy.Tummala@Sun.COM #include <libdladm.h>
43*12163SRamaswamy.Tummala@Sun.COM #include <libdlib.h>
44*12163SRamaswamy.Tummala@Sun.COM #include <libdllink.h>
45*12163SRamaswamy.Tummala@Sun.COM #include <sys/ib/ibnex/ibnex_devctl.h>
460Sstevel@tonic-gate
470Sstevel@tonic-gate #define DATADM_OP_VIEW 0x0000
480Sstevel@tonic-gate #define DATADM_OP_UPDATE 0x0001
490Sstevel@tonic-gate #define DATADM_OP_ADD 0x0002
500Sstevel@tonic-gate #define DATADM_OP_REMOVE 0x0003
510Sstevel@tonic-gate #define DATADM_NUM_OPS 0x0004
520Sstevel@tonic-gate #define DATADM_DAT_CONF "/etc/dat/dat.conf"
530Sstevel@tonic-gate #define DATADM_LINESZ 1024
540Sstevel@tonic-gate #define DATADM_NUM_SP_TOKENS 7
550Sstevel@tonic-gate #define DATADM_NUM_DAT_TOKENS 8
560Sstevel@tonic-gate #define DATADM_DRV_NAME "driver_name"
570Sstevel@tonic-gate #define DATADM_MAX_TOKENS 16
580Sstevel@tonic-gate
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate * generic entry
610Sstevel@tonic-gate * placed at the top of all entry types
620Sstevel@tonic-gate */
630Sstevel@tonic-gate typedef struct datadm_entry {
640Sstevel@tonic-gate struct datadm_entry *de_next;
650Sstevel@tonic-gate } datadm_entry_t;
660Sstevel@tonic-gate
670Sstevel@tonic-gate /*
680Sstevel@tonic-gate * list structure
690Sstevel@tonic-gate * can be manipulated using datadm_walk_list or
700Sstevel@tonic-gate * datadm_enqueue_entry
710Sstevel@tonic-gate */
720Sstevel@tonic-gate typedef struct datadm_list {
730Sstevel@tonic-gate datadm_entry_t *dl_head;
740Sstevel@tonic-gate datadm_entry_t *dl_tail;
750Sstevel@tonic-gate uint_t dl_count;
760Sstevel@tonic-gate } datadm_list_t;
770Sstevel@tonic-gate
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate * internal representation of the version string in
800Sstevel@tonic-gate * dat.conf or service_provider.conf. the format is
810Sstevel@tonic-gate * <dv_name><dv_major>.<dv_minor>
820Sstevel@tonic-gate */
830Sstevel@tonic-gate typedef struct datadm_version {
840Sstevel@tonic-gate char *dv_name;
850Sstevel@tonic-gate uint_t dv_major;
860Sstevel@tonic-gate uint_t dv_minor;
870Sstevel@tonic-gate } datadm_version_t;
880Sstevel@tonic-gate
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate * each sp_entry corresponds to an entry in dat.conf or
910Sstevel@tonic-gate * service_provider.conf. an sp_entry is processed by the
920Sstevel@tonic-gate * function datadm_process_sp_entry.
930Sstevel@tonic-gate */
940Sstevel@tonic-gate typedef struct datadm_sp_entry {
950Sstevel@tonic-gate datadm_entry_t spe_header;
960Sstevel@tonic-gate char *spe_devname;
970Sstevel@tonic-gate datadm_version_t spe_api_version;
980Sstevel@tonic-gate int spe_threadsafe;
990Sstevel@tonic-gate int spe_default;
1000Sstevel@tonic-gate char *spe_libpath;
1010Sstevel@tonic-gate datadm_version_t spe_sp_version;
1020Sstevel@tonic-gate char *spe_sp_data;
1030Sstevel@tonic-gate int spe_invalid;
1040Sstevel@tonic-gate } datadm_sp_entry_t;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate /*
1070Sstevel@tonic-gate * an hca_entry is created whenever a new hca device is
1080Sstevel@tonic-gate * encountered during sp_entry processing. this structure
1090Sstevel@tonic-gate * contains two lists. the sp_list holds sp entries that
1100Sstevel@tonic-gate * are added when sp entry processing occurs. duplicate
1110Sstevel@tonic-gate * sp entries are not added to this list. the ia_list may
1120Sstevel@tonic-gate * be built statically using the information in dat.conf or
113*12163SRamaswamy.Tummala@Sun.COM * dynamically. similar to the sp_list,
1140Sstevel@tonic-gate * the ia_list contains only unique entries.
1150Sstevel@tonic-gate */
1160Sstevel@tonic-gate typedef struct datadm_hca_entry {
1170Sstevel@tonic-gate datadm_entry_t he_header;
1180Sstevel@tonic-gate char *he_name;
1190Sstevel@tonic-gate datadm_list_t he_sp_list;
1200Sstevel@tonic-gate datadm_list_t he_ia_list;
1210Sstevel@tonic-gate } datadm_hca_entry_t;
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate * an ia_entry is created when a new ia name is encountered
1250Sstevel@tonic-gate * during sp_entry processing or when a new ia name is
126*12163SRamaswamy.Tummala@Sun.COM * discovered by datadm_build_ia_lists. ia_entry holds the ia
1270Sstevel@tonic-gate * device's instance number.
1280Sstevel@tonic-gate */
1290Sstevel@tonic-gate typedef struct datadm_ia_entry {
1300Sstevel@tonic-gate datadm_entry_t iae_header;
131*12163SRamaswamy.Tummala@Sun.COM char iae_name[MAXLINKNAMELEN];
1320Sstevel@tonic-gate } datadm_ia_entry_t;
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate /*
1350Sstevel@tonic-gate * a comment entry represents one of the comment lines at the
1360Sstevel@tonic-gate * top of dat.conf. a list of these lines are saved during the
1370Sstevel@tonic-gate * parsing of dat.conf. these lines are written back to dat.conf
1380Sstevel@tonic-gate * when dat.conf gets regenerated.
1390Sstevel@tonic-gate */
1400Sstevel@tonic-gate typedef struct datadm_cmnt_entry {
1410Sstevel@tonic-gate datadm_entry_t cmnt_header;
1420Sstevel@tonic-gate char *cmnt_line;
1430Sstevel@tonic-gate } datadm_cmnt_entry_t;
1440Sstevel@tonic-gate
145*12163SRamaswamy.Tummala@Sun.COM typedef struct datadm_hca_find_by_name {
146*12163SRamaswamy.Tummala@Sun.COM char *hf_name;
147*12163SRamaswamy.Tummala@Sun.COM datadm_hca_entry_t *hf_hca_entry;
148*12163SRamaswamy.Tummala@Sun.COM } datadm_hca_find_by_name_t;
149*12163SRamaswamy.Tummala@Sun.COM
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate * 2nd argument to datadm_hca_entry_find.
1520Sstevel@tonic-gate * hf_hca_entry is filled in if an hca_entry with
1530Sstevel@tonic-gate * a matching he_name is found.
1540Sstevel@tonic-gate */
1550Sstevel@tonic-gate typedef struct datadm_hca_find {
1560Sstevel@tonic-gate datadm_sp_entry_t *hf_sp_entry;
1570Sstevel@tonic-gate datadm_hca_entry_t *hf_hca_entry;
1580Sstevel@tonic-gate } datadm_hca_find_t;
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate /*
1610Sstevel@tonic-gate * 2nd argument to datadm_ia_entry_find.
1620Sstevel@tonic-gate * if_ia_entry is filled in if an ia_entry with
163*12163SRamaswamy.Tummala@Sun.COM * a matching ia_name is found.
1640Sstevel@tonic-gate */
1650Sstevel@tonic-gate typedef struct datadm_ia_find {
166*12163SRamaswamy.Tummala@Sun.COM char *if_ia_name;
1670Sstevel@tonic-gate datadm_ia_entry_t *if_ia_entry;
1680Sstevel@tonic-gate } datadm_ia_find_t;
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate /*
171*12163SRamaswamy.Tummala@Sun.COM * this gets passed to datadm_add_plink.
1720Sstevel@tonic-gate */
1730Sstevel@tonic-gate typedef struct datadm_fill_ia_list {
174*12163SRamaswamy.Tummala@Sun.COM datadm_list_t *ia_hca_list;
175*12163SRamaswamy.Tummala@Sun.COM dladm_handle_t ia_dlh;
176*12163SRamaswamy.Tummala@Sun.COM int ia_ibnex_fd;
1770Sstevel@tonic-gate int ia_sock_fd_v4;
1780Sstevel@tonic-gate int ia_sock_fd_v6;
1790Sstevel@tonic-gate } datadm_fill_ia_list_t;
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate /*
1820Sstevel@tonic-gate * this defines the commandline parameters specified
1830Sstevel@tonic-gate * by the user.
1840Sstevel@tonic-gate */
1850Sstevel@tonic-gate typedef struct datadm_args {
1860Sstevel@tonic-gate char *da_sp_conf;
1870Sstevel@tonic-gate char *da_dat_conf;
1880Sstevel@tonic-gate int da_op_type;
1890Sstevel@tonic-gate } datadm_args_t;
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate static datadm_args_t datadm_args;
1920Sstevel@tonic-gate static datadm_list_t datadm_conf_header;
1930Sstevel@tonic-gate static char *datadm_conf_header_default =
1940Sstevel@tonic-gate "#\n"
195*12163SRamaswamy.Tummala@Sun.COM "# Copyright (c) 2003, 2010, Oracle and/or its affiliates. "
196*12163SRamaswamy.Tummala@Sun.COM "All rights reserved.\n"
1970Sstevel@tonic-gate "#\n"
1980Sstevel@tonic-gate "# DAT configuration file.\n"
1990Sstevel@tonic-gate "#\n"
2000Sstevel@tonic-gate "# This file is updated using the datadm(1) command.\n"
2010Sstevel@tonic-gate "# Do not hand edit this file.\n"
2020Sstevel@tonic-gate "# See datadm(1) man page for more details.\n"
2030Sstevel@tonic-gate "#\n"
2040Sstevel@tonic-gate "# The fields in this file are -\n"
2050Sstevel@tonic-gate "#\n"
2060Sstevel@tonic-gate "# IAname version threadsafe default library-path provider-version \\\n"
2070Sstevel@tonic-gate "# instance-data platform-information\n"
2080Sstevel@tonic-gate "#\n";
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate /*
2110Sstevel@tonic-gate * common parsing functions.
2120Sstevel@tonic-gate */
2130Sstevel@tonic-gate typedef int (*datadm_parse_func_t)(char *, void *);
2140Sstevel@tonic-gate static int datadm_parse_line(char *, char *[], int *);
2150Sstevel@tonic-gate static int datadm_parse_generic_str(char *, char **);
2160Sstevel@tonic-gate static int datadm_parse_nonnull_str(char *, char **);
2170Sstevel@tonic-gate static int datadm_parse_version(char *, datadm_version_t *);
2180Sstevel@tonic-gate static int datadm_parse_devname(char *, datadm_sp_entry_t *);
2190Sstevel@tonic-gate static int datadm_parse_api_version(char *, datadm_sp_entry_t *);
2200Sstevel@tonic-gate static int datadm_parse_threadsafe(char *, datadm_sp_entry_t *);
2210Sstevel@tonic-gate static int datadm_parse_default(char *, datadm_sp_entry_t *);
2220Sstevel@tonic-gate static int datadm_parse_libpath(char *, datadm_sp_entry_t *);
2230Sstevel@tonic-gate static int datadm_parse_sp_version(char *, datadm_sp_entry_t *);
2240Sstevel@tonic-gate static int datadm_parse_sp_data(char *, datadm_sp_entry_t *);
225*12163SRamaswamy.Tummala@Sun.COM static int datadm_parse_ia_name(char *, char *);
2260Sstevel@tonic-gate
2270Sstevel@tonic-gate /*
2280Sstevel@tonic-gate * utility functions
2290Sstevel@tonic-gate */
2300Sstevel@tonic-gate static void datadm_enqueue_entry(datadm_list_t *, datadm_entry_t *);
2310Sstevel@tonic-gate static int datadm_walk_list(datadm_list_t *,
2320Sstevel@tonic-gate int (*)(datadm_entry_t *, void *), void *);
2330Sstevel@tonic-gate static int datadm_str_match(char *, char *);
2340Sstevel@tonic-gate static int datadm_version_match(datadm_version_t *, datadm_version_t *);
2350Sstevel@tonic-gate static int datadm_sp_entry_match(datadm_sp_entry_t *, datadm_sp_entry_t *);
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate * entry allocation/deallocation
2390Sstevel@tonic-gate */
2400Sstevel@tonic-gate static datadm_sp_entry_t *datadm_alloc_sp_entry(void);
2410Sstevel@tonic-gate static datadm_ia_entry_t *datadm_alloc_ia_entry(void);
2420Sstevel@tonic-gate static datadm_hca_entry_t *datadm_alloc_hca_entry(void);
2430Sstevel@tonic-gate static datadm_cmnt_entry_t *datadm_alloc_cmnt_entry(void);
2440Sstevel@tonic-gate static void datadm_free_sp_entry(datadm_sp_entry_t *);
2450Sstevel@tonic-gate static void datadm_free_ia_entry(datadm_ia_entry_t *);
2460Sstevel@tonic-gate static void datadm_free_hca_entry(datadm_hca_entry_t *);
2470Sstevel@tonic-gate static void datadm_free_cmnt_entry(datadm_cmnt_entry_t *);
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate /*
2510Sstevel@tonic-gate * high level parsing functions
2520Sstevel@tonic-gate */
2530Sstevel@tonic-gate static int datadm_parse_sp_conf(datadm_list_t *);
2540Sstevel@tonic-gate static int datadm_parse_dat_conf(datadm_list_t *);
255*12163SRamaswamy.Tummala@Sun.COM static int datadm_process_sp_entry(datadm_list_t *, datadm_sp_entry_t *,
256*12163SRamaswamy.Tummala@Sun.COM char *);
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate /*
2590Sstevel@tonic-gate * ia devices discovery
2600Sstevel@tonic-gate */
2610Sstevel@tonic-gate static int datadm_build_ia_lists(datadm_list_t *);
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate /*
2640Sstevel@tonic-gate * helper function for OP_REMOVE
2650Sstevel@tonic-gate */
2660Sstevel@tonic-gate static void datadm_invalidate_common_sp_entries(datadm_list_t *,
2670Sstevel@tonic-gate datadm_list_t *);
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate /*
2700Sstevel@tonic-gate * output generation
2710Sstevel@tonic-gate */
2720Sstevel@tonic-gate static int datadm_generate_dat_conf(datadm_list_t *);
2730Sstevel@tonic-gate static int datadm_generate_conf_header(FILE *);
2740Sstevel@tonic-gate static int datadm_generate_conf_entry(FILE *, datadm_ia_entry_t *,
2750Sstevel@tonic-gate datadm_sp_entry_t *);
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate * datadm operations
2790Sstevel@tonic-gate */
2800Sstevel@tonic-gate static int datadm_view(void);
2810Sstevel@tonic-gate static int datadm_update(void);
2820Sstevel@tonic-gate static int datadm_add(void);
2830Sstevel@tonic-gate static int datadm_remove(void);
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate /*
2860Sstevel@tonic-gate * usage
2870Sstevel@tonic-gate */
2880Sstevel@tonic-gate static void datadm_usage(void);
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate /*
2920Sstevel@tonic-gate * parse function tables
2930Sstevel@tonic-gate */
2940Sstevel@tonic-gate static datadm_parse_func_t datadm_sp_parse_funcs[DATADM_NUM_SP_TOKENS] = {
2950Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname,
2960Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version,
2970Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe,
2980Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default,
2990Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath,
3000Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version,
3010Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data
3020Sstevel@tonic-gate };
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate static datadm_parse_func_t datadm_dat_parse_funcs[DATADM_NUM_DAT_TOKENS] = {
3050Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_ia_name,
3060Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version,
3070Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe,
3080Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default,
3090Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath,
3100Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version,
3110Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data,
3120Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname
3130Sstevel@tonic-gate };
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate /*
3160Sstevel@tonic-gate * operation table
3170Sstevel@tonic-gate */
3180Sstevel@tonic-gate static int (*datadm_ops[DATADM_NUM_OPS])(void) = {
3190Sstevel@tonic-gate datadm_view,
3200Sstevel@tonic-gate datadm_update,
3210Sstevel@tonic-gate datadm_add,
3220Sstevel@tonic-gate datadm_remove
3230Sstevel@tonic-gate };
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate static void
datadm_usage(void)3260Sstevel@tonic-gate datadm_usage(void)
3270Sstevel@tonic-gate {
3280Sstevel@tonic-gate (void) fprintf(stderr, gettext(
3290Sstevel@tonic-gate "usage: datadm -v\n"
3300Sstevel@tonic-gate " -u\n"
3310Sstevel@tonic-gate " -a <service_provider.conf>\n"
3320Sstevel@tonic-gate " -r <service_provider.conf>\n"));
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate static int
datadm_parse_generic_str(char * str,char ** strptr)3360Sstevel@tonic-gate datadm_parse_generic_str(char *str, char **strptr)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate int len;
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate len = strlen(str);
3410Sstevel@tonic-gate *strptr = (char *)malloc(len + 1);
3420Sstevel@tonic-gate if (*strptr == NULL) {
3430Sstevel@tonic-gate return (-1);
3440Sstevel@tonic-gate }
3450Sstevel@tonic-gate (void) strcpy(*strptr, str);
3460Sstevel@tonic-gate return (0);
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate /*
3500Sstevel@tonic-gate * this function strips off leading and trailing
3510Sstevel@tonic-gate * whitespaces and returns an error for null or
3520Sstevel@tonic-gate * empty strings.
3530Sstevel@tonic-gate */
3540Sstevel@tonic-gate static int
datadm_parse_nonnull_str(char * str,char ** strptr)3550Sstevel@tonic-gate datadm_parse_nonnull_str(char *str, char **strptr)
3560Sstevel@tonic-gate {
3570Sstevel@tonic-gate int len, i;
3580Sstevel@tonic-gate char *start;
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate if (str[0] == '\0') {
3610Sstevel@tonic-gate return (-1);
3620Sstevel@tonic-gate }
3630Sstevel@tonic-gate start = str;
3640Sstevel@tonic-gate for (i = 0; str[i] != '\0'; i++) {
3650Sstevel@tonic-gate if (!isspace(str[i])) {
3660Sstevel@tonic-gate start = &str[i];
3670Sstevel@tonic-gate break;
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate }
3700Sstevel@tonic-gate for (; str[i] != '\0'; i++) {
3710Sstevel@tonic-gate if (isspace(str[i])) {
3720Sstevel@tonic-gate str[i] = '\0';
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate len = strlen(start);
3760Sstevel@tonic-gate *strptr = (char *)malloc(len + 1);
3770Sstevel@tonic-gate if (*strptr == NULL) {
3780Sstevel@tonic-gate return (-1);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate (void) strcpy(*strptr, start);
3810Sstevel@tonic-gate return (0);
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate /*
3850Sstevel@tonic-gate * parses the api_version and sp_version fields in
3860Sstevel@tonic-gate * dat.conf and service_provider.conf
3870Sstevel@tonic-gate */
3880Sstevel@tonic-gate static int
datadm_parse_version(char * str,datadm_version_t * version)3890Sstevel@tonic-gate datadm_parse_version(char *str, datadm_version_t *version)
3900Sstevel@tonic-gate {
3910Sstevel@tonic-gate int i = 0, len;
3920Sstevel@tonic-gate int major_idx, minor_idx;
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate len = strlen(str);
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate for (i = 0; i < len; i++) {
3970Sstevel@tonic-gate if (isdigit(str[i])) break;
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate if (i == len) {
4000Sstevel@tonic-gate return (-1);
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate if (i > 0) {
4030Sstevel@tonic-gate version->dv_name = (char *)malloc(i + 1);
4040Sstevel@tonic-gate bcopy(str, version->dv_name, i);
4050Sstevel@tonic-gate version->dv_name[i] = '\0';
4060Sstevel@tonic-gate } else {
4070Sstevel@tonic-gate version->dv_name = NULL;
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate major_idx = i;
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate for (; i < len; i++) {
4120Sstevel@tonic-gate if (!isdigit(str[i])) break;
4130Sstevel@tonic-gate }
4140Sstevel@tonic-gate if (i == len) {
4150Sstevel@tonic-gate return (-1);
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate if (str[i] != '.') {
4180Sstevel@tonic-gate return (-1);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate minor_idx = ++i;
4210Sstevel@tonic-gate if (i == len) {
4220Sstevel@tonic-gate return (-1);
4230Sstevel@tonic-gate }
4240Sstevel@tonic-gate for (; i < len; i++) {
4250Sstevel@tonic-gate if (!isdigit(str[i])) break;
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate if (i != len) {
4280Sstevel@tonic-gate return (-1);
4290Sstevel@tonic-gate }
4300Sstevel@tonic-gate version->dv_major = atoi(str + major_idx);
4310Sstevel@tonic-gate version->dv_minor = atoi(str + minor_idx);
4320Sstevel@tonic-gate return (0);
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate /*
4360Sstevel@tonic-gate * parses the ia_name field in dat.conf
4370Sstevel@tonic-gate */
4380Sstevel@tonic-gate static int
datadm_parse_ia_name(char * str,char * ia_name)439*12163SRamaswamy.Tummala@Sun.COM datadm_parse_ia_name(char *str, char *ia_name)
4400Sstevel@tonic-gate {
441*12163SRamaswamy.Tummala@Sun.COM if (strlen(str) >= MAXLINKNAMELEN)
4420Sstevel@tonic-gate return (-1);
443*12163SRamaswamy.Tummala@Sun.COM (void) strlcpy(ia_name, str, MAXLINKNAMELEN);
4440Sstevel@tonic-gate return (0);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate /*
4480Sstevel@tonic-gate * parses the device name, strips leading and trailing spaces.
4490Sstevel@tonic-gate * the format should be "driver_name=<dev_name>"
4500Sstevel@tonic-gate */
4510Sstevel@tonic-gate static int
datadm_parse_devname(char * str,datadm_sp_entry_t * sp_entry)4520Sstevel@tonic-gate datadm_parse_devname(char *str, datadm_sp_entry_t *sp_entry)
4530Sstevel@tonic-gate {
4540Sstevel@tonic-gate int len, dlen, i, j = 0;
4550Sstevel@tonic-gate char *drv_name = DATADM_DRV_NAME;
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate len = strlen(str);
4580Sstevel@tonic-gate dlen = strlen(drv_name);
4590Sstevel@tonic-gate
4600Sstevel@tonic-gate /*
4610Sstevel@tonic-gate * strip out leading spaces and try to match
4620Sstevel@tonic-gate * the expected string
4630Sstevel@tonic-gate */
4640Sstevel@tonic-gate for (i = 0; i < len; i++) {
4650Sstevel@tonic-gate if (isspace(str[i]) && j == 0) {
4660Sstevel@tonic-gate continue;
4670Sstevel@tonic-gate } else {
4680Sstevel@tonic-gate if (str[i] == drv_name[j]) {
4690Sstevel@tonic-gate j++;
4700Sstevel@tonic-gate if (j == dlen) {
4710Sstevel@tonic-gate break;
4720Sstevel@tonic-gate } else {
4730Sstevel@tonic-gate continue;
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate } else {
4760Sstevel@tonic-gate break;
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate }
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate /*
4820Sstevel@tonic-gate * j must be dlen if the matching string is found
4830Sstevel@tonic-gate */
4840Sstevel@tonic-gate if (j != dlen) {
4850Sstevel@tonic-gate return (-1);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate /*
4890Sstevel@tonic-gate * skip past the last char of drv_name
4900Sstevel@tonic-gate */
4910Sstevel@tonic-gate i++;
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate /*
4940Sstevel@tonic-gate * strip the spaces before the '='
4950Sstevel@tonic-gate */
4960Sstevel@tonic-gate for (; i < len; i++) {
4970Sstevel@tonic-gate if (!isspace(str[i])) {
4980Sstevel@tonic-gate break;
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate /*
5030Sstevel@tonic-gate * return if the string is too long or if
5040Sstevel@tonic-gate * the '=' isn't found
5050Sstevel@tonic-gate */
5060Sstevel@tonic-gate if (i >= len || str[i] != '=') {
5070Sstevel@tonic-gate return (-1);
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate i++;
5100Sstevel@tonic-gate if (i >= len) {
5110Sstevel@tonic-gate /*
5120Sstevel@tonic-gate * no string after the equal
5130Sstevel@tonic-gate */
5140Sstevel@tonic-gate return (-1);
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate return (datadm_parse_nonnull_str(str + i, &sp_entry->spe_devname));
5170Sstevel@tonic-gate }
5180Sstevel@tonic-gate
5190Sstevel@tonic-gate static int
datadm_parse_api_version(char * str,datadm_sp_entry_t * sp_entry)5200Sstevel@tonic-gate datadm_parse_api_version(char *str, datadm_sp_entry_t *sp_entry)
5210Sstevel@tonic-gate {
5220Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_api_version));
5230Sstevel@tonic-gate }
5240Sstevel@tonic-gate
5250Sstevel@tonic-gate static int
datadm_parse_threadsafe(char * str,datadm_sp_entry_t * sp_entry)5260Sstevel@tonic-gate datadm_parse_threadsafe(char *str, datadm_sp_entry_t *sp_entry)
5270Sstevel@tonic-gate {
5280Sstevel@tonic-gate int retval = 0;
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate if (strcmp(str, "threadsafe") == 0) {
5310Sstevel@tonic-gate sp_entry->spe_threadsafe = 1;
5320Sstevel@tonic-gate } else if (strcmp(str, "nonthreadsafe") == 0) {
5330Sstevel@tonic-gate sp_entry->spe_threadsafe = 0;
5340Sstevel@tonic-gate } else {
5350Sstevel@tonic-gate retval = -1;
5360Sstevel@tonic-gate }
5370Sstevel@tonic-gate return (retval);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate static int
datadm_parse_default(char * str,datadm_sp_entry_t * sp_entry)5410Sstevel@tonic-gate datadm_parse_default(char *str, datadm_sp_entry_t *sp_entry)
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate int retval = 0;
5440Sstevel@tonic-gate
5450Sstevel@tonic-gate if (strcmp(str, "default") == 0) {
5460Sstevel@tonic-gate sp_entry->spe_default = 1;
5470Sstevel@tonic-gate } else if (strcmp(str, "nondefault") == 0) {
5480Sstevel@tonic-gate sp_entry->spe_default = 0;
5490Sstevel@tonic-gate } else {
5500Sstevel@tonic-gate retval = -1;
5510Sstevel@tonic-gate }
5520Sstevel@tonic-gate return (retval);
5530Sstevel@tonic-gate }
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate static int
datadm_parse_libpath(char * str,datadm_sp_entry_t * sp_entry)5560Sstevel@tonic-gate datadm_parse_libpath(char *str, datadm_sp_entry_t *sp_entry)
5570Sstevel@tonic-gate {
5580Sstevel@tonic-gate return (datadm_parse_nonnull_str(str, &sp_entry->spe_libpath));
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate static int
datadm_parse_sp_version(char * str,datadm_sp_entry_t * sp_entry)5620Sstevel@tonic-gate datadm_parse_sp_version(char *str, datadm_sp_entry_t *sp_entry)
5630Sstevel@tonic-gate {
5640Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_sp_version));
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate
5670Sstevel@tonic-gate static int
datadm_parse_sp_data(char * str,datadm_sp_entry_t * sp_entry)5680Sstevel@tonic-gate datadm_parse_sp_data(char *str, datadm_sp_entry_t *sp_entry)
5690Sstevel@tonic-gate {
5700Sstevel@tonic-gate return (datadm_parse_generic_str(str, &sp_entry->spe_sp_data));
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate static void
datadm_enqueue_entry(datadm_list_t * list,datadm_entry_t * entry)5740Sstevel@tonic-gate datadm_enqueue_entry(datadm_list_t *list, datadm_entry_t *entry)
5750Sstevel@tonic-gate {
5760Sstevel@tonic-gate if (list->dl_head == NULL) {
5770Sstevel@tonic-gate list->dl_head = entry;
5780Sstevel@tonic-gate list->dl_tail = entry;
5790Sstevel@tonic-gate list->dl_count = 1;
5800Sstevel@tonic-gate } else {
5810Sstevel@tonic-gate list->dl_tail->de_next = entry;
5820Sstevel@tonic-gate list->dl_tail = entry;
5830Sstevel@tonic-gate list->dl_count++;
5840Sstevel@tonic-gate }
5850Sstevel@tonic-gate }
5860Sstevel@tonic-gate
5870Sstevel@tonic-gate /*
5880Sstevel@tonic-gate * iterates through the list applying func on each element.
5890Sstevel@tonic-gate * break and return if func returns non-zero.
5900Sstevel@tonic-gate */
5910Sstevel@tonic-gate static int
datadm_walk_list(datadm_list_t * list,int (* func)(datadm_entry_t *,void *),void * arg)5920Sstevel@tonic-gate datadm_walk_list(datadm_list_t *list, int (*func)(datadm_entry_t *, void *),
5930Sstevel@tonic-gate void *arg)
5940Sstevel@tonic-gate {
5950Sstevel@tonic-gate datadm_entry_t *entry;
5960Sstevel@tonic-gate int retval = 0;
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate entry = list->dl_head;
5990Sstevel@tonic-gate while (entry != NULL) {
6000Sstevel@tonic-gate retval = (*func)(entry, arg);
6010Sstevel@tonic-gate if (retval != 0) break;
6020Sstevel@tonic-gate entry = entry->de_next;
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate return (retval);
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate
6070Sstevel@tonic-gate /*
6080Sstevel@tonic-gate * iterates through the list applying free_func to each element.
6090Sstevel@tonic-gate * list becomes empty when the function returns.
6100Sstevel@tonic-gate */
6110Sstevel@tonic-gate static void
datadm_free_list(datadm_list_t * list,void (* free_func)(datadm_entry_t *))6120Sstevel@tonic-gate datadm_free_list(datadm_list_t *list, void (*free_func)(datadm_entry_t *))
6130Sstevel@tonic-gate {
6140Sstevel@tonic-gate while (list->dl_head != NULL) {
6150Sstevel@tonic-gate datadm_entry_t *entry;
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate entry = list->dl_head;
6180Sstevel@tonic-gate list->dl_head = entry->de_next;
6190Sstevel@tonic-gate (*free_func)(entry);
6200Sstevel@tonic-gate }
6210Sstevel@tonic-gate list->dl_count = 0;
6220Sstevel@tonic-gate list->dl_tail = NULL;
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate
6250Sstevel@tonic-gate static datadm_sp_entry_t *
datadm_alloc_sp_entry(void)6260Sstevel@tonic-gate datadm_alloc_sp_entry(void)
6270Sstevel@tonic-gate {
6280Sstevel@tonic-gate datadm_sp_entry_t *sp_entry;
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate sp_entry = (datadm_sp_entry_t *)malloc(sizeof (*sp_entry));
6310Sstevel@tonic-gate if (sp_entry == NULL) {
6320Sstevel@tonic-gate return (NULL);
6330Sstevel@tonic-gate }
6340Sstevel@tonic-gate bzero(sp_entry, sizeof (*sp_entry));
6350Sstevel@tonic-gate return (sp_entry);
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate
6380Sstevel@tonic-gate static void
datadm_free_sp_entry(datadm_sp_entry_t * sp_entry)6390Sstevel@tonic-gate datadm_free_sp_entry(datadm_sp_entry_t *sp_entry)
6400Sstevel@tonic-gate {
6410Sstevel@tonic-gate if (sp_entry->spe_devname != NULL) {
6420Sstevel@tonic-gate free(sp_entry->spe_devname);
6430Sstevel@tonic-gate sp_entry->spe_devname = NULL;
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate if (sp_entry->spe_api_version.dv_name != NULL) {
6460Sstevel@tonic-gate free(sp_entry->spe_api_version.dv_name);
6470Sstevel@tonic-gate sp_entry->spe_api_version.dv_name = NULL;
6480Sstevel@tonic-gate }
6490Sstevel@tonic-gate sp_entry->spe_api_version.dv_major = 0;
6500Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor = 0;
6510Sstevel@tonic-gate sp_entry->spe_threadsafe = 0;
6520Sstevel@tonic-gate sp_entry->spe_default = 0;
6530Sstevel@tonic-gate if (sp_entry->spe_libpath != NULL) {
6540Sstevel@tonic-gate free(sp_entry->spe_libpath);
6550Sstevel@tonic-gate sp_entry->spe_libpath = NULL;
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate if (sp_entry->spe_sp_version.dv_name != NULL) {
6580Sstevel@tonic-gate free(sp_entry->spe_sp_version.dv_name);
6590Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name = NULL;
6600Sstevel@tonic-gate }
6610Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major = 0;
6620Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor = 0;
6630Sstevel@tonic-gate if (sp_entry->spe_sp_data != NULL) {
6640Sstevel@tonic-gate free(sp_entry->spe_sp_data);
6650Sstevel@tonic-gate sp_entry->spe_sp_data = NULL;
6660Sstevel@tonic-gate }
6670Sstevel@tonic-gate free(sp_entry);
6680Sstevel@tonic-gate }
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate static int
datadm_str_match(char * s1,char * s2)6710Sstevel@tonic-gate datadm_str_match(char *s1, char *s2)
6720Sstevel@tonic-gate {
6730Sstevel@tonic-gate if (s1 == NULL || s2 == NULL) {
6740Sstevel@tonic-gate if (s1 != s2) {
6750Sstevel@tonic-gate return (0);
6760Sstevel@tonic-gate }
6770Sstevel@tonic-gate } else {
6780Sstevel@tonic-gate if (strcmp(s1, s2) != 0) {
6790Sstevel@tonic-gate return (0);
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate }
6820Sstevel@tonic-gate return (1);
6830Sstevel@tonic-gate }
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate static int
datadm_version_match(datadm_version_t * v1,datadm_version_t * v2)6860Sstevel@tonic-gate datadm_version_match(datadm_version_t *v1, datadm_version_t *v2)
6870Sstevel@tonic-gate {
6880Sstevel@tonic-gate if (!datadm_str_match(v1->dv_name, v2->dv_name)) {
6890Sstevel@tonic-gate return (0);
6900Sstevel@tonic-gate }
6910Sstevel@tonic-gate if (v1->dv_major != v2->dv_major) {
6920Sstevel@tonic-gate return (0);
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate if (v1->dv_minor != v2->dv_minor) {
6950Sstevel@tonic-gate return (0);
6960Sstevel@tonic-gate }
6970Sstevel@tonic-gate return (1);
6980Sstevel@tonic-gate }
6990Sstevel@tonic-gate
7000Sstevel@tonic-gate static int
datadm_sp_entry_match(datadm_sp_entry_t * sp1,datadm_sp_entry_t * sp2)7010Sstevel@tonic-gate datadm_sp_entry_match(datadm_sp_entry_t *sp1, datadm_sp_entry_t *sp2)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_devname, sp2->spe_devname)) {
7040Sstevel@tonic-gate return (0);
7050Sstevel@tonic-gate }
7060Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_api_version,
7070Sstevel@tonic-gate &sp2->spe_api_version)) {
7080Sstevel@tonic-gate return (0);
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate if (sp1->spe_threadsafe != sp2->spe_threadsafe) {
7110Sstevel@tonic-gate return (0);
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate if (sp2->spe_default != sp2->spe_default) {
7140Sstevel@tonic-gate return (0);
7150Sstevel@tonic-gate }
7160Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_libpath, sp2->spe_libpath)) {
7170Sstevel@tonic-gate return (0);
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_sp_version,
7200Sstevel@tonic-gate &sp2->spe_sp_version)) {
7210Sstevel@tonic-gate return (0);
7220Sstevel@tonic-gate }
7230Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_sp_data, sp2->spe_sp_data)) {
7240Sstevel@tonic-gate return (0);
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate return (1);
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate
7290Sstevel@tonic-gate static datadm_ia_entry_t *
datadm_alloc_ia_entry(void)7300Sstevel@tonic-gate datadm_alloc_ia_entry(void)
7310Sstevel@tonic-gate {
7320Sstevel@tonic-gate datadm_ia_entry_t *ia_entry;
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate ia_entry = (datadm_ia_entry_t *)malloc(sizeof (*ia_entry));
7350Sstevel@tonic-gate if (ia_entry == NULL) {
7360Sstevel@tonic-gate return (NULL);
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate bzero(ia_entry, sizeof (*ia_entry));
7390Sstevel@tonic-gate return (ia_entry);
7400Sstevel@tonic-gate }
7410Sstevel@tonic-gate
7420Sstevel@tonic-gate static void
datadm_free_ia_entry(datadm_ia_entry_t * ia_entry)7430Sstevel@tonic-gate datadm_free_ia_entry(datadm_ia_entry_t *ia_entry)
7440Sstevel@tonic-gate {
7450Sstevel@tonic-gate free(ia_entry);
7460Sstevel@tonic-gate }
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate static datadm_hca_entry_t *
datadm_alloc_hca_entry(void)7490Sstevel@tonic-gate datadm_alloc_hca_entry(void)
7500Sstevel@tonic-gate {
7510Sstevel@tonic-gate datadm_hca_entry_t *hca_entry;
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate hca_entry = (datadm_hca_entry_t *)malloc(sizeof (*hca_entry));
7540Sstevel@tonic-gate if (hca_entry == NULL) {
7550Sstevel@tonic-gate return (NULL);
7560Sstevel@tonic-gate }
7570Sstevel@tonic-gate bzero(hca_entry, sizeof (*hca_entry));
7580Sstevel@tonic-gate return (hca_entry);
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate
7610Sstevel@tonic-gate static void
datadm_free_hca_entry(datadm_hca_entry_t * hca_entry)7620Sstevel@tonic-gate datadm_free_hca_entry(datadm_hca_entry_t *hca_entry)
7630Sstevel@tonic-gate {
7640Sstevel@tonic-gate if (hca_entry->he_name != NULL) {
7650Sstevel@tonic-gate free(hca_entry->he_name);
7660Sstevel@tonic-gate hca_entry->he_name = NULL;
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate datadm_free_list(&hca_entry->he_sp_list,
7690Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_sp_entry);
7700Sstevel@tonic-gate datadm_free_list(&hca_entry->he_ia_list,
7710Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_ia_entry);
7720Sstevel@tonic-gate free(hca_entry);
7730Sstevel@tonic-gate }
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate static int
datadm_hca_entry_match(datadm_hca_entry_t * h1,datadm_hca_entry_t * h2)7760Sstevel@tonic-gate datadm_hca_entry_match(datadm_hca_entry_t *h1, datadm_hca_entry_t *h2)
7770Sstevel@tonic-gate {
7780Sstevel@tonic-gate if (!datadm_str_match(h1->he_name, h2->he_name)) {
7790Sstevel@tonic-gate return (0);
7800Sstevel@tonic-gate }
7810Sstevel@tonic-gate return (1);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate static int
datadm_hca_entry_find(datadm_hca_entry_t * h1,datadm_hca_find_t * hf)7850Sstevel@tonic-gate datadm_hca_entry_find(datadm_hca_entry_t *h1, datadm_hca_find_t *hf)
7860Sstevel@tonic-gate {
7870Sstevel@tonic-gate if (datadm_str_match(h1->he_name, hf->hf_sp_entry->spe_devname)) {
7880Sstevel@tonic-gate hf->hf_hca_entry = h1;
7890Sstevel@tonic-gate return (1);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate return (0);
7920Sstevel@tonic-gate }
7930Sstevel@tonic-gate
7940Sstevel@tonic-gate static int
datadm_ia_entry_find(datadm_ia_entry_t * i1,datadm_ia_find_t * iaf)7950Sstevel@tonic-gate datadm_ia_entry_find(datadm_ia_entry_t *i1, datadm_ia_find_t *iaf)
7960Sstevel@tonic-gate {
797*12163SRamaswamy.Tummala@Sun.COM if (strcmp(i1->iae_name, iaf->if_ia_name) == 0) {
7980Sstevel@tonic-gate iaf->if_ia_entry = i1;
7990Sstevel@tonic-gate return (1);
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate return (0);
8020Sstevel@tonic-gate }
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate static datadm_cmnt_entry_t *
datadm_alloc_cmnt_entry(void)8050Sstevel@tonic-gate datadm_alloc_cmnt_entry(void)
8060Sstevel@tonic-gate {
8070Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry;
8080Sstevel@tonic-gate
8090Sstevel@tonic-gate cmnt_entry = (datadm_cmnt_entry_t *)malloc(sizeof (*cmnt_entry));
8100Sstevel@tonic-gate if (cmnt_entry == NULL) {
8110Sstevel@tonic-gate return (NULL);
8120Sstevel@tonic-gate }
8130Sstevel@tonic-gate bzero(cmnt_entry, sizeof (*cmnt_entry));
8140Sstevel@tonic-gate return (cmnt_entry);
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate
8170Sstevel@tonic-gate static void
datadm_free_cmnt_entry(datadm_cmnt_entry_t * cmnt_entry)8180Sstevel@tonic-gate datadm_free_cmnt_entry(datadm_cmnt_entry_t *cmnt_entry)
8190Sstevel@tonic-gate {
8200Sstevel@tonic-gate if (cmnt_entry->cmnt_line != NULL) {
8210Sstevel@tonic-gate free(cmnt_entry->cmnt_line);
8220Sstevel@tonic-gate cmnt_entry->cmnt_line = NULL;
8230Sstevel@tonic-gate }
8240Sstevel@tonic-gate free(cmnt_entry);
8250Sstevel@tonic-gate }
8260Sstevel@tonic-gate
8270Sstevel@tonic-gate /*
8280Sstevel@tonic-gate * tokenizes a line and strips off the quotes from quoted strings
8290Sstevel@tonic-gate */
8300Sstevel@tonic-gate static int
datadm_parse_line(char * line_buf,char * tokens[],int * token_count)8310Sstevel@tonic-gate datadm_parse_line(char *line_buf, char *tokens[], int *token_count)
8320Sstevel@tonic-gate {
8330Sstevel@tonic-gate int len, i;
8340Sstevel@tonic-gate int count = 0;
8350Sstevel@tonic-gate char *start = NULL;
8360Sstevel@tonic-gate
8370Sstevel@tonic-gate /* the line must not be longer than DATADM_LINESZ */
8380Sstevel@tonic-gate len = strlen(line_buf);
8390Sstevel@tonic-gate if (line_buf[len - 1] != '\n') {
8400Sstevel@tonic-gate return (-1);
8410Sstevel@tonic-gate }
8420Sstevel@tonic-gate /* discard blank lines and comments */
8430Sstevel@tonic-gate if (len == 1) {
8440Sstevel@tonic-gate *token_count = 0;
8450Sstevel@tonic-gate return (0);
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate if (len >= 2 && line_buf[0] == '#') {
8480Sstevel@tonic-gate *token_count = 0;
8490Sstevel@tonic-gate return (0);
8500Sstevel@tonic-gate }
8510Sstevel@tonic-gate /* removes the new line */
8520Sstevel@tonic-gate line_buf[len - 1] = '\0';
8530Sstevel@tonic-gate len--;
8540Sstevel@tonic-gate
8550Sstevel@tonic-gate for (i = 0; i < len; i++) {
8560Sstevel@tonic-gate if (start != NULL) {
8570Sstevel@tonic-gate /*
8580Sstevel@tonic-gate * start points to the start of
8590Sstevel@tonic-gate * a new token. if start is '"',
8600Sstevel@tonic-gate * we should expect a quoted
8610Sstevel@tonic-gate * string.
8620Sstevel@tonic-gate */
8630Sstevel@tonic-gate if (*start == '\"') {
8640Sstevel@tonic-gate /*
8650Sstevel@tonic-gate * keep scanning until we
8660Sstevel@tonic-gate * hit the end quote.
8670Sstevel@tonic-gate */
8680Sstevel@tonic-gate if (line_buf[i] != '\"') {
8690Sstevel@tonic-gate continue;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate /*
8720Sstevel@tonic-gate * skip past the start quote
8730Sstevel@tonic-gate */
8740Sstevel@tonic-gate start++;
8750Sstevel@tonic-gate } else {
8760Sstevel@tonic-gate /*
8770Sstevel@tonic-gate * our token is not a quoted
8780Sstevel@tonic-gate * string. our token ends only
8790Sstevel@tonic-gate * when we hit a whitespace.
8800Sstevel@tonic-gate */
8810Sstevel@tonic-gate if (!isspace(line_buf[i])) {
8820Sstevel@tonic-gate continue;
8830Sstevel@tonic-gate }
8840Sstevel@tonic-gate }
8850Sstevel@tonic-gate /*
8860Sstevel@tonic-gate * nullify the end quote (if any)
8870Sstevel@tonic-gate * and update the tokens array.
8880Sstevel@tonic-gate */
8890Sstevel@tonic-gate line_buf[i] = '\0';
8900Sstevel@tonic-gate tokens[count] = start;
8910Sstevel@tonic-gate start = NULL;
8920Sstevel@tonic-gate count++;
8930Sstevel@tonic-gate } else {
8940Sstevel@tonic-gate /*
8950Sstevel@tonic-gate * skip whitespaces
8960Sstevel@tonic-gate */
8970Sstevel@tonic-gate if (isspace(line_buf[i])) {
8980Sstevel@tonic-gate continue;
8990Sstevel@tonic-gate } else {
9000Sstevel@tonic-gate start = &line_buf[i];
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate if (count == DATADM_MAX_TOKENS) {
9040Sstevel@tonic-gate start = NULL;
9050Sstevel@tonic-gate break;
9060Sstevel@tonic-gate }
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate if (start != NULL) {
9090Sstevel@tonic-gate tokens[count] = start;
9100Sstevel@tonic-gate start = NULL;
9110Sstevel@tonic-gate count++;
9120Sstevel@tonic-gate }
9130Sstevel@tonic-gate *token_count = count;
9140Sstevel@tonic-gate return (0);
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate
9170Sstevel@tonic-gate /*
9180Sstevel@tonic-gate * attempts to save sp_entry into hca_list.
9190Sstevel@tonic-gate * becomes no-op if sp entry already exists.
9200Sstevel@tonic-gate * new hca entries and ia entries are created as needed.
9210Sstevel@tonic-gate */
9220Sstevel@tonic-gate static int
datadm_process_sp_entry(datadm_list_t * hca_list,datadm_sp_entry_t * sp_entry,char * ia_name)9230Sstevel@tonic-gate datadm_process_sp_entry(datadm_list_t *hca_list, datadm_sp_entry_t *sp_entry,
924*12163SRamaswamy.Tummala@Sun.COM char *ia_name)
9250Sstevel@tonic-gate {
9260Sstevel@tonic-gate datadm_hca_find_t hca_find;
9270Sstevel@tonic-gate datadm_ia_find_t ia_find;
9280Sstevel@tonic-gate datadm_hca_entry_t *hca_entry;
9290Sstevel@tonic-gate
9300Sstevel@tonic-gate hca_find.hf_sp_entry = sp_entry;
9310Sstevel@tonic-gate hca_find.hf_hca_entry = NULL;
9320Sstevel@tonic-gate (void) datadm_walk_list(hca_list, (int (*)(datadm_entry_t *, void *))
9330Sstevel@tonic-gate datadm_hca_entry_find, (void *)&hca_find);
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate if (hca_find.hf_hca_entry == NULL) {
9360Sstevel@tonic-gate int dlen;
9370Sstevel@tonic-gate
9380Sstevel@tonic-gate /*
9390Sstevel@tonic-gate * hca_entry not found, need to create
9400Sstevel@tonic-gate * and insert one.
9410Sstevel@tonic-gate */
9420Sstevel@tonic-gate hca_entry = datadm_alloc_hca_entry();
9430Sstevel@tonic-gate if (hca_entry == NULL) {
9440Sstevel@tonic-gate return (-1);
9450Sstevel@tonic-gate }
9460Sstevel@tonic-gate dlen = strlen(sp_entry->spe_devname);
9470Sstevel@tonic-gate hca_entry->he_name = (char *)malloc(dlen + 1);
9480Sstevel@tonic-gate if (hca_entry->he_name == NULL) {
9490Sstevel@tonic-gate datadm_free_hca_entry(hca_entry);
9500Sstevel@tonic-gate return (-1);
9510Sstevel@tonic-gate }
9520Sstevel@tonic-gate (void) strcpy(hca_entry->he_name, sp_entry->spe_devname);
9530Sstevel@tonic-gate datadm_enqueue_entry(hca_list, (datadm_entry_t *)hca_entry);
9540Sstevel@tonic-gate } else {
9550Sstevel@tonic-gate hca_entry = hca_find.hf_hca_entry;
9560Sstevel@tonic-gate }
957*12163SRamaswamy.Tummala@Sun.COM if (ia_name == NULL) {
9580Sstevel@tonic-gate goto put_sp_entry;
9590Sstevel@tonic-gate }
960*12163SRamaswamy.Tummala@Sun.COM ia_find.if_ia_name = ia_name;
9610Sstevel@tonic-gate ia_find.if_ia_entry = NULL;
9620Sstevel@tonic-gate (void) datadm_walk_list(&hca_entry->he_ia_list,
9630Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_ia_entry_find, &ia_find);
9640Sstevel@tonic-gate
9650Sstevel@tonic-gate if (ia_find.if_ia_entry == NULL) {
9660Sstevel@tonic-gate datadm_ia_entry_t *ia_entry;
9670Sstevel@tonic-gate
9680Sstevel@tonic-gate /*
9690Sstevel@tonic-gate * ia_entry not found, need to create
9700Sstevel@tonic-gate * and insert one.
9710Sstevel@tonic-gate */
9720Sstevel@tonic-gate ia_entry = datadm_alloc_ia_entry();
9730Sstevel@tonic-gate if (ia_entry == NULL) {
9740Sstevel@tonic-gate return (-1);
9750Sstevel@tonic-gate }
976*12163SRamaswamy.Tummala@Sun.COM (void) strlcpy(ia_entry->iae_name, ia_name, MAXLINKNAMELEN);
9770Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_ia_list,
9780Sstevel@tonic-gate (datadm_entry_t *)ia_entry);
9790Sstevel@tonic-gate }
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate put_sp_entry:;
9820Sstevel@tonic-gate
9830Sstevel@tonic-gate if (datadm_walk_list(&hca_entry->he_sp_list,
9840Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_sp_entry_match,
9850Sstevel@tonic-gate (void *)sp_entry)) {
9860Sstevel@tonic-gate return (1);
9870Sstevel@tonic-gate } else {
9880Sstevel@tonic-gate /*
9890Sstevel@tonic-gate * only insert sp_entry if it is not found.
9900Sstevel@tonic-gate */
9910Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_sp_list,
9920Sstevel@tonic-gate (datadm_entry_t *)sp_entry);
9930Sstevel@tonic-gate }
9940Sstevel@tonic-gate return (0);
9950Sstevel@tonic-gate }
9960Sstevel@tonic-gate
9970Sstevel@tonic-gate /*
9980Sstevel@tonic-gate * parses service_provider.conf
9990Sstevel@tonic-gate */
10000Sstevel@tonic-gate static int
datadm_parse_sp_conf(datadm_list_t * hca_list)10010Sstevel@tonic-gate datadm_parse_sp_conf(datadm_list_t *hca_list)
10020Sstevel@tonic-gate {
10030Sstevel@tonic-gate datadm_sp_entry_t *sp_entry;
10040Sstevel@tonic-gate FILE *sp_file;
10050Sstevel@tonic-gate char *sp_conf = datadm_args.da_sp_conf;
10060Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS];
10070Sstevel@tonic-gate char line_buf[DATADM_LINESZ];
10080Sstevel@tonic-gate int retval = 0;
10090Sstevel@tonic-gate int token_count = 0;
10100Sstevel@tonic-gate int line_count = 0;
10110Sstevel@tonic-gate
10120Sstevel@tonic-gate sp_file = fopen(sp_conf, "r");
10130Sstevel@tonic-gate if (sp_file == NULL) {
10140Sstevel@tonic-gate (void) fprintf(stderr,
10150Sstevel@tonic-gate gettext("datadm: cannot open %s\n"), sp_conf);
10160Sstevel@tonic-gate return (-1);
10170Sstevel@tonic-gate }
10180Sstevel@tonic-gate
10190Sstevel@tonic-gate for (;;) {
10200Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ);
10210Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, sp_file) == NULL) {
10220Sstevel@tonic-gate break;
10230Sstevel@tonic-gate }
10240Sstevel@tonic-gate token_count = 0;
10250Sstevel@tonic-gate line_count++;
10260Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count);
10270Sstevel@tonic-gate if (retval != 0) {
10280Sstevel@tonic-gate (void) fprintf(stderr, gettext(
10290Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"),
10300Sstevel@tonic-gate sp_conf, line_count, DATADM_LINESZ);
10310Sstevel@tonic-gate break;
10320Sstevel@tonic-gate }
10330Sstevel@tonic-gate if (token_count == 0) continue;
10340Sstevel@tonic-gate if (token_count == DATADM_NUM_SP_TOKENS) {
10350Sstevel@tonic-gate int i = 0;
10360Sstevel@tonic-gate
10370Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry();
10380Sstevel@tonic-gate if (sp_entry == NULL) {
10390Sstevel@tonic-gate retval = -1;
10400Sstevel@tonic-gate break;
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate
10430Sstevel@tonic-gate /*
10440Sstevel@tonic-gate * sp_entry gets filled incrementally by
10450Sstevel@tonic-gate * each parsing function
10460Sstevel@tonic-gate */
10470Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_SP_TOKENS &&
10480Sstevel@tonic-gate retval == 0; i++) {
10490Sstevel@tonic-gate retval = (*datadm_sp_parse_funcs[i])
10500Sstevel@tonic-gate (tokens[i], (void *)sp_entry);
10510Sstevel@tonic-gate }
10520Sstevel@tonic-gate if (retval != 0) {
10530Sstevel@tonic-gate (void) fprintf(stderr, gettext(
10540Sstevel@tonic-gate "datadm: parse error: %s, "
10550Sstevel@tonic-gate "line %d, token: %s\n"),
10560Sstevel@tonic-gate sp_conf, line_count, tokens[i - 1]);
10570Sstevel@tonic-gate datadm_free_sp_entry(sp_entry);
10580Sstevel@tonic-gate sp_entry = NULL;
10590Sstevel@tonic-gate break;
10600Sstevel@tonic-gate }
10610Sstevel@tonic-gate
10620Sstevel@tonic-gate retval = datadm_process_sp_entry(hca_list,
1063*12163SRamaswamy.Tummala@Sun.COM sp_entry, NULL);
10640Sstevel@tonic-gate if (retval != 0) {
10650Sstevel@tonic-gate datadm_free_sp_entry(sp_entry);
10660Sstevel@tonic-gate if (retval == 1) {
10670Sstevel@tonic-gate retval = 0;
10680Sstevel@tonic-gate } else {
10690Sstevel@tonic-gate break;
10700Sstevel@tonic-gate }
10710Sstevel@tonic-gate }
10720Sstevel@tonic-gate } else {
10730Sstevel@tonic-gate (void) fprintf(stderr, gettext(
10740Sstevel@tonic-gate "datadm: parse error: %s, line %d, "
10750Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), sp_conf,
10760Sstevel@tonic-gate line_count, token_count, DATADM_NUM_SP_TOKENS);
10770Sstevel@tonic-gate retval = -1;
10780Sstevel@tonic-gate break;
10790Sstevel@tonic-gate }
10800Sstevel@tonic-gate }
10810Sstevel@tonic-gate if (retval != 0) {
10820Sstevel@tonic-gate datadm_free_list(hca_list,
10830Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
10840Sstevel@tonic-gate }
10850Sstevel@tonic-gate (void) fclose(sp_file);
10860Sstevel@tonic-gate return (retval);
10870Sstevel@tonic-gate }
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate /*
10900Sstevel@tonic-gate * parses dat.conf
10910Sstevel@tonic-gate */
10920Sstevel@tonic-gate static int
datadm_parse_dat_conf(datadm_list_t * hca_list)10930Sstevel@tonic-gate datadm_parse_dat_conf(datadm_list_t *hca_list)
10940Sstevel@tonic-gate {
10950Sstevel@tonic-gate boolean_t save_header = B_TRUE;
10960Sstevel@tonic-gate datadm_sp_entry_t *sp_entry;
10970Sstevel@tonic-gate FILE *dat_file;
10980Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf;
10990Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS];
11000Sstevel@tonic-gate char line_buf[DATADM_LINESZ];
11010Sstevel@tonic-gate int retval = 0;
11020Sstevel@tonic-gate int token_count = 0;
11030Sstevel@tonic-gate int line_count = 0;
11040Sstevel@tonic-gate
11050Sstevel@tonic-gate dat_file = fopen(dat_conf, "r");
11060Sstevel@tonic-gate if (dat_file == NULL) {
11070Sstevel@tonic-gate /* dat.conf not existing is not an error for OP_ADD */
11080Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_ADD) {
11090Sstevel@tonic-gate return (0);
11100Sstevel@tonic-gate }
11110Sstevel@tonic-gate (void) fprintf(stderr, gettext("datadm: cannot open %s\n"),
11120Sstevel@tonic-gate dat_conf);
11130Sstevel@tonic-gate return (-1);
11140Sstevel@tonic-gate }
11150Sstevel@tonic-gate
11160Sstevel@tonic-gate for (;;) {
11170Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ);
11180Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, dat_file) == NULL) {
11190Sstevel@tonic-gate break;
11200Sstevel@tonic-gate }
11210Sstevel@tonic-gate token_count = 0;
11220Sstevel@tonic-gate line_count++;
11230Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count);
11240Sstevel@tonic-gate if (retval != 0) {
11250Sstevel@tonic-gate (void) fprintf(stderr, gettext(
11260Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"),
11270Sstevel@tonic-gate dat_conf, line_count, DATADM_LINESZ);
11280Sstevel@tonic-gate break;
11290Sstevel@tonic-gate }
11300Sstevel@tonic-gate if (token_count == 0) {
11310Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry;
11320Sstevel@tonic-gate int cmnt_len;
11330Sstevel@tonic-gate
11340Sstevel@tonic-gate /*
11350Sstevel@tonic-gate * comments are saved only if they are
11360Sstevel@tonic-gate * at the top of dat.conf.
11370Sstevel@tonic-gate */
11380Sstevel@tonic-gate if (!save_header) continue;
11390Sstevel@tonic-gate cmnt_entry = datadm_alloc_cmnt_entry();
11400Sstevel@tonic-gate if (cmnt_entry == NULL) {
11410Sstevel@tonic-gate perror("datadm: malloc");
11420Sstevel@tonic-gate retval = -1;
11430Sstevel@tonic-gate break;
11440Sstevel@tonic-gate }
11450Sstevel@tonic-gate cmnt_len = strlen(line_buf);
11460Sstevel@tonic-gate cmnt_entry->cmnt_line = (char *)malloc(cmnt_len + 1);
11470Sstevel@tonic-gate if (cmnt_entry->cmnt_line == NULL) {
11480Sstevel@tonic-gate perror("datadm: malloc");
11490Sstevel@tonic-gate datadm_free_cmnt_entry(cmnt_entry);
11500Sstevel@tonic-gate retval = -1;
11510Sstevel@tonic-gate break;
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate (void) strncpy(cmnt_entry->cmnt_line,
11540Sstevel@tonic-gate line_buf, cmnt_len);
11550Sstevel@tonic-gate cmnt_entry->cmnt_line[cmnt_len] = '\0';
11560Sstevel@tonic-gate datadm_enqueue_entry(&datadm_conf_header,
11570Sstevel@tonic-gate (datadm_entry_t *)cmnt_entry);
11580Sstevel@tonic-gate continue;
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate if (token_count == DATADM_NUM_DAT_TOKENS) {
11610Sstevel@tonic-gate int i = 0;
1162*12163SRamaswamy.Tummala@Sun.COM char ia_name[MAXLINKNAMELEN];
11630Sstevel@tonic-gate
11640Sstevel@tonic-gate /*
11650Sstevel@tonic-gate * we stop saving comment lines once
11660Sstevel@tonic-gate * we see the first valid line.
11670Sstevel@tonic-gate */
11680Sstevel@tonic-gate save_header = B_FALSE;
11690Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry();
11700Sstevel@tonic-gate if (sp_entry == NULL) {
11710Sstevel@tonic-gate retval = -1;
11720Sstevel@tonic-gate break;
11730Sstevel@tonic-gate }
11740Sstevel@tonic-gate
11750Sstevel@tonic-gate /*
11760Sstevel@tonic-gate * sp_entry gets filled incrementally by
11770Sstevel@tonic-gate * each parsing function
11780Sstevel@tonic-gate */
11790Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_DAT_TOKENS &&
11800Sstevel@tonic-gate retval == 0; i++) {
11810Sstevel@tonic-gate void *arg;
11820Sstevel@tonic-gate
11830Sstevel@tonic-gate if (i == 0) {
11840Sstevel@tonic-gate /*
11850Sstevel@tonic-gate * the first token (ia name)
11860Sstevel@tonic-gate * does not belong to an
11870Sstevel@tonic-gate * sp_entry
11880Sstevel@tonic-gate */
1189*12163SRamaswamy.Tummala@Sun.COM arg = (void *)ia_name;
11900Sstevel@tonic-gate } else {
11910Sstevel@tonic-gate arg = (void *)sp_entry;
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate retval = (*datadm_dat_parse_funcs[i])
11940Sstevel@tonic-gate (tokens[i], arg);
11950Sstevel@tonic-gate }
11960Sstevel@tonic-gate if (retval != 0) {
11970Sstevel@tonic-gate (void) fprintf(stderr, gettext(
11980Sstevel@tonic-gate "datadm: parse error: %s, "
11990Sstevel@tonic-gate "line %d, token: %s\n"), dat_conf,
12000Sstevel@tonic-gate line_count, tokens[i - 1]);
12010Sstevel@tonic-gate datadm_free_sp_entry(sp_entry);
12020Sstevel@tonic-gate sp_entry = NULL;
12030Sstevel@tonic-gate break;
12040Sstevel@tonic-gate }
12050Sstevel@tonic-gate
12060Sstevel@tonic-gate /*
12070Sstevel@tonic-gate * we ignore the ibds in dat.conf if we are
12080Sstevel@tonic-gate * doing update
12090Sstevel@tonic-gate */
12100Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_UPDATE) {
1211*12163SRamaswamy.Tummala@Sun.COM retval = datadm_process_sp_entry(hca_list,
1212*12163SRamaswamy.Tummala@Sun.COM sp_entry, NULL);
1213*12163SRamaswamy.Tummala@Sun.COM } else {
1214*12163SRamaswamy.Tummala@Sun.COM retval = datadm_process_sp_entry(hca_list,
1215*12163SRamaswamy.Tummala@Sun.COM sp_entry, ia_name);
12160Sstevel@tonic-gate }
12170Sstevel@tonic-gate if (retval != 0) {
12180Sstevel@tonic-gate datadm_free_sp_entry(sp_entry);
12190Sstevel@tonic-gate if (retval == 1) {
12200Sstevel@tonic-gate retval = 0;
12210Sstevel@tonic-gate } else {
12220Sstevel@tonic-gate break;
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate }
12250Sstevel@tonic-gate } else {
12260Sstevel@tonic-gate (void) fprintf(stderr, gettext(
12270Sstevel@tonic-gate "datadm: parse error: %s, line %d, "
12280Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), dat_conf,
12290Sstevel@tonic-gate line_count, token_count, DATADM_NUM_DAT_TOKENS);
12300Sstevel@tonic-gate retval = -1;
12310Sstevel@tonic-gate break;
12320Sstevel@tonic-gate }
12330Sstevel@tonic-gate }
12340Sstevel@tonic-gate if (retval != 0) {
12350Sstevel@tonic-gate datadm_free_list(&datadm_conf_header,
12360Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry);
12370Sstevel@tonic-gate datadm_free_list(hca_list,
12380Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
12390Sstevel@tonic-gate }
12400Sstevel@tonic-gate (void) fclose(dat_file);
12410Sstevel@tonic-gate return (retval);
12420Sstevel@tonic-gate }
12430Sstevel@tonic-gate
12440Sstevel@tonic-gate /*
12450Sstevel@tonic-gate * used by OP_REMOVE to invalidate common sp entries between hl1 and hl2.
12460Sstevel@tonic-gate * invalid sp entries will be ignored by datadm_generate_dat_conf.
12470Sstevel@tonic-gate */
12480Sstevel@tonic-gate static void
datadm_invalidate_common_sp_entries(datadm_list_t * hl1,datadm_list_t * hl2)12490Sstevel@tonic-gate datadm_invalidate_common_sp_entries(datadm_list_t *hl1, datadm_list_t *hl2)
12500Sstevel@tonic-gate {
12510Sstevel@tonic-gate datadm_entry_t *he1, *he2;
12520Sstevel@tonic-gate
12530Sstevel@tonic-gate he1 = hl1->dl_head;
12540Sstevel@tonic-gate while (he1 != NULL) {
12550Sstevel@tonic-gate he2 = hl2->dl_head;
12560Sstevel@tonic-gate while (he2 != NULL) {
12570Sstevel@tonic-gate datadm_entry_t *se1, *se2;
12580Sstevel@tonic-gate
12590Sstevel@tonic-gate if (!datadm_hca_entry_match(
12600Sstevel@tonic-gate (datadm_hca_entry_t *)he1,
12610Sstevel@tonic-gate (datadm_hca_entry_t *)he2)) {
12620Sstevel@tonic-gate he2 = he2->de_next;
12630Sstevel@tonic-gate continue;
12640Sstevel@tonic-gate }
12650Sstevel@tonic-gate se1 = ((datadm_hca_entry_t *)he1)->he_sp_list.dl_head;
12660Sstevel@tonic-gate while (se1 != NULL) {
12670Sstevel@tonic-gate se2 = ((datadm_hca_entry_t *)he2)->
12680Sstevel@tonic-gate he_sp_list.dl_head;
12690Sstevel@tonic-gate while (se2 != NULL) {
12700Sstevel@tonic-gate if (!datadm_sp_entry_match(
12710Sstevel@tonic-gate (datadm_sp_entry_t *)se1,
12720Sstevel@tonic-gate (datadm_sp_entry_t *)se2)) {
12730Sstevel@tonic-gate se2 = se2->de_next;
12740Sstevel@tonic-gate continue;
12750Sstevel@tonic-gate }
12760Sstevel@tonic-gate ((datadm_sp_entry_t *)se1)->
12770Sstevel@tonic-gate spe_invalid = 1;
12780Sstevel@tonic-gate break;
12790Sstevel@tonic-gate }
12800Sstevel@tonic-gate se1 = se1->de_next;
12810Sstevel@tonic-gate }
12820Sstevel@tonic-gate break;
12830Sstevel@tonic-gate }
12840Sstevel@tonic-gate he1 = he1->de_next;
12850Sstevel@tonic-gate }
12860Sstevel@tonic-gate }
12870Sstevel@tonic-gate
1288*12163SRamaswamy.Tummala@Sun.COM static int
datadm_hca_entry_find_by_name(datadm_hca_entry_t * h1,datadm_hca_find_by_name_t * hf)1289*12163SRamaswamy.Tummala@Sun.COM datadm_hca_entry_find_by_name(datadm_hca_entry_t *h1,
1290*12163SRamaswamy.Tummala@Sun.COM datadm_hca_find_by_name_t *hf)
1291*12163SRamaswamy.Tummala@Sun.COM {
1292*12163SRamaswamy.Tummala@Sun.COM if (datadm_str_match(h1->he_name, hf->hf_name)) {
1293*12163SRamaswamy.Tummala@Sun.COM hf->hf_hca_entry = h1;
1294*12163SRamaswamy.Tummala@Sun.COM return (1);
1295*12163SRamaswamy.Tummala@Sun.COM }
1296*12163SRamaswamy.Tummala@Sun.COM return (0);
1297*12163SRamaswamy.Tummala@Sun.COM }
1298*12163SRamaswamy.Tummala@Sun.COM
1299*12163SRamaswamy.Tummala@Sun.COM datadm_hca_entry_t *
datadm_hca_lookup_by_name(datadm_list_t * hca_list,char * hca_driver_name)1300*12163SRamaswamy.Tummala@Sun.COM datadm_hca_lookup_by_name(datadm_list_t *hca_list, char *hca_driver_name)
1301*12163SRamaswamy.Tummala@Sun.COM {
1302*12163SRamaswamy.Tummala@Sun.COM datadm_hca_find_by_name_t hf;
1303*12163SRamaswamy.Tummala@Sun.COM
1304*12163SRamaswamy.Tummala@Sun.COM hf.hf_name = hca_driver_name;
1305*12163SRamaswamy.Tummala@Sun.COM hf.hf_hca_entry = NULL;
1306*12163SRamaswamy.Tummala@Sun.COM (void) datadm_walk_list(hca_list,
1307*12163SRamaswamy.Tummala@Sun.COM (int (*)(datadm_entry_t *, void *))datadm_hca_entry_find_by_name,
1308*12163SRamaswamy.Tummala@Sun.COM &hf);
1309*12163SRamaswamy.Tummala@Sun.COM return (hf.hf_hca_entry);
1310*12163SRamaswamy.Tummala@Sun.COM }
1311*12163SRamaswamy.Tummala@Sun.COM
1312*12163SRamaswamy.Tummala@Sun.COM static boolean_t
datadm_add_plink(char * linkname,datadm_fill_ia_list_t * ia_args)1313*12163SRamaswamy.Tummala@Sun.COM datadm_add_plink(char *linkname, datadm_fill_ia_list_t *ia_args)
1314*12163SRamaswamy.Tummala@Sun.COM {
1315*12163SRamaswamy.Tummala@Sun.COM datalink_class_t class;
1316*12163SRamaswamy.Tummala@Sun.COM datalink_id_t linkid;
1317*12163SRamaswamy.Tummala@Sun.COM dladm_ib_attr_t ib_attr;
1318*12163SRamaswamy.Tummala@Sun.COM ibnex_ctl_query_hca_t query_hca;
1319*12163SRamaswamy.Tummala@Sun.COM datadm_hca_entry_t *hca;
1320*12163SRamaswamy.Tummala@Sun.COM struct lifreq req;
1321*12163SRamaswamy.Tummala@Sun.COM datadm_ia_find_t ia_find;
1322*12163SRamaswamy.Tummala@Sun.COM datadm_ia_entry_t *ia_entry;
1323*12163SRamaswamy.Tummala@Sun.COM
1324*12163SRamaswamy.Tummala@Sun.COM if ((dladm_name2info(ia_args->ia_dlh, linkname, &linkid, NULL, &class,
1325*12163SRamaswamy.Tummala@Sun.COM NULL) != DLADM_STATUS_OK) ||
1326*12163SRamaswamy.Tummala@Sun.COM (class != DATALINK_CLASS_PART) ||
1327*12163SRamaswamy.Tummala@Sun.COM (dladm_part_info(ia_args->ia_dlh, linkid, &ib_attr,
1328*12163SRamaswamy.Tummala@Sun.COM DLADM_OPT_ACTIVE) != DLADM_STATUS_OK)) {
1329*12163SRamaswamy.Tummala@Sun.COM return (B_FALSE);
1330*12163SRamaswamy.Tummala@Sun.COM }
1331*12163SRamaswamy.Tummala@Sun.COM
1332*12163SRamaswamy.Tummala@Sun.COM (void) strlcpy(req.lifr_name, linkname, sizeof (req.lifr_name));
1333*12163SRamaswamy.Tummala@Sun.COM /*
1334*12163SRamaswamy.Tummala@Sun.COM * we don't really need to know the ip address.
1335*12163SRamaswamy.Tummala@Sun.COM * we just want to check if the device is plumbed
1336*12163SRamaswamy.Tummala@Sun.COM * or not.
1337*12163SRamaswamy.Tummala@Sun.COM */
1338*12163SRamaswamy.Tummala@Sun.COM if (ioctl(ia_args->ia_sock_fd_v4, SIOCGLIFADDR, (caddr_t)&req) != 0) {
1339*12163SRamaswamy.Tummala@Sun.COM /*
1340*12163SRamaswamy.Tummala@Sun.COM * we try v6 if the v4 address isn't found.
1341*12163SRamaswamy.Tummala@Sun.COM */
1342*12163SRamaswamy.Tummala@Sun.COM if (ioctl(ia_args->ia_sock_fd_v6, SIOCGLIFADDR,
1343*12163SRamaswamy.Tummala@Sun.COM (caddr_t)&req) != 0)
1344*12163SRamaswamy.Tummala@Sun.COM return (B_FALSE);
1345*12163SRamaswamy.Tummala@Sun.COM }
1346*12163SRamaswamy.Tummala@Sun.COM
1347*12163SRamaswamy.Tummala@Sun.COM bzero(&query_hca, sizeof (query_hca));
1348*12163SRamaswamy.Tummala@Sun.COM query_hca.hca_guid = ib_attr.dia_hca_guid;
1349*12163SRamaswamy.Tummala@Sun.COM if (ioctl(ia_args->ia_ibnex_fd, IBNEX_CTL_QUERY_HCA, &query_hca) == -1)
1350*12163SRamaswamy.Tummala@Sun.COM return (B_FALSE);
1351*12163SRamaswamy.Tummala@Sun.COM
1352*12163SRamaswamy.Tummala@Sun.COM if ((hca = datadm_hca_lookup_by_name(ia_args->ia_hca_list,
1353*12163SRamaswamy.Tummala@Sun.COM query_hca.hca_info.hca_driver_name)) == NULL)
1354*12163SRamaswamy.Tummala@Sun.COM return (B_FALSE);
1355*12163SRamaswamy.Tummala@Sun.COM
1356*12163SRamaswamy.Tummala@Sun.COM ia_find.if_ia_name = linkname;
1357*12163SRamaswamy.Tummala@Sun.COM ia_find.if_ia_entry = NULL;
1358*12163SRamaswamy.Tummala@Sun.COM (void) datadm_walk_list(&hca->he_ia_list,
1359*12163SRamaswamy.Tummala@Sun.COM (int (*)(datadm_entry_t *, void *))
1360*12163SRamaswamy.Tummala@Sun.COM datadm_ia_entry_find, &ia_find);
1361*12163SRamaswamy.Tummala@Sun.COM
1362*12163SRamaswamy.Tummala@Sun.COM if (ia_find.if_ia_entry == NULL) {
1363*12163SRamaswamy.Tummala@Sun.COM /*
1364*12163SRamaswamy.Tummala@Sun.COM * we insert an ia entry only if
1365*12163SRamaswamy.Tummala@Sun.COM * it is unique.
1366*12163SRamaswamy.Tummala@Sun.COM */
1367*12163SRamaswamy.Tummala@Sun.COM ia_entry = datadm_alloc_ia_entry();
1368*12163SRamaswamy.Tummala@Sun.COM if (ia_entry != NULL) {
1369*12163SRamaswamy.Tummala@Sun.COM (void) strlcpy(ia_entry->iae_name, linkname,
1370*12163SRamaswamy.Tummala@Sun.COM MAXLINKNAMELEN);
1371*12163SRamaswamy.Tummala@Sun.COM datadm_enqueue_entry(&hca->he_ia_list,
1372*12163SRamaswamy.Tummala@Sun.COM (datadm_entry_t *)ia_entry);
1373*12163SRamaswamy.Tummala@Sun.COM }
1374*12163SRamaswamy.Tummala@Sun.COM }
1375*12163SRamaswamy.Tummala@Sun.COM
1376*12163SRamaswamy.Tummala@Sun.COM return (B_FALSE);
1377*12163SRamaswamy.Tummala@Sun.COM }
1378*12163SRamaswamy.Tummala@Sun.COM
13790Sstevel@tonic-gate /*
1380*12163SRamaswamy.Tummala@Sun.COM * build ia lists for each hca_list element
13810Sstevel@tonic-gate */
13820Sstevel@tonic-gate static int
datadm_build_ia_lists(datadm_list_t * hca_list)13830Sstevel@tonic-gate datadm_build_ia_lists(datadm_list_t *hca_list)
13840Sstevel@tonic-gate {
1385*12163SRamaswamy.Tummala@Sun.COM dladm_handle_t dlh;
13860Sstevel@tonic-gate datadm_fill_ia_list_t ia_args;
1387*12163SRamaswamy.Tummala@Sun.COM int rv = -1;
1388*12163SRamaswamy.Tummala@Sun.COM int fd = -1;
1389*12163SRamaswamy.Tummala@Sun.COM int sv4 = -1;
1390*12163SRamaswamy.Tummala@Sun.COM int sv6 = -1;
13910Sstevel@tonic-gate
1392*12163SRamaswamy.Tummala@Sun.COM if (dladm_open(&dlh) != DLADM_STATUS_OK)
13930Sstevel@tonic-gate return (-1);
1394*12163SRamaswamy.Tummala@Sun.COM
1395*12163SRamaswamy.Tummala@Sun.COM if ((fd = open(IBNEX_DEVCTL_DEV, O_RDONLY)) < 0)
1396*12163SRamaswamy.Tummala@Sun.COM goto out;
1397*12163SRamaswamy.Tummala@Sun.COM
1398*12163SRamaswamy.Tummala@Sun.COM if ((sv4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1399*12163SRamaswamy.Tummala@Sun.COM perror("datadm: socket");
1400*12163SRamaswamy.Tummala@Sun.COM goto out;
14010Sstevel@tonic-gate }
1402*12163SRamaswamy.Tummala@Sun.COM
1403*12163SRamaswamy.Tummala@Sun.COM if ((sv6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
14040Sstevel@tonic-gate perror("datadm: socket");
1405*12163SRamaswamy.Tummala@Sun.COM goto out;
14060Sstevel@tonic-gate }
1407*12163SRamaswamy.Tummala@Sun.COM
1408*12163SRamaswamy.Tummala@Sun.COM ia_args.ia_hca_list = hca_list;
1409*12163SRamaswamy.Tummala@Sun.COM ia_args.ia_dlh = dlh;
1410*12163SRamaswamy.Tummala@Sun.COM ia_args.ia_ibnex_fd = fd;
14110Sstevel@tonic-gate ia_args.ia_sock_fd_v4 = sv4;
14120Sstevel@tonic-gate ia_args.ia_sock_fd_v6 = sv6;
14130Sstevel@tonic-gate
1414*12163SRamaswamy.Tummala@Sun.COM dlpi_walk((boolean_t (*) (const char *, void *))datadm_add_plink,
1415*12163SRamaswamy.Tummala@Sun.COM &ia_args, 0);
1416*12163SRamaswamy.Tummala@Sun.COM rv = 0;
14170Sstevel@tonic-gate
1418*12163SRamaswamy.Tummala@Sun.COM out:
1419*12163SRamaswamy.Tummala@Sun.COM if (sv4 != -1)
1420*12163SRamaswamy.Tummala@Sun.COM (void) close(sv4);
1421*12163SRamaswamy.Tummala@Sun.COM if (sv6 != -1)
1422*12163SRamaswamy.Tummala@Sun.COM (void) close(sv6);
1423*12163SRamaswamy.Tummala@Sun.COM if (fd != -1)
1424*12163SRamaswamy.Tummala@Sun.COM (void) close(fd);
1425*12163SRamaswamy.Tummala@Sun.COM
1426*12163SRamaswamy.Tummala@Sun.COM dladm_close(dlh);
1427*12163SRamaswamy.Tummala@Sun.COM return (rv);
14280Sstevel@tonic-gate }
14290Sstevel@tonic-gate
14300Sstevel@tonic-gate static int
datadm_generate_conf_entry(FILE * outfile,datadm_ia_entry_t * ia_entry,datadm_sp_entry_t * sp_entry)14310Sstevel@tonic-gate datadm_generate_conf_entry(FILE *outfile, datadm_ia_entry_t *ia_entry,
14320Sstevel@tonic-gate datadm_sp_entry_t *sp_entry)
14330Sstevel@tonic-gate {
14340Sstevel@tonic-gate int retval;
14350Sstevel@tonic-gate
14360Sstevel@tonic-gate retval = fprintf(outfile,
1437*12163SRamaswamy.Tummala@Sun.COM "%s %s%d.%d %s %s %s %s%d.%d \"%s\" \"%s%s%s\"\n",
1438*12163SRamaswamy.Tummala@Sun.COM ia_entry->iae_name,
14390Sstevel@tonic-gate (sp_entry->spe_api_version.dv_name ?
14400Sstevel@tonic-gate sp_entry->spe_api_version.dv_name : ""),
14410Sstevel@tonic-gate sp_entry->spe_api_version.dv_major,
14420Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor,
14430Sstevel@tonic-gate (sp_entry->spe_threadsafe ? "threadsafe" : "nonthreadsafe"),
14440Sstevel@tonic-gate (sp_entry->spe_default ? "default" : "nondefault"),
14450Sstevel@tonic-gate sp_entry->spe_libpath,
14460Sstevel@tonic-gate (sp_entry->spe_sp_version.dv_name ?
14470Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name : ""),
14480Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major,
14490Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor,
14500Sstevel@tonic-gate sp_entry->spe_sp_data,
14510Sstevel@tonic-gate DATADM_DRV_NAME, "=", sp_entry->spe_devname);
14520Sstevel@tonic-gate
14530Sstevel@tonic-gate if (retval < 0) {
14540Sstevel@tonic-gate return (-1);
14550Sstevel@tonic-gate }
14560Sstevel@tonic-gate return (0);
14570Sstevel@tonic-gate }
14580Sstevel@tonic-gate
14590Sstevel@tonic-gate /*
14600Sstevel@tonic-gate * generate dat.conf header
14610Sstevel@tonic-gate */
14620Sstevel@tonic-gate static int
datadm_generate_conf_header(FILE * outfile)14630Sstevel@tonic-gate datadm_generate_conf_header(FILE *outfile)
14640Sstevel@tonic-gate {
14650Sstevel@tonic-gate datadm_entry_t *cep;
14660Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt;
14670Sstevel@tonic-gate int retval = 0;
14680Sstevel@tonic-gate
14690Sstevel@tonic-gate cep = datadm_conf_header.dl_head;
14700Sstevel@tonic-gate if (cep == NULL) {
14710Sstevel@tonic-gate /*
14720Sstevel@tonic-gate * if dat.conf doesn't have a header, we prepend a
14730Sstevel@tonic-gate * default one.
14740Sstevel@tonic-gate */
14750Sstevel@tonic-gate retval = fprintf(outfile, "%s", datadm_conf_header_default);
14760Sstevel@tonic-gate goto done;
14770Sstevel@tonic-gate }
14780Sstevel@tonic-gate while (cep != NULL) {
14790Sstevel@tonic-gate cmnt = (datadm_cmnt_entry_t *)cep;
14800Sstevel@tonic-gate if (cmnt->cmnt_line != NULL) {
14810Sstevel@tonic-gate int len;
14820Sstevel@tonic-gate
14830Sstevel@tonic-gate retval = fprintf(outfile, "%s", cmnt->cmnt_line);
14840Sstevel@tonic-gate if (retval < 0) {
14850Sstevel@tonic-gate break;
14860Sstevel@tonic-gate }
14870Sstevel@tonic-gate
14880Sstevel@tonic-gate /*
14890Sstevel@tonic-gate * append a newline if the comment line doesn't
14900Sstevel@tonic-gate * have one.
14910Sstevel@tonic-gate */
14920Sstevel@tonic-gate len = strlen(cmnt->cmnt_line);
14930Sstevel@tonic-gate if (cmnt->cmnt_line[len - 1] != '\n') {
14940Sstevel@tonic-gate retval = fprintf(outfile, "\n");
14950Sstevel@tonic-gate if (retval < 0) {
14960Sstevel@tonic-gate break;
14970Sstevel@tonic-gate }
14980Sstevel@tonic-gate }
14990Sstevel@tonic-gate }
15000Sstevel@tonic-gate cep = cep->de_next;
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate done:;
15030Sstevel@tonic-gate if (retval < 0) {
15040Sstevel@tonic-gate return (-1);
15050Sstevel@tonic-gate }
15060Sstevel@tonic-gate return (0);
15070Sstevel@tonic-gate }
15080Sstevel@tonic-gate
15090Sstevel@tonic-gate /*
15100Sstevel@tonic-gate * outputs dat.conf to stdout or to basedir/etc/dat/dat.conf
15110Sstevel@tonic-gate */
15120Sstevel@tonic-gate static int
datadm_generate_dat_conf(datadm_list_t * hca_list)15130Sstevel@tonic-gate datadm_generate_dat_conf(datadm_list_t *hca_list)
15140Sstevel@tonic-gate {
15150Sstevel@tonic-gate FILE *outfile = NULL;
15160Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf;
15170Sstevel@tonic-gate datadm_entry_t *hep;
15180Sstevel@tonic-gate int retval = 0;
15190Sstevel@tonic-gate
15200Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_VIEW) {
15210Sstevel@tonic-gate outfile = stdout;
15220Sstevel@tonic-gate } else {
15230Sstevel@tonic-gate outfile = fopen(dat_conf, "w+");
15240Sstevel@tonic-gate if (outfile == NULL) {
15250Sstevel@tonic-gate (void) fprintf(stderr, gettext(
15260Sstevel@tonic-gate "datadm: cannot open %s: %s\n"),
15270Sstevel@tonic-gate dat_conf, strerror(errno));
15280Sstevel@tonic-gate return (-1);
15290Sstevel@tonic-gate }
15300Sstevel@tonic-gate }
15310Sstevel@tonic-gate if (outfile != stdout) {
15320Sstevel@tonic-gate /*
15330Sstevel@tonic-gate * do not generate the header if we are
15340Sstevel@tonic-gate * printing to the screen
15350Sstevel@tonic-gate */
15360Sstevel@tonic-gate retval = datadm_generate_conf_header(outfile);
15370Sstevel@tonic-gate if (retval != 0) {
15380Sstevel@tonic-gate goto done;
15390Sstevel@tonic-gate }
15400Sstevel@tonic-gate }
15410Sstevel@tonic-gate hep = hca_list->dl_head;
15420Sstevel@tonic-gate while (hep != NULL) {
15430Sstevel@tonic-gate datadm_entry_t *iep;
15440Sstevel@tonic-gate
15450Sstevel@tonic-gate iep = ((datadm_hca_entry_t *)hep)->he_ia_list.dl_head;
15460Sstevel@tonic-gate while (iep != NULL) {
15470Sstevel@tonic-gate datadm_entry_t *sep;
15480Sstevel@tonic-gate
15490Sstevel@tonic-gate sep = ((datadm_hca_entry_t *)hep)->he_sp_list.dl_head;
15500Sstevel@tonic-gate while (sep != NULL) {
15510Sstevel@tonic-gate if (((datadm_sp_entry_t *)sep)->spe_invalid) {
15520Sstevel@tonic-gate sep = sep->de_next;
15530Sstevel@tonic-gate continue;
15540Sstevel@tonic-gate }
15550Sstevel@tonic-gate retval = datadm_generate_conf_entry(outfile,
15560Sstevel@tonic-gate (datadm_ia_entry_t *)iep,
15570Sstevel@tonic-gate (datadm_sp_entry_t *)sep);
15580Sstevel@tonic-gate if (retval != 0) {
15590Sstevel@tonic-gate goto done;
15600Sstevel@tonic-gate }
15610Sstevel@tonic-gate sep = sep->de_next;
15620Sstevel@tonic-gate }
15630Sstevel@tonic-gate iep = iep->de_next;
15640Sstevel@tonic-gate }
15650Sstevel@tonic-gate hep = hep->de_next;
15660Sstevel@tonic-gate }
15670Sstevel@tonic-gate retval = fflush(outfile);
15680Sstevel@tonic-gate done:;
15690Sstevel@tonic-gate if (outfile != stdout) {
15700Sstevel@tonic-gate (void) fclose(outfile);
15710Sstevel@tonic-gate }
15720Sstevel@tonic-gate if (retval < 0) {
15730Sstevel@tonic-gate perror("datadm: fprintf");
15740Sstevel@tonic-gate }
15750Sstevel@tonic-gate return (retval);
15760Sstevel@tonic-gate }
15770Sstevel@tonic-gate
15780Sstevel@tonic-gate static int
datadm_view(void)15790Sstevel@tonic-gate datadm_view(void)
15800Sstevel@tonic-gate {
15810Sstevel@tonic-gate int retval = 0;
15820Sstevel@tonic-gate datadm_list_t hca_list;
15830Sstevel@tonic-gate
15840Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list));
15850Sstevel@tonic-gate
15860Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list);
15870Sstevel@tonic-gate if (retval != 0) {
15880Sstevel@tonic-gate goto cleanup;
15890Sstevel@tonic-gate }
15900Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list);
15910Sstevel@tonic-gate if (retval != 0) {
15920Sstevel@tonic-gate goto cleanup;
15930Sstevel@tonic-gate }
15940Sstevel@tonic-gate
15950Sstevel@tonic-gate cleanup:;
15960Sstevel@tonic-gate datadm_free_list(&datadm_conf_header,
15970Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry);
15980Sstevel@tonic-gate datadm_free_list(&hca_list,
15990Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
16000Sstevel@tonic-gate return (retval);
16010Sstevel@tonic-gate }
16020Sstevel@tonic-gate
16030Sstevel@tonic-gate static int
datadm_update(void)16040Sstevel@tonic-gate datadm_update(void)
16050Sstevel@tonic-gate {
16060Sstevel@tonic-gate int retval = 0;
16070Sstevel@tonic-gate datadm_list_t hca_list;
16080Sstevel@tonic-gate
16090Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list));
16100Sstevel@tonic-gate
16110Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list);
16120Sstevel@tonic-gate if (retval != 0) {
16130Sstevel@tonic-gate goto cleanup;
16140Sstevel@tonic-gate }
16150Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list);
16160Sstevel@tonic-gate if (retval != 0) {
16170Sstevel@tonic-gate goto cleanup;
16180Sstevel@tonic-gate }
16190Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list);
16200Sstevel@tonic-gate if (retval != 0) {
16210Sstevel@tonic-gate goto cleanup;
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate cleanup:;
16250Sstevel@tonic-gate datadm_free_list(&datadm_conf_header,
16260Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry);
16270Sstevel@tonic-gate datadm_free_list(&hca_list,
16280Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
16290Sstevel@tonic-gate return (retval);
16300Sstevel@tonic-gate }
16310Sstevel@tonic-gate
16320Sstevel@tonic-gate static int
datadm_add(void)16330Sstevel@tonic-gate datadm_add(void)
16340Sstevel@tonic-gate {
16350Sstevel@tonic-gate int retval = 0;
16360Sstevel@tonic-gate datadm_list_t hca_list;
16370Sstevel@tonic-gate
16380Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list));
16390Sstevel@tonic-gate
16400Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list);
16410Sstevel@tonic-gate if (retval != 0) {
16420Sstevel@tonic-gate goto cleanup;
16430Sstevel@tonic-gate }
16440Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list);
16450Sstevel@tonic-gate if (retval != 0) {
16460Sstevel@tonic-gate goto cleanup;
16470Sstevel@tonic-gate }
16480Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list);
16490Sstevel@tonic-gate if (retval != 0) {
16500Sstevel@tonic-gate goto cleanup;
16510Sstevel@tonic-gate }
16520Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list);
16530Sstevel@tonic-gate if (retval != 0) {
16540Sstevel@tonic-gate goto cleanup;
16550Sstevel@tonic-gate }
16560Sstevel@tonic-gate
16570Sstevel@tonic-gate cleanup:;
16580Sstevel@tonic-gate datadm_free_list(&datadm_conf_header,
16590Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry);
16600Sstevel@tonic-gate datadm_free_list(&hca_list,
16610Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
16620Sstevel@tonic-gate return (retval);
16630Sstevel@tonic-gate }
16640Sstevel@tonic-gate
16650Sstevel@tonic-gate static int
datadm_remove(void)16660Sstevel@tonic-gate datadm_remove(void)
16670Sstevel@tonic-gate {
16680Sstevel@tonic-gate int retval = 0;
16690Sstevel@tonic-gate datadm_list_t hca_list;
16700Sstevel@tonic-gate datadm_list_t hca_list2;
16710Sstevel@tonic-gate
16720Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list));
16730Sstevel@tonic-gate bzero(&hca_list2, sizeof (hca_list2));
16740Sstevel@tonic-gate
16750Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list);
16760Sstevel@tonic-gate if (retval != 0) {
16770Sstevel@tonic-gate goto cleanup;
16780Sstevel@tonic-gate }
16790Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list2);
16800Sstevel@tonic-gate if (retval != 0) {
16810Sstevel@tonic-gate goto cleanup;
16820Sstevel@tonic-gate }
16830Sstevel@tonic-gate datadm_invalidate_common_sp_entries(&hca_list, &hca_list2);
16840Sstevel@tonic-gate
16850Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list);
16860Sstevel@tonic-gate if (retval != 0) {
16870Sstevel@tonic-gate goto cleanup;
16880Sstevel@tonic-gate }
16890Sstevel@tonic-gate
16900Sstevel@tonic-gate cleanup:;
16910Sstevel@tonic-gate datadm_free_list(&datadm_conf_header,
16920Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry);
16930Sstevel@tonic-gate datadm_free_list(&hca_list,
16940Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
16950Sstevel@tonic-gate datadm_free_list(&hca_list2,
16960Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry);
16970Sstevel@tonic-gate return (retval);
16980Sstevel@tonic-gate }
16990Sstevel@tonic-gate
17000Sstevel@tonic-gate static int
datadm_locate_dat_conf(char * basedir)17010Sstevel@tonic-gate datadm_locate_dat_conf(char *basedir)
17020Sstevel@tonic-gate {
17030Sstevel@tonic-gate char *dat_conf;
17040Sstevel@tonic-gate
17050Sstevel@tonic-gate if (basedir == NULL) {
17060Sstevel@tonic-gate datadm_args.da_dat_conf = DATADM_DAT_CONF;
17070Sstevel@tonic-gate return (0);
17080Sstevel@tonic-gate }
17090Sstevel@tonic-gate dat_conf = (char *)malloc(strlen(basedir) +
17100Sstevel@tonic-gate strlen(DATADM_DAT_CONF) + 1);
17110Sstevel@tonic-gate if (dat_conf == NULL) {
17120Sstevel@tonic-gate return (-1);
17130Sstevel@tonic-gate }
17140Sstevel@tonic-gate dat_conf[0] = '\0';
17150Sstevel@tonic-gate (void) strcat(dat_conf, basedir);
17160Sstevel@tonic-gate (void) strcat(dat_conf, DATADM_DAT_CONF);
17170Sstevel@tonic-gate datadm_args.da_dat_conf = dat_conf;
17180Sstevel@tonic-gate return (0);
17190Sstevel@tonic-gate }
17200Sstevel@tonic-gate
17210Sstevel@tonic-gate int
main(int argc,char ** argv)17220Sstevel@tonic-gate main(int argc, char **argv)
17230Sstevel@tonic-gate {
17240Sstevel@tonic-gate extern char *optarg;
17250Sstevel@tonic-gate extern int optind;
17260Sstevel@tonic-gate char *basedir = NULL;
17270Sstevel@tonic-gate int c, retval;
17280Sstevel@tonic-gate int op_type = -1, errflg = 0;
17290Sstevel@tonic-gate
17300Sstevel@tonic-gate bzero(&datadm_args, sizeof (datadm_args));
17310Sstevel@tonic-gate bzero(&datadm_conf_header, sizeof (datadm_conf_header));
17320Sstevel@tonic-gate
17330Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
17340Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
17350Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
17360Sstevel@tonic-gate #endif
17370Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
17380Sstevel@tonic-gate
17390Sstevel@tonic-gate while ((c = getopt(argc, argv, "vua:r:b:")) != EOF) {
17400Sstevel@tonic-gate switch (c) {
17410Sstevel@tonic-gate case 'v':
17420Sstevel@tonic-gate if (op_type != -1) errflg = 1;
17430Sstevel@tonic-gate op_type = DATADM_OP_VIEW;
17440Sstevel@tonic-gate break;
17450Sstevel@tonic-gate case 'u':
17460Sstevel@tonic-gate if (op_type != -1) errflg = 1;
17470Sstevel@tonic-gate op_type = DATADM_OP_UPDATE;
17480Sstevel@tonic-gate break;
17490Sstevel@tonic-gate case 'a':
17500Sstevel@tonic-gate if (op_type != -1) errflg = 1;
17510Sstevel@tonic-gate op_type = DATADM_OP_ADD;
17520Sstevel@tonic-gate datadm_args.da_sp_conf = optarg;
17530Sstevel@tonic-gate break;
17540Sstevel@tonic-gate case 'r':
17550Sstevel@tonic-gate if (op_type != -1) errflg = 1;
17560Sstevel@tonic-gate op_type = DATADM_OP_REMOVE;
17570Sstevel@tonic-gate datadm_args.da_sp_conf = optarg;
17580Sstevel@tonic-gate break;
17590Sstevel@tonic-gate case 'b':
17600Sstevel@tonic-gate basedir = optarg;
17610Sstevel@tonic-gate break;
17620Sstevel@tonic-gate default:
17630Sstevel@tonic-gate errflg = 1;
17640Sstevel@tonic-gate break;
17650Sstevel@tonic-gate }
17660Sstevel@tonic-gate if (errflg != 0) {
17670Sstevel@tonic-gate break;
17680Sstevel@tonic-gate }
17690Sstevel@tonic-gate }
17700Sstevel@tonic-gate if (errflg != 0 || op_type == -1 || optind < argc) {
17710Sstevel@tonic-gate datadm_usage();
17720Sstevel@tonic-gate return (1);
17730Sstevel@tonic-gate }
17740Sstevel@tonic-gate datadm_args.da_op_type = op_type;
17750Sstevel@tonic-gate if (datadm_locate_dat_conf(basedir)) {
17760Sstevel@tonic-gate return (1);
17770Sstevel@tonic-gate }
17780Sstevel@tonic-gate
17790Sstevel@tonic-gate retval = (*datadm_ops[op_type])();
17800Sstevel@tonic-gate return (retval);
17810Sstevel@tonic-gate }
1782