1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <unistd.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/sockio.h> 33*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 34*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 35*7c478bd9Sstevel@tonic-gate #include <net/if.h> 36*7c478bd9Sstevel@tonic-gate #include <stdio.h> 37*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7c478bd9Sstevel@tonic-gate #include <strings.h> 39*7c478bd9Sstevel@tonic-gate #include <ctype.h> 40*7c478bd9Sstevel@tonic-gate #include <errno.h> 41*7c478bd9Sstevel@tonic-gate #include <libintl.h> 42*7c478bd9Sstevel@tonic-gate #include <locale.h> 43*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #define DATADM_OP_VIEW 0x0000 46*7c478bd9Sstevel@tonic-gate #define DATADM_OP_UPDATE 0x0001 47*7c478bd9Sstevel@tonic-gate #define DATADM_OP_ADD 0x0002 48*7c478bd9Sstevel@tonic-gate #define DATADM_OP_REMOVE 0x0003 49*7c478bd9Sstevel@tonic-gate #define DATADM_NUM_OPS 0x0004 50*7c478bd9Sstevel@tonic-gate #define DATADM_DAT_CONF "/etc/dat/dat.conf" 51*7c478bd9Sstevel@tonic-gate #define DATADM_LINESZ 1024 52*7c478bd9Sstevel@tonic-gate #define DATADM_NUM_SP_TOKENS 7 53*7c478bd9Sstevel@tonic-gate #define DATADM_NUM_DAT_TOKENS 8 54*7c478bd9Sstevel@tonic-gate #define DATADM_IA_NAME "ibd" 55*7c478bd9Sstevel@tonic-gate #define DATADM_DRV_NAME "driver_name" 56*7c478bd9Sstevel@tonic-gate #define DATADM_MAX_TOKENS 16 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate * generic entry 60*7c478bd9Sstevel@tonic-gate * placed at the top of all entry types 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate typedef struct datadm_entry { 63*7c478bd9Sstevel@tonic-gate struct datadm_entry *de_next; 64*7c478bd9Sstevel@tonic-gate } datadm_entry_t; 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * list structure 68*7c478bd9Sstevel@tonic-gate * can be manipulated using datadm_walk_list or 69*7c478bd9Sstevel@tonic-gate * datadm_enqueue_entry 70*7c478bd9Sstevel@tonic-gate */ 71*7c478bd9Sstevel@tonic-gate typedef struct datadm_list { 72*7c478bd9Sstevel@tonic-gate datadm_entry_t *dl_head; 73*7c478bd9Sstevel@tonic-gate datadm_entry_t *dl_tail; 74*7c478bd9Sstevel@tonic-gate uint_t dl_count; 75*7c478bd9Sstevel@tonic-gate } datadm_list_t; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate /* 78*7c478bd9Sstevel@tonic-gate * internal representation of the version string in 79*7c478bd9Sstevel@tonic-gate * dat.conf or service_provider.conf. the format is 80*7c478bd9Sstevel@tonic-gate * <dv_name><dv_major>.<dv_minor> 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate typedef struct datadm_version { 83*7c478bd9Sstevel@tonic-gate char *dv_name; 84*7c478bd9Sstevel@tonic-gate uint_t dv_major; 85*7c478bd9Sstevel@tonic-gate uint_t dv_minor; 86*7c478bd9Sstevel@tonic-gate } datadm_version_t; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * each sp_entry corresponds to an entry in dat.conf or 90*7c478bd9Sstevel@tonic-gate * service_provider.conf. an sp_entry is processed by the 91*7c478bd9Sstevel@tonic-gate * function datadm_process_sp_entry. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate typedef struct datadm_sp_entry { 94*7c478bd9Sstevel@tonic-gate datadm_entry_t spe_header; 95*7c478bd9Sstevel@tonic-gate char *spe_devname; 96*7c478bd9Sstevel@tonic-gate datadm_version_t spe_api_version; 97*7c478bd9Sstevel@tonic-gate int spe_threadsafe; 98*7c478bd9Sstevel@tonic-gate int spe_default; 99*7c478bd9Sstevel@tonic-gate char *spe_libpath; 100*7c478bd9Sstevel@tonic-gate datadm_version_t spe_sp_version; 101*7c478bd9Sstevel@tonic-gate char *spe_sp_data; 102*7c478bd9Sstevel@tonic-gate int spe_invalid; 103*7c478bd9Sstevel@tonic-gate } datadm_sp_entry_t; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* 106*7c478bd9Sstevel@tonic-gate * an hca_entry is created whenever a new hca device is 107*7c478bd9Sstevel@tonic-gate * encountered during sp_entry processing. this structure 108*7c478bd9Sstevel@tonic-gate * contains two lists. the sp_list holds sp entries that 109*7c478bd9Sstevel@tonic-gate * are added when sp entry processing occurs. duplicate 110*7c478bd9Sstevel@tonic-gate * sp entries are not added to this list. the ia_list may 111*7c478bd9Sstevel@tonic-gate * be built statically using the information in dat.conf or 112*7c478bd9Sstevel@tonic-gate * dynamically using libdevinfo. similar to the sp_list, 113*7c478bd9Sstevel@tonic-gate * the ia_list contains only unique entries. 114*7c478bd9Sstevel@tonic-gate */ 115*7c478bd9Sstevel@tonic-gate typedef struct datadm_hca_entry { 116*7c478bd9Sstevel@tonic-gate datadm_entry_t he_header; 117*7c478bd9Sstevel@tonic-gate char *he_name; 118*7c478bd9Sstevel@tonic-gate datadm_list_t he_sp_list; 119*7c478bd9Sstevel@tonic-gate datadm_list_t he_ia_list; 120*7c478bd9Sstevel@tonic-gate } datadm_hca_entry_t; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate /* 123*7c478bd9Sstevel@tonic-gate * an ia_entry is created when a new ia name is encountered 124*7c478bd9Sstevel@tonic-gate * during sp_entry processing or when a new ia name is 125*7c478bd9Sstevel@tonic-gate * discovered by datadm_fill_ia_list. ia_entry holds the ia 126*7c478bd9Sstevel@tonic-gate * device's instance number. 127*7c478bd9Sstevel@tonic-gate */ 128*7c478bd9Sstevel@tonic-gate typedef struct datadm_ia_entry { 129*7c478bd9Sstevel@tonic-gate datadm_entry_t iae_header; 130*7c478bd9Sstevel@tonic-gate int iae_devnum; 131*7c478bd9Sstevel@tonic-gate } datadm_ia_entry_t; 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate /* 134*7c478bd9Sstevel@tonic-gate * a comment entry represents one of the comment lines at the 135*7c478bd9Sstevel@tonic-gate * top of dat.conf. a list of these lines are saved during the 136*7c478bd9Sstevel@tonic-gate * parsing of dat.conf. these lines are written back to dat.conf 137*7c478bd9Sstevel@tonic-gate * when dat.conf gets regenerated. 138*7c478bd9Sstevel@tonic-gate */ 139*7c478bd9Sstevel@tonic-gate typedef struct datadm_cmnt_entry { 140*7c478bd9Sstevel@tonic-gate datadm_entry_t cmnt_header; 141*7c478bd9Sstevel@tonic-gate char *cmnt_line; 142*7c478bd9Sstevel@tonic-gate } datadm_cmnt_entry_t; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * 2nd argument to datadm_hca_entry_find. 146*7c478bd9Sstevel@tonic-gate * hf_hca_entry is filled in if an hca_entry with 147*7c478bd9Sstevel@tonic-gate * a matching he_name is found. 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate typedef struct datadm_hca_find { 150*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *hf_sp_entry; 151*7c478bd9Sstevel@tonic-gate datadm_hca_entry_t *hf_hca_entry; 152*7c478bd9Sstevel@tonic-gate } datadm_hca_find_t; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* 155*7c478bd9Sstevel@tonic-gate * 2nd argument to datadm_ia_entry_find. 156*7c478bd9Sstevel@tonic-gate * if_ia_entry is filled in if an ia_entry with 157*7c478bd9Sstevel@tonic-gate * a matching ia_devnum is found. 158*7c478bd9Sstevel@tonic-gate */ 159*7c478bd9Sstevel@tonic-gate typedef struct datadm_ia_find { 160*7c478bd9Sstevel@tonic-gate int if_ia_devnum; 161*7c478bd9Sstevel@tonic-gate datadm_ia_entry_t *if_ia_entry; 162*7c478bd9Sstevel@tonic-gate } datadm_ia_find_t; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate /* 165*7c478bd9Sstevel@tonic-gate * this gets passed to datadm_fill_ia_list. 166*7c478bd9Sstevel@tonic-gate * we do this to avoid regenerating the device 167*7c478bd9Sstevel@tonic-gate * tree for each hca_entry we process. 168*7c478bd9Sstevel@tonic-gate */ 169*7c478bd9Sstevel@tonic-gate typedef struct datadm_fill_ia_list { 170*7c478bd9Sstevel@tonic-gate di_node_t ia_root_node; 171*7c478bd9Sstevel@tonic-gate int ia_sock_fd_v4; 172*7c478bd9Sstevel@tonic-gate int ia_sock_fd_v6; 173*7c478bd9Sstevel@tonic-gate } datadm_fill_ia_list_t; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate /* 176*7c478bd9Sstevel@tonic-gate * this defines the commandline parameters specified 177*7c478bd9Sstevel@tonic-gate * by the user. 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate typedef struct datadm_args { 180*7c478bd9Sstevel@tonic-gate char *da_sp_conf; 181*7c478bd9Sstevel@tonic-gate char *da_dat_conf; 182*7c478bd9Sstevel@tonic-gate int da_op_type; 183*7c478bd9Sstevel@tonic-gate } datadm_args_t; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate static datadm_args_t datadm_args; 186*7c478bd9Sstevel@tonic-gate static datadm_list_t datadm_conf_header; 187*7c478bd9Sstevel@tonic-gate static char *datadm_conf_header_default = 188*7c478bd9Sstevel@tonic-gate "#\n" 189*7c478bd9Sstevel@tonic-gate "# Copyright 2004 Sun Microsystems, Inc. All rights reserved.\n" 190*7c478bd9Sstevel@tonic-gate "# Use is subject to license terms.\n" 191*7c478bd9Sstevel@tonic-gate "#\n" 192*7c478bd9Sstevel@tonic-gate "# ident \"@(#)dat.conf 1.1 03/08/26 SMI\"\n" 193*7c478bd9Sstevel@tonic-gate "#\n" 194*7c478bd9Sstevel@tonic-gate "# DAT configuration file.\n" 195*7c478bd9Sstevel@tonic-gate "#\n" 196*7c478bd9Sstevel@tonic-gate "# This file is updated using the datadm(1) command.\n" 197*7c478bd9Sstevel@tonic-gate "# Do not hand edit this file.\n" 198*7c478bd9Sstevel@tonic-gate "# See datadm(1) man page for more details.\n" 199*7c478bd9Sstevel@tonic-gate "#\n" 200*7c478bd9Sstevel@tonic-gate "# The fields in this file are -\n" 201*7c478bd9Sstevel@tonic-gate "#\n" 202*7c478bd9Sstevel@tonic-gate "# IAname version threadsafe default library-path provider-version \\\n" 203*7c478bd9Sstevel@tonic-gate "# instance-data platform-information\n" 204*7c478bd9Sstevel@tonic-gate "#\n"; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * common parsing functions. 208*7c478bd9Sstevel@tonic-gate */ 209*7c478bd9Sstevel@tonic-gate typedef int (*datadm_parse_func_t)(char *, void *); 210*7c478bd9Sstevel@tonic-gate static int datadm_parse_line(char *, char *[], int *); 211*7c478bd9Sstevel@tonic-gate static int datadm_parse_generic_str(char *, char **); 212*7c478bd9Sstevel@tonic-gate static int datadm_parse_nonnull_str(char *, char **); 213*7c478bd9Sstevel@tonic-gate static int datadm_parse_version(char *, datadm_version_t *); 214*7c478bd9Sstevel@tonic-gate static int datadm_parse_devname(char *, datadm_sp_entry_t *); 215*7c478bd9Sstevel@tonic-gate static int datadm_parse_api_version(char *, datadm_sp_entry_t *); 216*7c478bd9Sstevel@tonic-gate static int datadm_parse_threadsafe(char *, datadm_sp_entry_t *); 217*7c478bd9Sstevel@tonic-gate static int datadm_parse_default(char *, datadm_sp_entry_t *); 218*7c478bd9Sstevel@tonic-gate static int datadm_parse_libpath(char *, datadm_sp_entry_t *); 219*7c478bd9Sstevel@tonic-gate static int datadm_parse_sp_version(char *, datadm_sp_entry_t *); 220*7c478bd9Sstevel@tonic-gate static int datadm_parse_sp_data(char *, datadm_sp_entry_t *); 221*7c478bd9Sstevel@tonic-gate static int datadm_parse_ia_name(char *, int *); 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* 224*7c478bd9Sstevel@tonic-gate * utility functions 225*7c478bd9Sstevel@tonic-gate */ 226*7c478bd9Sstevel@tonic-gate static void datadm_enqueue_entry(datadm_list_t *, datadm_entry_t *); 227*7c478bd9Sstevel@tonic-gate static int datadm_walk_list(datadm_list_t *, 228*7c478bd9Sstevel@tonic-gate int (*)(datadm_entry_t *, void *), void *); 229*7c478bd9Sstevel@tonic-gate static int datadm_str_match(char *, char *); 230*7c478bd9Sstevel@tonic-gate static int datadm_version_match(datadm_version_t *, datadm_version_t *); 231*7c478bd9Sstevel@tonic-gate static int datadm_sp_entry_match(datadm_sp_entry_t *, datadm_sp_entry_t *); 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate /* 234*7c478bd9Sstevel@tonic-gate * entry allocation/deallocation 235*7c478bd9Sstevel@tonic-gate */ 236*7c478bd9Sstevel@tonic-gate static datadm_sp_entry_t *datadm_alloc_sp_entry(void); 237*7c478bd9Sstevel@tonic-gate static datadm_ia_entry_t *datadm_alloc_ia_entry(void); 238*7c478bd9Sstevel@tonic-gate static datadm_hca_entry_t *datadm_alloc_hca_entry(void); 239*7c478bd9Sstevel@tonic-gate static datadm_cmnt_entry_t *datadm_alloc_cmnt_entry(void); 240*7c478bd9Sstevel@tonic-gate static void datadm_free_sp_entry(datadm_sp_entry_t *); 241*7c478bd9Sstevel@tonic-gate static void datadm_free_ia_entry(datadm_ia_entry_t *); 242*7c478bd9Sstevel@tonic-gate static void datadm_free_hca_entry(datadm_hca_entry_t *); 243*7c478bd9Sstevel@tonic-gate static void datadm_free_cmnt_entry(datadm_cmnt_entry_t *); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* 247*7c478bd9Sstevel@tonic-gate * high level parsing functions 248*7c478bd9Sstevel@tonic-gate */ 249*7c478bd9Sstevel@tonic-gate static int datadm_parse_sp_conf(datadm_list_t *); 250*7c478bd9Sstevel@tonic-gate static int datadm_parse_dat_conf(datadm_list_t *); 251*7c478bd9Sstevel@tonic-gate static int datadm_process_sp_entry(datadm_list_t *, datadm_sp_entry_t *, int); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* 254*7c478bd9Sstevel@tonic-gate * ia devices discovery 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate static int datadm_build_ia_lists(datadm_list_t *); 257*7c478bd9Sstevel@tonic-gate static int datadm_fill_ia_list(datadm_hca_entry_t *, datadm_fill_ia_list_t *); 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate /* 260*7c478bd9Sstevel@tonic-gate * helper function for OP_REMOVE 261*7c478bd9Sstevel@tonic-gate */ 262*7c478bd9Sstevel@tonic-gate static void datadm_invalidate_common_sp_entries(datadm_list_t *, 263*7c478bd9Sstevel@tonic-gate datadm_list_t *); 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate /* 266*7c478bd9Sstevel@tonic-gate * output generation 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate static int datadm_generate_dat_conf(datadm_list_t *); 269*7c478bd9Sstevel@tonic-gate static int datadm_generate_conf_header(FILE *); 270*7c478bd9Sstevel@tonic-gate static int datadm_generate_conf_entry(FILE *, datadm_ia_entry_t *, 271*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *); 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * datadm operations 275*7c478bd9Sstevel@tonic-gate */ 276*7c478bd9Sstevel@tonic-gate static int datadm_view(void); 277*7c478bd9Sstevel@tonic-gate static int datadm_update(void); 278*7c478bd9Sstevel@tonic-gate static int datadm_add(void); 279*7c478bd9Sstevel@tonic-gate static int datadm_remove(void); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* 282*7c478bd9Sstevel@tonic-gate * usage 283*7c478bd9Sstevel@tonic-gate */ 284*7c478bd9Sstevel@tonic-gate static void datadm_usage(void); 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* 288*7c478bd9Sstevel@tonic-gate * parse function tables 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate static datadm_parse_func_t datadm_sp_parse_funcs[DATADM_NUM_SP_TOKENS] = { 291*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname, 292*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version, 293*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe, 294*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default, 295*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath, 296*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version, 297*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data 298*7c478bd9Sstevel@tonic-gate }; 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate static datadm_parse_func_t datadm_dat_parse_funcs[DATADM_NUM_DAT_TOKENS] = { 301*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_ia_name, 302*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_api_version, 303*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_threadsafe, 304*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_default, 305*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_libpath, 306*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_version, 307*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_sp_data, 308*7c478bd9Sstevel@tonic-gate (datadm_parse_func_t)datadm_parse_devname 309*7c478bd9Sstevel@tonic-gate }; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate /* 312*7c478bd9Sstevel@tonic-gate * operation table 313*7c478bd9Sstevel@tonic-gate */ 314*7c478bd9Sstevel@tonic-gate static int (*datadm_ops[DATADM_NUM_OPS])(void) = { 315*7c478bd9Sstevel@tonic-gate datadm_view, 316*7c478bd9Sstevel@tonic-gate datadm_update, 317*7c478bd9Sstevel@tonic-gate datadm_add, 318*7c478bd9Sstevel@tonic-gate datadm_remove 319*7c478bd9Sstevel@tonic-gate }; 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate static void 322*7c478bd9Sstevel@tonic-gate datadm_usage(void) 323*7c478bd9Sstevel@tonic-gate { 324*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 325*7c478bd9Sstevel@tonic-gate "usage: datadm -v\n" 326*7c478bd9Sstevel@tonic-gate " -u\n" 327*7c478bd9Sstevel@tonic-gate " -a <service_provider.conf>\n" 328*7c478bd9Sstevel@tonic-gate " -r <service_provider.conf>\n")); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate static int 332*7c478bd9Sstevel@tonic-gate datadm_parse_generic_str(char *str, char **strptr) 333*7c478bd9Sstevel@tonic-gate { 334*7c478bd9Sstevel@tonic-gate int len; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate len = strlen(str); 337*7c478bd9Sstevel@tonic-gate *strptr = (char *)malloc(len + 1); 338*7c478bd9Sstevel@tonic-gate if (*strptr == NULL) { 339*7c478bd9Sstevel@tonic-gate return (-1); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate (void) strcpy(*strptr, str); 342*7c478bd9Sstevel@tonic-gate return (0); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * this function strips off leading and trailing 347*7c478bd9Sstevel@tonic-gate * whitespaces and returns an error for null or 348*7c478bd9Sstevel@tonic-gate * empty strings. 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate static int 351*7c478bd9Sstevel@tonic-gate datadm_parse_nonnull_str(char *str, char **strptr) 352*7c478bd9Sstevel@tonic-gate { 353*7c478bd9Sstevel@tonic-gate int len, i; 354*7c478bd9Sstevel@tonic-gate char *start; 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate if (str[0] == '\0') { 357*7c478bd9Sstevel@tonic-gate return (-1); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate start = str; 360*7c478bd9Sstevel@tonic-gate for (i = 0; str[i] != '\0'; i++) { 361*7c478bd9Sstevel@tonic-gate if (!isspace(str[i])) { 362*7c478bd9Sstevel@tonic-gate start = &str[i]; 363*7c478bd9Sstevel@tonic-gate break; 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate for (; str[i] != '\0'; i++) { 367*7c478bd9Sstevel@tonic-gate if (isspace(str[i])) { 368*7c478bd9Sstevel@tonic-gate str[i] = '\0'; 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate len = strlen(start); 372*7c478bd9Sstevel@tonic-gate *strptr = (char *)malloc(len + 1); 373*7c478bd9Sstevel@tonic-gate if (*strptr == NULL) { 374*7c478bd9Sstevel@tonic-gate return (-1); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate (void) strcpy(*strptr, start); 377*7c478bd9Sstevel@tonic-gate return (0); 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate /* 381*7c478bd9Sstevel@tonic-gate * parses the api_version and sp_version fields in 382*7c478bd9Sstevel@tonic-gate * dat.conf and service_provider.conf 383*7c478bd9Sstevel@tonic-gate */ 384*7c478bd9Sstevel@tonic-gate static int 385*7c478bd9Sstevel@tonic-gate datadm_parse_version(char *str, datadm_version_t *version) 386*7c478bd9Sstevel@tonic-gate { 387*7c478bd9Sstevel@tonic-gate int i = 0, len; 388*7c478bd9Sstevel@tonic-gate int major_idx, minor_idx; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate len = strlen(str); 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 393*7c478bd9Sstevel@tonic-gate if (isdigit(str[i])) break; 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate if (i == len) { 396*7c478bd9Sstevel@tonic-gate return (-1); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate if (i > 0) { 399*7c478bd9Sstevel@tonic-gate version->dv_name = (char *)malloc(i + 1); 400*7c478bd9Sstevel@tonic-gate bcopy(str, version->dv_name, i); 401*7c478bd9Sstevel@tonic-gate version->dv_name[i] = '\0'; 402*7c478bd9Sstevel@tonic-gate } else { 403*7c478bd9Sstevel@tonic-gate version->dv_name = NULL; 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate major_idx = i; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate for (; i < len; i++) { 408*7c478bd9Sstevel@tonic-gate if (!isdigit(str[i])) break; 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate if (i == len) { 411*7c478bd9Sstevel@tonic-gate return (-1); 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate if (str[i] != '.') { 414*7c478bd9Sstevel@tonic-gate return (-1); 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate minor_idx = ++i; 417*7c478bd9Sstevel@tonic-gate if (i == len) { 418*7c478bd9Sstevel@tonic-gate return (-1); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate for (; i < len; i++) { 421*7c478bd9Sstevel@tonic-gate if (!isdigit(str[i])) break; 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate if (i != len) { 424*7c478bd9Sstevel@tonic-gate return (-1); 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate version->dv_major = atoi(str + major_idx); 427*7c478bd9Sstevel@tonic-gate version->dv_minor = atoi(str + minor_idx); 428*7c478bd9Sstevel@tonic-gate return (0); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate /* 432*7c478bd9Sstevel@tonic-gate * parses the ia_name field in dat.conf 433*7c478bd9Sstevel@tonic-gate */ 434*7c478bd9Sstevel@tonic-gate static int 435*7c478bd9Sstevel@tonic-gate datadm_parse_ia_name(char *str, int *ia_devnum) 436*7c478bd9Sstevel@tonic-gate { 437*7c478bd9Sstevel@tonic-gate int len; 438*7c478bd9Sstevel@tonic-gate int i, start; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate len = strlen(DATADM_IA_NAME); 441*7c478bd9Sstevel@tonic-gate if (strncmp(str, DATADM_IA_NAME, len) != 0) { 442*7c478bd9Sstevel@tonic-gate return (-1); 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate start = i = len; 445*7c478bd9Sstevel@tonic-gate len = strlen(str); 446*7c478bd9Sstevel@tonic-gate if (str[i] == '\0') { 447*7c478bd9Sstevel@tonic-gate return (-1); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate for (; i < len; i++) { 450*7c478bd9Sstevel@tonic-gate if (!isdigit(str[i])) break; 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate if (i != len) { 453*7c478bd9Sstevel@tonic-gate return (-1); 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate *ia_devnum = atoi(str + start); 456*7c478bd9Sstevel@tonic-gate return (0); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate /* 460*7c478bd9Sstevel@tonic-gate * parses the device name, strips leading and trailing spaces. 461*7c478bd9Sstevel@tonic-gate * the format should be "driver_name=<dev_name>" 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate static int 464*7c478bd9Sstevel@tonic-gate datadm_parse_devname(char *str, datadm_sp_entry_t *sp_entry) 465*7c478bd9Sstevel@tonic-gate { 466*7c478bd9Sstevel@tonic-gate int len, dlen, i, j = 0; 467*7c478bd9Sstevel@tonic-gate char *drv_name = DATADM_DRV_NAME; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate len = strlen(str); 470*7c478bd9Sstevel@tonic-gate dlen = strlen(drv_name); 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate /* 473*7c478bd9Sstevel@tonic-gate * strip out leading spaces and try to match 474*7c478bd9Sstevel@tonic-gate * the expected string 475*7c478bd9Sstevel@tonic-gate */ 476*7c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 477*7c478bd9Sstevel@tonic-gate if (isspace(str[i]) && j == 0) { 478*7c478bd9Sstevel@tonic-gate continue; 479*7c478bd9Sstevel@tonic-gate } else { 480*7c478bd9Sstevel@tonic-gate if (str[i] == drv_name[j]) { 481*7c478bd9Sstevel@tonic-gate j++; 482*7c478bd9Sstevel@tonic-gate if (j == dlen) { 483*7c478bd9Sstevel@tonic-gate break; 484*7c478bd9Sstevel@tonic-gate } else { 485*7c478bd9Sstevel@tonic-gate continue; 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate } else { 488*7c478bd9Sstevel@tonic-gate break; 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate /* 494*7c478bd9Sstevel@tonic-gate * j must be dlen if the matching string is found 495*7c478bd9Sstevel@tonic-gate */ 496*7c478bd9Sstevel@tonic-gate if (j != dlen) { 497*7c478bd9Sstevel@tonic-gate return (-1); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate /* 501*7c478bd9Sstevel@tonic-gate * skip past the last char of drv_name 502*7c478bd9Sstevel@tonic-gate */ 503*7c478bd9Sstevel@tonic-gate i++; 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate /* 506*7c478bd9Sstevel@tonic-gate * strip the spaces before the '=' 507*7c478bd9Sstevel@tonic-gate */ 508*7c478bd9Sstevel@tonic-gate for (; i < len; i++) { 509*7c478bd9Sstevel@tonic-gate if (!isspace(str[i])) { 510*7c478bd9Sstevel@tonic-gate break; 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* 515*7c478bd9Sstevel@tonic-gate * return if the string is too long or if 516*7c478bd9Sstevel@tonic-gate * the '=' isn't found 517*7c478bd9Sstevel@tonic-gate */ 518*7c478bd9Sstevel@tonic-gate if (i >= len || str[i] != '=') { 519*7c478bd9Sstevel@tonic-gate return (-1); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate i++; 522*7c478bd9Sstevel@tonic-gate if (i >= len) { 523*7c478bd9Sstevel@tonic-gate /* 524*7c478bd9Sstevel@tonic-gate * no string after the equal 525*7c478bd9Sstevel@tonic-gate */ 526*7c478bd9Sstevel@tonic-gate return (-1); 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate return (datadm_parse_nonnull_str(str + i, &sp_entry->spe_devname)); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate static int 532*7c478bd9Sstevel@tonic-gate datadm_parse_api_version(char *str, datadm_sp_entry_t *sp_entry) 533*7c478bd9Sstevel@tonic-gate { 534*7c478bd9Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_api_version)); 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate static int 538*7c478bd9Sstevel@tonic-gate datadm_parse_threadsafe(char *str, datadm_sp_entry_t *sp_entry) 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate int retval = 0; 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate if (strcmp(str, "threadsafe") == 0) { 543*7c478bd9Sstevel@tonic-gate sp_entry->spe_threadsafe = 1; 544*7c478bd9Sstevel@tonic-gate } else if (strcmp(str, "nonthreadsafe") == 0) { 545*7c478bd9Sstevel@tonic-gate sp_entry->spe_threadsafe = 0; 546*7c478bd9Sstevel@tonic-gate } else { 547*7c478bd9Sstevel@tonic-gate retval = -1; 548*7c478bd9Sstevel@tonic-gate } 549*7c478bd9Sstevel@tonic-gate return (retval); 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate static int 553*7c478bd9Sstevel@tonic-gate datadm_parse_default(char *str, datadm_sp_entry_t *sp_entry) 554*7c478bd9Sstevel@tonic-gate { 555*7c478bd9Sstevel@tonic-gate int retval = 0; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate if (strcmp(str, "default") == 0) { 558*7c478bd9Sstevel@tonic-gate sp_entry->spe_default = 1; 559*7c478bd9Sstevel@tonic-gate } else if (strcmp(str, "nondefault") == 0) { 560*7c478bd9Sstevel@tonic-gate sp_entry->spe_default = 0; 561*7c478bd9Sstevel@tonic-gate } else { 562*7c478bd9Sstevel@tonic-gate retval = -1; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate return (retval); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate static int 568*7c478bd9Sstevel@tonic-gate datadm_parse_libpath(char *str, datadm_sp_entry_t *sp_entry) 569*7c478bd9Sstevel@tonic-gate { 570*7c478bd9Sstevel@tonic-gate return (datadm_parse_nonnull_str(str, &sp_entry->spe_libpath)); 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate static int 574*7c478bd9Sstevel@tonic-gate datadm_parse_sp_version(char *str, datadm_sp_entry_t *sp_entry) 575*7c478bd9Sstevel@tonic-gate { 576*7c478bd9Sstevel@tonic-gate return (datadm_parse_version(str, &sp_entry->spe_sp_version)); 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate static int 580*7c478bd9Sstevel@tonic-gate datadm_parse_sp_data(char *str, datadm_sp_entry_t *sp_entry) 581*7c478bd9Sstevel@tonic-gate { 582*7c478bd9Sstevel@tonic-gate return (datadm_parse_generic_str(str, &sp_entry->spe_sp_data)); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate static void 586*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(datadm_list_t *list, datadm_entry_t *entry) 587*7c478bd9Sstevel@tonic-gate { 588*7c478bd9Sstevel@tonic-gate if (list->dl_head == NULL) { 589*7c478bd9Sstevel@tonic-gate list->dl_head = entry; 590*7c478bd9Sstevel@tonic-gate list->dl_tail = entry; 591*7c478bd9Sstevel@tonic-gate list->dl_count = 1; 592*7c478bd9Sstevel@tonic-gate } else { 593*7c478bd9Sstevel@tonic-gate list->dl_tail->de_next = entry; 594*7c478bd9Sstevel@tonic-gate list->dl_tail = entry; 595*7c478bd9Sstevel@tonic-gate list->dl_count++; 596*7c478bd9Sstevel@tonic-gate } 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate /* 600*7c478bd9Sstevel@tonic-gate * iterates through the list applying func on each element. 601*7c478bd9Sstevel@tonic-gate * break and return if func returns non-zero. 602*7c478bd9Sstevel@tonic-gate */ 603*7c478bd9Sstevel@tonic-gate static int 604*7c478bd9Sstevel@tonic-gate datadm_walk_list(datadm_list_t *list, int (*func)(datadm_entry_t *, void *), 605*7c478bd9Sstevel@tonic-gate void *arg) 606*7c478bd9Sstevel@tonic-gate { 607*7c478bd9Sstevel@tonic-gate datadm_entry_t *entry; 608*7c478bd9Sstevel@tonic-gate int retval = 0; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate entry = list->dl_head; 611*7c478bd9Sstevel@tonic-gate while (entry != NULL) { 612*7c478bd9Sstevel@tonic-gate retval = (*func)(entry, arg); 613*7c478bd9Sstevel@tonic-gate if (retval != 0) break; 614*7c478bd9Sstevel@tonic-gate entry = entry->de_next; 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate return (retval); 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate /* 620*7c478bd9Sstevel@tonic-gate * iterates through the list applying free_func to each element. 621*7c478bd9Sstevel@tonic-gate * list becomes empty when the function returns. 622*7c478bd9Sstevel@tonic-gate */ 623*7c478bd9Sstevel@tonic-gate static void 624*7c478bd9Sstevel@tonic-gate datadm_free_list(datadm_list_t *list, void (*free_func)(datadm_entry_t *)) 625*7c478bd9Sstevel@tonic-gate { 626*7c478bd9Sstevel@tonic-gate while (list->dl_head != NULL) { 627*7c478bd9Sstevel@tonic-gate datadm_entry_t *entry; 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate entry = list->dl_head; 630*7c478bd9Sstevel@tonic-gate list->dl_head = entry->de_next; 631*7c478bd9Sstevel@tonic-gate (*free_func)(entry); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate list->dl_count = 0; 634*7c478bd9Sstevel@tonic-gate list->dl_tail = NULL; 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate static datadm_sp_entry_t * 638*7c478bd9Sstevel@tonic-gate datadm_alloc_sp_entry(void) 639*7c478bd9Sstevel@tonic-gate { 640*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate sp_entry = (datadm_sp_entry_t *)malloc(sizeof (*sp_entry)); 643*7c478bd9Sstevel@tonic-gate if (sp_entry == NULL) { 644*7c478bd9Sstevel@tonic-gate return (NULL); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate bzero(sp_entry, sizeof (*sp_entry)); 647*7c478bd9Sstevel@tonic-gate return (sp_entry); 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate static void 651*7c478bd9Sstevel@tonic-gate datadm_free_sp_entry(datadm_sp_entry_t *sp_entry) 652*7c478bd9Sstevel@tonic-gate { 653*7c478bd9Sstevel@tonic-gate if (sp_entry->spe_devname != NULL) { 654*7c478bd9Sstevel@tonic-gate free(sp_entry->spe_devname); 655*7c478bd9Sstevel@tonic-gate sp_entry->spe_devname = NULL; 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate if (sp_entry->spe_api_version.dv_name != NULL) { 658*7c478bd9Sstevel@tonic-gate free(sp_entry->spe_api_version.dv_name); 659*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_name = NULL; 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_major = 0; 662*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor = 0; 663*7c478bd9Sstevel@tonic-gate sp_entry->spe_threadsafe = 0; 664*7c478bd9Sstevel@tonic-gate sp_entry->spe_default = 0; 665*7c478bd9Sstevel@tonic-gate if (sp_entry->spe_libpath != NULL) { 666*7c478bd9Sstevel@tonic-gate free(sp_entry->spe_libpath); 667*7c478bd9Sstevel@tonic-gate sp_entry->spe_libpath = NULL; 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate if (sp_entry->spe_sp_version.dv_name != NULL) { 670*7c478bd9Sstevel@tonic-gate free(sp_entry->spe_sp_version.dv_name); 671*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name = NULL; 672*7c478bd9Sstevel@tonic-gate } 673*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major = 0; 674*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor = 0; 675*7c478bd9Sstevel@tonic-gate if (sp_entry->spe_sp_data != NULL) { 676*7c478bd9Sstevel@tonic-gate free(sp_entry->spe_sp_data); 677*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_data = NULL; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate free(sp_entry); 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate static int 683*7c478bd9Sstevel@tonic-gate datadm_str_match(char *s1, char *s2) 684*7c478bd9Sstevel@tonic-gate { 685*7c478bd9Sstevel@tonic-gate if (s1 == NULL || s2 == NULL) { 686*7c478bd9Sstevel@tonic-gate if (s1 != s2) { 687*7c478bd9Sstevel@tonic-gate return (0); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate } else { 690*7c478bd9Sstevel@tonic-gate if (strcmp(s1, s2) != 0) { 691*7c478bd9Sstevel@tonic-gate return (0); 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate return (1); 695*7c478bd9Sstevel@tonic-gate } 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate static int 698*7c478bd9Sstevel@tonic-gate datadm_version_match(datadm_version_t *v1, datadm_version_t *v2) 699*7c478bd9Sstevel@tonic-gate { 700*7c478bd9Sstevel@tonic-gate if (!datadm_str_match(v1->dv_name, v2->dv_name)) { 701*7c478bd9Sstevel@tonic-gate return (0); 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate if (v1->dv_major != v2->dv_major) { 704*7c478bd9Sstevel@tonic-gate return (0); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate if (v1->dv_minor != v2->dv_minor) { 707*7c478bd9Sstevel@tonic-gate return (0); 708*7c478bd9Sstevel@tonic-gate } 709*7c478bd9Sstevel@tonic-gate return (1); 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate static int 713*7c478bd9Sstevel@tonic-gate datadm_sp_entry_match(datadm_sp_entry_t *sp1, datadm_sp_entry_t *sp2) 714*7c478bd9Sstevel@tonic-gate { 715*7c478bd9Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_devname, sp2->spe_devname)) { 716*7c478bd9Sstevel@tonic-gate return (0); 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_api_version, 719*7c478bd9Sstevel@tonic-gate &sp2->spe_api_version)) { 720*7c478bd9Sstevel@tonic-gate return (0); 721*7c478bd9Sstevel@tonic-gate } 722*7c478bd9Sstevel@tonic-gate if (sp1->spe_threadsafe != sp2->spe_threadsafe) { 723*7c478bd9Sstevel@tonic-gate return (0); 724*7c478bd9Sstevel@tonic-gate } 725*7c478bd9Sstevel@tonic-gate if (sp2->spe_default != sp2->spe_default) { 726*7c478bd9Sstevel@tonic-gate return (0); 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_libpath, sp2->spe_libpath)) { 729*7c478bd9Sstevel@tonic-gate return (0); 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate if (!datadm_version_match(&sp1->spe_sp_version, 732*7c478bd9Sstevel@tonic-gate &sp2->spe_sp_version)) { 733*7c478bd9Sstevel@tonic-gate return (0); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate if (!datadm_str_match(sp1->spe_sp_data, sp2->spe_sp_data)) { 736*7c478bd9Sstevel@tonic-gate return (0); 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate return (1); 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate static datadm_ia_entry_t * 742*7c478bd9Sstevel@tonic-gate datadm_alloc_ia_entry(void) 743*7c478bd9Sstevel@tonic-gate { 744*7c478bd9Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate ia_entry = (datadm_ia_entry_t *)malloc(sizeof (*ia_entry)); 747*7c478bd9Sstevel@tonic-gate if (ia_entry == NULL) { 748*7c478bd9Sstevel@tonic-gate return (NULL); 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate bzero(ia_entry, sizeof (*ia_entry)); 751*7c478bd9Sstevel@tonic-gate return (ia_entry); 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate static void 755*7c478bd9Sstevel@tonic-gate datadm_free_ia_entry(datadm_ia_entry_t *ia_entry) 756*7c478bd9Sstevel@tonic-gate { 757*7c478bd9Sstevel@tonic-gate free(ia_entry); 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate static datadm_hca_entry_t * 761*7c478bd9Sstevel@tonic-gate datadm_alloc_hca_entry(void) 762*7c478bd9Sstevel@tonic-gate { 763*7c478bd9Sstevel@tonic-gate datadm_hca_entry_t *hca_entry; 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate hca_entry = (datadm_hca_entry_t *)malloc(sizeof (*hca_entry)); 766*7c478bd9Sstevel@tonic-gate if (hca_entry == NULL) { 767*7c478bd9Sstevel@tonic-gate return (NULL); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate bzero(hca_entry, sizeof (*hca_entry)); 770*7c478bd9Sstevel@tonic-gate return (hca_entry); 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate static void 774*7c478bd9Sstevel@tonic-gate datadm_free_hca_entry(datadm_hca_entry_t *hca_entry) 775*7c478bd9Sstevel@tonic-gate { 776*7c478bd9Sstevel@tonic-gate if (hca_entry->he_name != NULL) { 777*7c478bd9Sstevel@tonic-gate free(hca_entry->he_name); 778*7c478bd9Sstevel@tonic-gate hca_entry->he_name = NULL; 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_entry->he_sp_list, 781*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_sp_entry); 782*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_entry->he_ia_list, 783*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_ia_entry); 784*7c478bd9Sstevel@tonic-gate free(hca_entry); 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate 787*7c478bd9Sstevel@tonic-gate static int 788*7c478bd9Sstevel@tonic-gate datadm_hca_entry_match(datadm_hca_entry_t *h1, datadm_hca_entry_t *h2) 789*7c478bd9Sstevel@tonic-gate { 790*7c478bd9Sstevel@tonic-gate if (!datadm_str_match(h1->he_name, h2->he_name)) { 791*7c478bd9Sstevel@tonic-gate return (0); 792*7c478bd9Sstevel@tonic-gate } 793*7c478bd9Sstevel@tonic-gate return (1); 794*7c478bd9Sstevel@tonic-gate } 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate static int 797*7c478bd9Sstevel@tonic-gate datadm_hca_entry_find(datadm_hca_entry_t *h1, datadm_hca_find_t *hf) 798*7c478bd9Sstevel@tonic-gate { 799*7c478bd9Sstevel@tonic-gate if (datadm_str_match(h1->he_name, hf->hf_sp_entry->spe_devname)) { 800*7c478bd9Sstevel@tonic-gate hf->hf_hca_entry = h1; 801*7c478bd9Sstevel@tonic-gate return (1); 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate return (0); 804*7c478bd9Sstevel@tonic-gate } 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate static int 807*7c478bd9Sstevel@tonic-gate datadm_ia_entry_find(datadm_ia_entry_t *i1, datadm_ia_find_t *iaf) 808*7c478bd9Sstevel@tonic-gate { 809*7c478bd9Sstevel@tonic-gate if (i1->iae_devnum == iaf->if_ia_devnum) { 810*7c478bd9Sstevel@tonic-gate iaf->if_ia_entry = i1; 811*7c478bd9Sstevel@tonic-gate return (1); 812*7c478bd9Sstevel@tonic-gate } 813*7c478bd9Sstevel@tonic-gate return (0); 814*7c478bd9Sstevel@tonic-gate } 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate static datadm_cmnt_entry_t * 817*7c478bd9Sstevel@tonic-gate datadm_alloc_cmnt_entry(void) 818*7c478bd9Sstevel@tonic-gate { 819*7c478bd9Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry; 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate cmnt_entry = (datadm_cmnt_entry_t *)malloc(sizeof (*cmnt_entry)); 822*7c478bd9Sstevel@tonic-gate if (cmnt_entry == NULL) { 823*7c478bd9Sstevel@tonic-gate return (NULL); 824*7c478bd9Sstevel@tonic-gate } 825*7c478bd9Sstevel@tonic-gate bzero(cmnt_entry, sizeof (*cmnt_entry)); 826*7c478bd9Sstevel@tonic-gate return (cmnt_entry); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate static void 830*7c478bd9Sstevel@tonic-gate datadm_free_cmnt_entry(datadm_cmnt_entry_t *cmnt_entry) 831*7c478bd9Sstevel@tonic-gate { 832*7c478bd9Sstevel@tonic-gate if (cmnt_entry->cmnt_line != NULL) { 833*7c478bd9Sstevel@tonic-gate free(cmnt_entry->cmnt_line); 834*7c478bd9Sstevel@tonic-gate cmnt_entry->cmnt_line = NULL; 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate free(cmnt_entry); 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate /* 840*7c478bd9Sstevel@tonic-gate * tokenizes a line and strips off the quotes from quoted strings 841*7c478bd9Sstevel@tonic-gate */ 842*7c478bd9Sstevel@tonic-gate static int 843*7c478bd9Sstevel@tonic-gate datadm_parse_line(char *line_buf, char *tokens[], int *token_count) 844*7c478bd9Sstevel@tonic-gate { 845*7c478bd9Sstevel@tonic-gate int len, i; 846*7c478bd9Sstevel@tonic-gate int count = 0; 847*7c478bd9Sstevel@tonic-gate char *start = NULL; 848*7c478bd9Sstevel@tonic-gate 849*7c478bd9Sstevel@tonic-gate /* the line must not be longer than DATADM_LINESZ */ 850*7c478bd9Sstevel@tonic-gate len = strlen(line_buf); 851*7c478bd9Sstevel@tonic-gate if (line_buf[len - 1] != '\n') { 852*7c478bd9Sstevel@tonic-gate return (-1); 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate /* discard blank lines and comments */ 855*7c478bd9Sstevel@tonic-gate if (len == 1) { 856*7c478bd9Sstevel@tonic-gate *token_count = 0; 857*7c478bd9Sstevel@tonic-gate return (0); 858*7c478bd9Sstevel@tonic-gate } 859*7c478bd9Sstevel@tonic-gate if (len >= 2 && line_buf[0] == '#') { 860*7c478bd9Sstevel@tonic-gate *token_count = 0; 861*7c478bd9Sstevel@tonic-gate return (0); 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate /* removes the new line */ 864*7c478bd9Sstevel@tonic-gate line_buf[len - 1] = '\0'; 865*7c478bd9Sstevel@tonic-gate len--; 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 868*7c478bd9Sstevel@tonic-gate if (start != NULL) { 869*7c478bd9Sstevel@tonic-gate /* 870*7c478bd9Sstevel@tonic-gate * start points to the start of 871*7c478bd9Sstevel@tonic-gate * a new token. if start is '"', 872*7c478bd9Sstevel@tonic-gate * we should expect a quoted 873*7c478bd9Sstevel@tonic-gate * string. 874*7c478bd9Sstevel@tonic-gate */ 875*7c478bd9Sstevel@tonic-gate if (*start == '\"') { 876*7c478bd9Sstevel@tonic-gate /* 877*7c478bd9Sstevel@tonic-gate * keep scanning until we 878*7c478bd9Sstevel@tonic-gate * hit the end quote. 879*7c478bd9Sstevel@tonic-gate */ 880*7c478bd9Sstevel@tonic-gate if (line_buf[i] != '\"') { 881*7c478bd9Sstevel@tonic-gate continue; 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate /* 884*7c478bd9Sstevel@tonic-gate * skip past the start quote 885*7c478bd9Sstevel@tonic-gate */ 886*7c478bd9Sstevel@tonic-gate start++; 887*7c478bd9Sstevel@tonic-gate } else { 888*7c478bd9Sstevel@tonic-gate /* 889*7c478bd9Sstevel@tonic-gate * our token is not a quoted 890*7c478bd9Sstevel@tonic-gate * string. our token ends only 891*7c478bd9Sstevel@tonic-gate * when we hit a whitespace. 892*7c478bd9Sstevel@tonic-gate */ 893*7c478bd9Sstevel@tonic-gate if (!isspace(line_buf[i])) { 894*7c478bd9Sstevel@tonic-gate continue; 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate } 897*7c478bd9Sstevel@tonic-gate /* 898*7c478bd9Sstevel@tonic-gate * nullify the end quote (if any) 899*7c478bd9Sstevel@tonic-gate * and update the tokens array. 900*7c478bd9Sstevel@tonic-gate */ 901*7c478bd9Sstevel@tonic-gate line_buf[i] = '\0'; 902*7c478bd9Sstevel@tonic-gate tokens[count] = start; 903*7c478bd9Sstevel@tonic-gate start = NULL; 904*7c478bd9Sstevel@tonic-gate count++; 905*7c478bd9Sstevel@tonic-gate } else { 906*7c478bd9Sstevel@tonic-gate /* 907*7c478bd9Sstevel@tonic-gate * skip whitespaces 908*7c478bd9Sstevel@tonic-gate */ 909*7c478bd9Sstevel@tonic-gate if (isspace(line_buf[i])) { 910*7c478bd9Sstevel@tonic-gate continue; 911*7c478bd9Sstevel@tonic-gate } else { 912*7c478bd9Sstevel@tonic-gate start = &line_buf[i]; 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate if (count == DATADM_MAX_TOKENS) { 916*7c478bd9Sstevel@tonic-gate start = NULL; 917*7c478bd9Sstevel@tonic-gate break; 918*7c478bd9Sstevel@tonic-gate } 919*7c478bd9Sstevel@tonic-gate } 920*7c478bd9Sstevel@tonic-gate if (start != NULL) { 921*7c478bd9Sstevel@tonic-gate tokens[count] = start; 922*7c478bd9Sstevel@tonic-gate start = NULL; 923*7c478bd9Sstevel@tonic-gate count++; 924*7c478bd9Sstevel@tonic-gate } 925*7c478bd9Sstevel@tonic-gate *token_count = count; 926*7c478bd9Sstevel@tonic-gate return (0); 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate /* 930*7c478bd9Sstevel@tonic-gate * attempts to save sp_entry into hca_list. 931*7c478bd9Sstevel@tonic-gate * becomes no-op if sp entry already exists. 932*7c478bd9Sstevel@tonic-gate * new hca entries and ia entries are created as needed. 933*7c478bd9Sstevel@tonic-gate */ 934*7c478bd9Sstevel@tonic-gate static int 935*7c478bd9Sstevel@tonic-gate datadm_process_sp_entry(datadm_list_t *hca_list, datadm_sp_entry_t *sp_entry, 936*7c478bd9Sstevel@tonic-gate int ia_devnum) 937*7c478bd9Sstevel@tonic-gate { 938*7c478bd9Sstevel@tonic-gate datadm_hca_find_t hca_find; 939*7c478bd9Sstevel@tonic-gate datadm_ia_find_t ia_find; 940*7c478bd9Sstevel@tonic-gate datadm_hca_entry_t *hca_entry; 941*7c478bd9Sstevel@tonic-gate 942*7c478bd9Sstevel@tonic-gate hca_find.hf_sp_entry = sp_entry; 943*7c478bd9Sstevel@tonic-gate hca_find.hf_hca_entry = NULL; 944*7c478bd9Sstevel@tonic-gate (void) datadm_walk_list(hca_list, (int (*)(datadm_entry_t *, void *)) 945*7c478bd9Sstevel@tonic-gate datadm_hca_entry_find, (void *)&hca_find); 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate if (hca_find.hf_hca_entry == NULL) { 948*7c478bd9Sstevel@tonic-gate int dlen; 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate /* 951*7c478bd9Sstevel@tonic-gate * hca_entry not found, need to create 952*7c478bd9Sstevel@tonic-gate * and insert one. 953*7c478bd9Sstevel@tonic-gate */ 954*7c478bd9Sstevel@tonic-gate hca_entry = datadm_alloc_hca_entry(); 955*7c478bd9Sstevel@tonic-gate if (hca_entry == NULL) { 956*7c478bd9Sstevel@tonic-gate return (-1); 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate dlen = strlen(sp_entry->spe_devname); 959*7c478bd9Sstevel@tonic-gate hca_entry->he_name = (char *)malloc(dlen + 1); 960*7c478bd9Sstevel@tonic-gate if (hca_entry->he_name == NULL) { 961*7c478bd9Sstevel@tonic-gate datadm_free_hca_entry(hca_entry); 962*7c478bd9Sstevel@tonic-gate return (-1); 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate (void) strcpy(hca_entry->he_name, sp_entry->spe_devname); 965*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(hca_list, (datadm_entry_t *)hca_entry); 966*7c478bd9Sstevel@tonic-gate } else { 967*7c478bd9Sstevel@tonic-gate hca_entry = hca_find.hf_hca_entry; 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate if (ia_devnum == -1) { 970*7c478bd9Sstevel@tonic-gate goto put_sp_entry; 971*7c478bd9Sstevel@tonic-gate } 972*7c478bd9Sstevel@tonic-gate ia_find.if_ia_devnum = ia_devnum; 973*7c478bd9Sstevel@tonic-gate ia_find.if_ia_entry = NULL; 974*7c478bd9Sstevel@tonic-gate (void) datadm_walk_list(&hca_entry->he_ia_list, 975*7c478bd9Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_ia_entry_find, &ia_find); 976*7c478bd9Sstevel@tonic-gate 977*7c478bd9Sstevel@tonic-gate if (ia_find.if_ia_entry == NULL) { 978*7c478bd9Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate /* 981*7c478bd9Sstevel@tonic-gate * ia_entry not found, need to create 982*7c478bd9Sstevel@tonic-gate * and insert one. 983*7c478bd9Sstevel@tonic-gate */ 984*7c478bd9Sstevel@tonic-gate ia_entry = datadm_alloc_ia_entry(); 985*7c478bd9Sstevel@tonic-gate if (ia_entry == NULL) { 986*7c478bd9Sstevel@tonic-gate return (-1); 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate ia_entry->iae_devnum = ia_devnum; 989*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_ia_list, 990*7c478bd9Sstevel@tonic-gate (datadm_entry_t *)ia_entry); 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate put_sp_entry:; 994*7c478bd9Sstevel@tonic-gate 995*7c478bd9Sstevel@tonic-gate if (datadm_walk_list(&hca_entry->he_sp_list, 996*7c478bd9Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_sp_entry_match, 997*7c478bd9Sstevel@tonic-gate (void *)sp_entry)) { 998*7c478bd9Sstevel@tonic-gate return (1); 999*7c478bd9Sstevel@tonic-gate } else { 1000*7c478bd9Sstevel@tonic-gate /* 1001*7c478bd9Sstevel@tonic-gate * only insert sp_entry if it is not found. 1002*7c478bd9Sstevel@tonic-gate */ 1003*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(&hca_entry->he_sp_list, 1004*7c478bd9Sstevel@tonic-gate (datadm_entry_t *)sp_entry); 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate return (0); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate /* 1010*7c478bd9Sstevel@tonic-gate * parses service_provider.conf 1011*7c478bd9Sstevel@tonic-gate */ 1012*7c478bd9Sstevel@tonic-gate static int 1013*7c478bd9Sstevel@tonic-gate datadm_parse_sp_conf(datadm_list_t *hca_list) 1014*7c478bd9Sstevel@tonic-gate { 1015*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 1016*7c478bd9Sstevel@tonic-gate FILE *sp_file; 1017*7c478bd9Sstevel@tonic-gate char *sp_conf = datadm_args.da_sp_conf; 1018*7c478bd9Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS]; 1019*7c478bd9Sstevel@tonic-gate char line_buf[DATADM_LINESZ]; 1020*7c478bd9Sstevel@tonic-gate int retval = 0; 1021*7c478bd9Sstevel@tonic-gate int token_count = 0; 1022*7c478bd9Sstevel@tonic-gate int line_count = 0; 1023*7c478bd9Sstevel@tonic-gate 1024*7c478bd9Sstevel@tonic-gate sp_file = fopen(sp_conf, "r"); 1025*7c478bd9Sstevel@tonic-gate if (sp_file == NULL) { 1026*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1027*7c478bd9Sstevel@tonic-gate gettext("datadm: cannot open %s\n"), sp_conf); 1028*7c478bd9Sstevel@tonic-gate return (-1); 1029*7c478bd9Sstevel@tonic-gate } 1030*7c478bd9Sstevel@tonic-gate 1031*7c478bd9Sstevel@tonic-gate for (;;) { 1032*7c478bd9Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ); 1033*7c478bd9Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, sp_file) == NULL) { 1034*7c478bd9Sstevel@tonic-gate break; 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate token_count = 0; 1037*7c478bd9Sstevel@tonic-gate line_count++; 1038*7c478bd9Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count); 1039*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1040*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1041*7c478bd9Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"), 1042*7c478bd9Sstevel@tonic-gate sp_conf, line_count, DATADM_LINESZ); 1043*7c478bd9Sstevel@tonic-gate break; 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate if (token_count == 0) continue; 1046*7c478bd9Sstevel@tonic-gate if (token_count == DATADM_NUM_SP_TOKENS) { 1047*7c478bd9Sstevel@tonic-gate int i = 0; 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry(); 1050*7c478bd9Sstevel@tonic-gate if (sp_entry == NULL) { 1051*7c478bd9Sstevel@tonic-gate retval = -1; 1052*7c478bd9Sstevel@tonic-gate break; 1053*7c478bd9Sstevel@tonic-gate } 1054*7c478bd9Sstevel@tonic-gate 1055*7c478bd9Sstevel@tonic-gate /* 1056*7c478bd9Sstevel@tonic-gate * sp_entry gets filled incrementally by 1057*7c478bd9Sstevel@tonic-gate * each parsing function 1058*7c478bd9Sstevel@tonic-gate */ 1059*7c478bd9Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_SP_TOKENS && 1060*7c478bd9Sstevel@tonic-gate retval == 0; i++) { 1061*7c478bd9Sstevel@tonic-gate retval = (*datadm_sp_parse_funcs[i]) 1062*7c478bd9Sstevel@tonic-gate (tokens[i], (void *)sp_entry); 1063*7c478bd9Sstevel@tonic-gate } 1064*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1065*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1066*7c478bd9Sstevel@tonic-gate "datadm: parse error: %s, " 1067*7c478bd9Sstevel@tonic-gate "line %d, token: %s\n"), 1068*7c478bd9Sstevel@tonic-gate sp_conf, line_count, tokens[i - 1]); 1069*7c478bd9Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1070*7c478bd9Sstevel@tonic-gate sp_entry = NULL; 1071*7c478bd9Sstevel@tonic-gate break; 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate retval = datadm_process_sp_entry(hca_list, 1075*7c478bd9Sstevel@tonic-gate sp_entry, -1); 1076*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1077*7c478bd9Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1078*7c478bd9Sstevel@tonic-gate if (retval == 1) { 1079*7c478bd9Sstevel@tonic-gate retval = 0; 1080*7c478bd9Sstevel@tonic-gate } else { 1081*7c478bd9Sstevel@tonic-gate break; 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate } 1084*7c478bd9Sstevel@tonic-gate } else { 1085*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1086*7c478bd9Sstevel@tonic-gate "datadm: parse error: %s, line %d, " 1087*7c478bd9Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), sp_conf, 1088*7c478bd9Sstevel@tonic-gate line_count, token_count, DATADM_NUM_SP_TOKENS); 1089*7c478bd9Sstevel@tonic-gate retval = -1; 1090*7c478bd9Sstevel@tonic-gate break; 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate } 1093*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1094*7c478bd9Sstevel@tonic-gate datadm_free_list(hca_list, 1095*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1096*7c478bd9Sstevel@tonic-gate } 1097*7c478bd9Sstevel@tonic-gate (void) fclose(sp_file); 1098*7c478bd9Sstevel@tonic-gate return (retval); 1099*7c478bd9Sstevel@tonic-gate } 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate /* 1102*7c478bd9Sstevel@tonic-gate * parses dat.conf 1103*7c478bd9Sstevel@tonic-gate */ 1104*7c478bd9Sstevel@tonic-gate static int 1105*7c478bd9Sstevel@tonic-gate datadm_parse_dat_conf(datadm_list_t *hca_list) 1106*7c478bd9Sstevel@tonic-gate { 1107*7c478bd9Sstevel@tonic-gate boolean_t save_header = B_TRUE; 1108*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *sp_entry; 1109*7c478bd9Sstevel@tonic-gate FILE *dat_file; 1110*7c478bd9Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf; 1111*7c478bd9Sstevel@tonic-gate char *tokens[DATADM_MAX_TOKENS]; 1112*7c478bd9Sstevel@tonic-gate char line_buf[DATADM_LINESZ]; 1113*7c478bd9Sstevel@tonic-gate int retval = 0; 1114*7c478bd9Sstevel@tonic-gate int token_count = 0; 1115*7c478bd9Sstevel@tonic-gate int line_count = 0; 1116*7c478bd9Sstevel@tonic-gate 1117*7c478bd9Sstevel@tonic-gate dat_file = fopen(dat_conf, "r"); 1118*7c478bd9Sstevel@tonic-gate if (dat_file == NULL) { 1119*7c478bd9Sstevel@tonic-gate /* dat.conf not existing is not an error for OP_ADD */ 1120*7c478bd9Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_ADD) { 1121*7c478bd9Sstevel@tonic-gate return (0); 1122*7c478bd9Sstevel@tonic-gate } 1123*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("datadm: cannot open %s\n"), 1124*7c478bd9Sstevel@tonic-gate dat_conf); 1125*7c478bd9Sstevel@tonic-gate return (-1); 1126*7c478bd9Sstevel@tonic-gate } 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate for (;;) { 1129*7c478bd9Sstevel@tonic-gate bzero(line_buf, DATADM_LINESZ); 1130*7c478bd9Sstevel@tonic-gate if (fgets(line_buf, DATADM_LINESZ, dat_file) == NULL) { 1131*7c478bd9Sstevel@tonic-gate break; 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate token_count = 0; 1134*7c478bd9Sstevel@tonic-gate line_count++; 1135*7c478bd9Sstevel@tonic-gate retval = datadm_parse_line(line_buf, tokens, &token_count); 1136*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1137*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1138*7c478bd9Sstevel@tonic-gate "datadm: %s: line %d exceeded max length %d\n"), 1139*7c478bd9Sstevel@tonic-gate dat_conf, line_count, DATADM_LINESZ); 1140*7c478bd9Sstevel@tonic-gate break; 1141*7c478bd9Sstevel@tonic-gate } 1142*7c478bd9Sstevel@tonic-gate if (token_count == 0) { 1143*7c478bd9Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt_entry; 1144*7c478bd9Sstevel@tonic-gate int cmnt_len; 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate /* 1147*7c478bd9Sstevel@tonic-gate * comments are saved only if they are 1148*7c478bd9Sstevel@tonic-gate * at the top of dat.conf. 1149*7c478bd9Sstevel@tonic-gate */ 1150*7c478bd9Sstevel@tonic-gate if (!save_header) continue; 1151*7c478bd9Sstevel@tonic-gate cmnt_entry = datadm_alloc_cmnt_entry(); 1152*7c478bd9Sstevel@tonic-gate if (cmnt_entry == NULL) { 1153*7c478bd9Sstevel@tonic-gate perror("datadm: malloc"); 1154*7c478bd9Sstevel@tonic-gate retval = -1; 1155*7c478bd9Sstevel@tonic-gate break; 1156*7c478bd9Sstevel@tonic-gate } 1157*7c478bd9Sstevel@tonic-gate cmnt_len = strlen(line_buf); 1158*7c478bd9Sstevel@tonic-gate cmnt_entry->cmnt_line = (char *)malloc(cmnt_len + 1); 1159*7c478bd9Sstevel@tonic-gate if (cmnt_entry->cmnt_line == NULL) { 1160*7c478bd9Sstevel@tonic-gate perror("datadm: malloc"); 1161*7c478bd9Sstevel@tonic-gate datadm_free_cmnt_entry(cmnt_entry); 1162*7c478bd9Sstevel@tonic-gate retval = -1; 1163*7c478bd9Sstevel@tonic-gate break; 1164*7c478bd9Sstevel@tonic-gate } 1165*7c478bd9Sstevel@tonic-gate (void) strncpy(cmnt_entry->cmnt_line, 1166*7c478bd9Sstevel@tonic-gate line_buf, cmnt_len); 1167*7c478bd9Sstevel@tonic-gate cmnt_entry->cmnt_line[cmnt_len] = '\0'; 1168*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(&datadm_conf_header, 1169*7c478bd9Sstevel@tonic-gate (datadm_entry_t *)cmnt_entry); 1170*7c478bd9Sstevel@tonic-gate continue; 1171*7c478bd9Sstevel@tonic-gate } 1172*7c478bd9Sstevel@tonic-gate if (token_count == DATADM_NUM_DAT_TOKENS) { 1173*7c478bd9Sstevel@tonic-gate int i = 0; 1174*7c478bd9Sstevel@tonic-gate int ia_devnum = -1; 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate /* 1177*7c478bd9Sstevel@tonic-gate * we stop saving comment lines once 1178*7c478bd9Sstevel@tonic-gate * we see the first valid line. 1179*7c478bd9Sstevel@tonic-gate */ 1180*7c478bd9Sstevel@tonic-gate save_header = B_FALSE; 1181*7c478bd9Sstevel@tonic-gate sp_entry = datadm_alloc_sp_entry(); 1182*7c478bd9Sstevel@tonic-gate if (sp_entry == NULL) { 1183*7c478bd9Sstevel@tonic-gate retval = -1; 1184*7c478bd9Sstevel@tonic-gate break; 1185*7c478bd9Sstevel@tonic-gate } 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate /* 1188*7c478bd9Sstevel@tonic-gate * sp_entry gets filled incrementally by 1189*7c478bd9Sstevel@tonic-gate * each parsing function 1190*7c478bd9Sstevel@tonic-gate */ 1191*7c478bd9Sstevel@tonic-gate for (i = 0; i < DATADM_NUM_DAT_TOKENS && 1192*7c478bd9Sstevel@tonic-gate retval == 0; i++) { 1193*7c478bd9Sstevel@tonic-gate void *arg; 1194*7c478bd9Sstevel@tonic-gate 1195*7c478bd9Sstevel@tonic-gate if (i == 0) { 1196*7c478bd9Sstevel@tonic-gate /* 1197*7c478bd9Sstevel@tonic-gate * the first token (ia name) 1198*7c478bd9Sstevel@tonic-gate * does not belong to an 1199*7c478bd9Sstevel@tonic-gate * sp_entry 1200*7c478bd9Sstevel@tonic-gate */ 1201*7c478bd9Sstevel@tonic-gate arg = (void *)&ia_devnum; 1202*7c478bd9Sstevel@tonic-gate } else { 1203*7c478bd9Sstevel@tonic-gate arg = (void *)sp_entry; 1204*7c478bd9Sstevel@tonic-gate } 1205*7c478bd9Sstevel@tonic-gate retval = (*datadm_dat_parse_funcs[i]) 1206*7c478bd9Sstevel@tonic-gate (tokens[i], arg); 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1209*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1210*7c478bd9Sstevel@tonic-gate "datadm: parse error: %s, " 1211*7c478bd9Sstevel@tonic-gate "line %d, token: %s\n"), dat_conf, 1212*7c478bd9Sstevel@tonic-gate line_count, tokens[i - 1]); 1213*7c478bd9Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1214*7c478bd9Sstevel@tonic-gate sp_entry = NULL; 1215*7c478bd9Sstevel@tonic-gate break; 1216*7c478bd9Sstevel@tonic-gate } 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate /* 1219*7c478bd9Sstevel@tonic-gate * we ignore the ibds in dat.conf if we are 1220*7c478bd9Sstevel@tonic-gate * doing update 1221*7c478bd9Sstevel@tonic-gate */ 1222*7c478bd9Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_UPDATE) { 1223*7c478bd9Sstevel@tonic-gate ia_devnum = -1; 1224*7c478bd9Sstevel@tonic-gate } 1225*7c478bd9Sstevel@tonic-gate retval = datadm_process_sp_entry(hca_list, sp_entry, 1226*7c478bd9Sstevel@tonic-gate ia_devnum); 1227*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1228*7c478bd9Sstevel@tonic-gate datadm_free_sp_entry(sp_entry); 1229*7c478bd9Sstevel@tonic-gate if (retval == 1) { 1230*7c478bd9Sstevel@tonic-gate retval = 0; 1231*7c478bd9Sstevel@tonic-gate } else { 1232*7c478bd9Sstevel@tonic-gate break; 1233*7c478bd9Sstevel@tonic-gate } 1234*7c478bd9Sstevel@tonic-gate } 1235*7c478bd9Sstevel@tonic-gate } else { 1236*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1237*7c478bd9Sstevel@tonic-gate "datadm: parse error: %s, line %d, " 1238*7c478bd9Sstevel@tonic-gate "# of tokens: %d, expected %d\n"), dat_conf, 1239*7c478bd9Sstevel@tonic-gate line_count, token_count, DATADM_NUM_DAT_TOKENS); 1240*7c478bd9Sstevel@tonic-gate retval = -1; 1241*7c478bd9Sstevel@tonic-gate break; 1242*7c478bd9Sstevel@tonic-gate } 1243*7c478bd9Sstevel@tonic-gate } 1244*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1245*7c478bd9Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1246*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1247*7c478bd9Sstevel@tonic-gate datadm_free_list(hca_list, 1248*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate (void) fclose(dat_file); 1251*7c478bd9Sstevel@tonic-gate return (retval); 1252*7c478bd9Sstevel@tonic-gate } 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate /* 1255*7c478bd9Sstevel@tonic-gate * discovers all ibd devices under a particular hca 1256*7c478bd9Sstevel@tonic-gate */ 1257*7c478bd9Sstevel@tonic-gate static int 1258*7c478bd9Sstevel@tonic-gate datadm_fill_ia_list(datadm_hca_entry_t *hca, datadm_fill_ia_list_t *args) 1259*7c478bd9Sstevel@tonic-gate { 1260*7c478bd9Sstevel@tonic-gate di_node_t root_node; 1261*7c478bd9Sstevel@tonic-gate di_node_t hca_node; 1262*7c478bd9Sstevel@tonic-gate int retval = 0; 1263*7c478bd9Sstevel@tonic-gate int sv4, sv6; 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate root_node = args->ia_root_node; 1266*7c478bd9Sstevel@tonic-gate sv4 = args->ia_sock_fd_v4; 1267*7c478bd9Sstevel@tonic-gate sv6 = args->ia_sock_fd_v6; 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate hca_node = di_drv_first_node(hca->he_name, root_node); 1270*7c478bd9Sstevel@tonic-gate if (hca_node == DI_NODE_NIL) { 1271*7c478bd9Sstevel@tonic-gate return (0); 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate while (hca_node != DI_NODE_NIL) { 1274*7c478bd9Sstevel@tonic-gate di_node_t ibd_node; 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate ibd_node = di_drv_first_node(DATADM_IA_NAME, hca_node); 1277*7c478bd9Sstevel@tonic-gate while (ibd_node != DI_NODE_NIL) { 1278*7c478bd9Sstevel@tonic-gate datadm_ia_find_t ia_find; 1279*7c478bd9Sstevel@tonic-gate datadm_ia_entry_t *ia_entry; 1280*7c478bd9Sstevel@tonic-gate struct lifreq req; 1281*7c478bd9Sstevel@tonic-gate int devnum, rval; 1282*7c478bd9Sstevel@tonic-gate 1283*7c478bd9Sstevel@tonic-gate devnum = di_instance(ibd_node); 1284*7c478bd9Sstevel@tonic-gate if (devnum == -1) { 1285*7c478bd9Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1286*7c478bd9Sstevel@tonic-gate continue; 1287*7c478bd9Sstevel@tonic-gate } 1288*7c478bd9Sstevel@tonic-gate 1289*7c478bd9Sstevel@tonic-gate (void) snprintf(req.lifr_name, sizeof (req.lifr_name), 1290*7c478bd9Sstevel@tonic-gate "%s%d", DATADM_IA_NAME, devnum); 1291*7c478bd9Sstevel@tonic-gate /* 1292*7c478bd9Sstevel@tonic-gate * we don't really need to know the ip address. 1293*7c478bd9Sstevel@tonic-gate * we just want to check if the device is plumbed 1294*7c478bd9Sstevel@tonic-gate * or not. 1295*7c478bd9Sstevel@tonic-gate */ 1296*7c478bd9Sstevel@tonic-gate rval = ioctl(sv4, SIOCGLIFADDR, (caddr_t)&req); 1297*7c478bd9Sstevel@tonic-gate if (rval != 0) { 1298*7c478bd9Sstevel@tonic-gate /* 1299*7c478bd9Sstevel@tonic-gate * we try v6 if the v4 address isn't found. 1300*7c478bd9Sstevel@tonic-gate */ 1301*7c478bd9Sstevel@tonic-gate rval = ioctl(sv6, SIOCGLIFADDR, (caddr_t)&req); 1302*7c478bd9Sstevel@tonic-gate if (rval != 0) { 1303*7c478bd9Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1304*7c478bd9Sstevel@tonic-gate continue; 1305*7c478bd9Sstevel@tonic-gate } 1306*7c478bd9Sstevel@tonic-gate } 1307*7c478bd9Sstevel@tonic-gate ia_find.if_ia_devnum = devnum; 1308*7c478bd9Sstevel@tonic-gate ia_find.if_ia_entry = NULL; 1309*7c478bd9Sstevel@tonic-gate (void) datadm_walk_list(&hca->he_ia_list, 1310*7c478bd9Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *)) 1311*7c478bd9Sstevel@tonic-gate datadm_ia_entry_find, &ia_find); 1312*7c478bd9Sstevel@tonic-gate 1313*7c478bd9Sstevel@tonic-gate if (ia_find.if_ia_entry == NULL) { 1314*7c478bd9Sstevel@tonic-gate /* 1315*7c478bd9Sstevel@tonic-gate * we insert an ia entry only if 1316*7c478bd9Sstevel@tonic-gate * it is unique. 1317*7c478bd9Sstevel@tonic-gate */ 1318*7c478bd9Sstevel@tonic-gate ia_entry = datadm_alloc_ia_entry(); 1319*7c478bd9Sstevel@tonic-gate if (ia_entry == NULL) { 1320*7c478bd9Sstevel@tonic-gate retval = -1; 1321*7c478bd9Sstevel@tonic-gate break; 1322*7c478bd9Sstevel@tonic-gate } 1323*7c478bd9Sstevel@tonic-gate ia_entry->iae_devnum = devnum; 1324*7c478bd9Sstevel@tonic-gate datadm_enqueue_entry(&hca->he_ia_list, 1325*7c478bd9Sstevel@tonic-gate (datadm_entry_t *)ia_entry); 1326*7c478bd9Sstevel@tonic-gate } else { 1327*7c478bd9Sstevel@tonic-gate ia_entry = ia_find.if_ia_entry; 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate ibd_node = di_drv_next_node(ibd_node); 1330*7c478bd9Sstevel@tonic-gate } 1331*7c478bd9Sstevel@tonic-gate hca_node = di_drv_next_node(hca_node); 1332*7c478bd9Sstevel@tonic-gate } 1333*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1334*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca->he_ia_list, 1335*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_ia_entry); 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate return (0); 1338*7c478bd9Sstevel@tonic-gate } 1339*7c478bd9Sstevel@tonic-gate 1340*7c478bd9Sstevel@tonic-gate /* 1341*7c478bd9Sstevel@tonic-gate * used by OP_REMOVE to invalidate common sp entries between hl1 and hl2. 1342*7c478bd9Sstevel@tonic-gate * invalid sp entries will be ignored by datadm_generate_dat_conf. 1343*7c478bd9Sstevel@tonic-gate */ 1344*7c478bd9Sstevel@tonic-gate static void 1345*7c478bd9Sstevel@tonic-gate datadm_invalidate_common_sp_entries(datadm_list_t *hl1, datadm_list_t *hl2) 1346*7c478bd9Sstevel@tonic-gate { 1347*7c478bd9Sstevel@tonic-gate datadm_entry_t *he1, *he2; 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate he1 = hl1->dl_head; 1350*7c478bd9Sstevel@tonic-gate while (he1 != NULL) { 1351*7c478bd9Sstevel@tonic-gate he2 = hl2->dl_head; 1352*7c478bd9Sstevel@tonic-gate while (he2 != NULL) { 1353*7c478bd9Sstevel@tonic-gate datadm_entry_t *se1, *se2; 1354*7c478bd9Sstevel@tonic-gate 1355*7c478bd9Sstevel@tonic-gate if (!datadm_hca_entry_match( 1356*7c478bd9Sstevel@tonic-gate (datadm_hca_entry_t *)he1, 1357*7c478bd9Sstevel@tonic-gate (datadm_hca_entry_t *)he2)) { 1358*7c478bd9Sstevel@tonic-gate he2 = he2->de_next; 1359*7c478bd9Sstevel@tonic-gate continue; 1360*7c478bd9Sstevel@tonic-gate } 1361*7c478bd9Sstevel@tonic-gate se1 = ((datadm_hca_entry_t *)he1)->he_sp_list.dl_head; 1362*7c478bd9Sstevel@tonic-gate while (se1 != NULL) { 1363*7c478bd9Sstevel@tonic-gate se2 = ((datadm_hca_entry_t *)he2)-> 1364*7c478bd9Sstevel@tonic-gate he_sp_list.dl_head; 1365*7c478bd9Sstevel@tonic-gate while (se2 != NULL) { 1366*7c478bd9Sstevel@tonic-gate if (!datadm_sp_entry_match( 1367*7c478bd9Sstevel@tonic-gate (datadm_sp_entry_t *)se1, 1368*7c478bd9Sstevel@tonic-gate (datadm_sp_entry_t *)se2)) { 1369*7c478bd9Sstevel@tonic-gate se2 = se2->de_next; 1370*7c478bd9Sstevel@tonic-gate continue; 1371*7c478bd9Sstevel@tonic-gate } 1372*7c478bd9Sstevel@tonic-gate ((datadm_sp_entry_t *)se1)-> 1373*7c478bd9Sstevel@tonic-gate spe_invalid = 1; 1374*7c478bd9Sstevel@tonic-gate break; 1375*7c478bd9Sstevel@tonic-gate } 1376*7c478bd9Sstevel@tonic-gate se1 = se1->de_next; 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate break; 1379*7c478bd9Sstevel@tonic-gate } 1380*7c478bd9Sstevel@tonic-gate he1 = he1->de_next; 1381*7c478bd9Sstevel@tonic-gate } 1382*7c478bd9Sstevel@tonic-gate } 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate /* 1385*7c478bd9Sstevel@tonic-gate * applies datadm_fill_ia_list on each hca_list element 1386*7c478bd9Sstevel@tonic-gate */ 1387*7c478bd9Sstevel@tonic-gate static int 1388*7c478bd9Sstevel@tonic-gate datadm_build_ia_lists(datadm_list_t *hca_list) 1389*7c478bd9Sstevel@tonic-gate { 1390*7c478bd9Sstevel@tonic-gate datadm_fill_ia_list_t ia_args; 1391*7c478bd9Sstevel@tonic-gate di_node_t root_node; 1392*7c478bd9Sstevel@tonic-gate int retval = 0; 1393*7c478bd9Sstevel@tonic-gate int sv4, sv6; 1394*7c478bd9Sstevel@tonic-gate 1395*7c478bd9Sstevel@tonic-gate root_node = di_init("/", DINFOCPYALL); 1396*7c478bd9Sstevel@tonic-gate if (root_node == DI_NODE_NIL) { 1397*7c478bd9Sstevel@tonic-gate perror("datadm: di_init"); 1398*7c478bd9Sstevel@tonic-gate return (-1); 1399*7c478bd9Sstevel@tonic-gate } 1400*7c478bd9Sstevel@tonic-gate sv4 = socket(AF_INET, SOCK_DGRAM, 0); 1401*7c478bd9Sstevel@tonic-gate if (sv4 < 0) { 1402*7c478bd9Sstevel@tonic-gate perror("datadm: socket"); 1403*7c478bd9Sstevel@tonic-gate di_fini(root_node); 1404*7c478bd9Sstevel@tonic-gate return (-1); 1405*7c478bd9Sstevel@tonic-gate } 1406*7c478bd9Sstevel@tonic-gate sv6 = socket(AF_INET6, SOCK_DGRAM, 0); 1407*7c478bd9Sstevel@tonic-gate if (sv6 < 0) { 1408*7c478bd9Sstevel@tonic-gate perror("datadm: socket"); 1409*7c478bd9Sstevel@tonic-gate di_fini(root_node); 1410*7c478bd9Sstevel@tonic-gate return (-1); 1411*7c478bd9Sstevel@tonic-gate } 1412*7c478bd9Sstevel@tonic-gate ia_args.ia_root_node = root_node; 1413*7c478bd9Sstevel@tonic-gate ia_args.ia_sock_fd_v4 = sv4; 1414*7c478bd9Sstevel@tonic-gate ia_args.ia_sock_fd_v6 = sv6; 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate retval = datadm_walk_list(hca_list, 1417*7c478bd9Sstevel@tonic-gate (int (*)(datadm_entry_t *, void *))datadm_fill_ia_list, &ia_args); 1418*7c478bd9Sstevel@tonic-gate 1419*7c478bd9Sstevel@tonic-gate (void) close(sv4); 1420*7c478bd9Sstevel@tonic-gate (void) close(sv6); 1421*7c478bd9Sstevel@tonic-gate di_fini(root_node); 1422*7c478bd9Sstevel@tonic-gate return (retval); 1423*7c478bd9Sstevel@tonic-gate } 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate static int 1426*7c478bd9Sstevel@tonic-gate datadm_generate_conf_entry(FILE *outfile, datadm_ia_entry_t *ia_entry, 1427*7c478bd9Sstevel@tonic-gate datadm_sp_entry_t *sp_entry) 1428*7c478bd9Sstevel@tonic-gate { 1429*7c478bd9Sstevel@tonic-gate int retval; 1430*7c478bd9Sstevel@tonic-gate 1431*7c478bd9Sstevel@tonic-gate retval = fprintf(outfile, 1432*7c478bd9Sstevel@tonic-gate "%s%d %s%d.%d %s %s %s %s%d.%d \"%s\" \"%s%s%s\"\n", 1433*7c478bd9Sstevel@tonic-gate DATADM_IA_NAME, ia_entry->iae_devnum, 1434*7c478bd9Sstevel@tonic-gate (sp_entry->spe_api_version.dv_name ? 1435*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_name : ""), 1436*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_major, 1437*7c478bd9Sstevel@tonic-gate sp_entry->spe_api_version.dv_minor, 1438*7c478bd9Sstevel@tonic-gate (sp_entry->spe_threadsafe ? "threadsafe" : "nonthreadsafe"), 1439*7c478bd9Sstevel@tonic-gate (sp_entry->spe_default ? "default" : "nondefault"), 1440*7c478bd9Sstevel@tonic-gate sp_entry->spe_libpath, 1441*7c478bd9Sstevel@tonic-gate (sp_entry->spe_sp_version.dv_name ? 1442*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_name : ""), 1443*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_major, 1444*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_version.dv_minor, 1445*7c478bd9Sstevel@tonic-gate sp_entry->spe_sp_data, 1446*7c478bd9Sstevel@tonic-gate DATADM_DRV_NAME, "=", sp_entry->spe_devname); 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate if (retval < 0) { 1449*7c478bd9Sstevel@tonic-gate return (-1); 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate return (0); 1452*7c478bd9Sstevel@tonic-gate } 1453*7c478bd9Sstevel@tonic-gate 1454*7c478bd9Sstevel@tonic-gate /* 1455*7c478bd9Sstevel@tonic-gate * generate dat.conf header 1456*7c478bd9Sstevel@tonic-gate */ 1457*7c478bd9Sstevel@tonic-gate static int 1458*7c478bd9Sstevel@tonic-gate datadm_generate_conf_header(FILE *outfile) 1459*7c478bd9Sstevel@tonic-gate { 1460*7c478bd9Sstevel@tonic-gate datadm_entry_t *cep; 1461*7c478bd9Sstevel@tonic-gate datadm_cmnt_entry_t *cmnt; 1462*7c478bd9Sstevel@tonic-gate int retval = 0; 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate cep = datadm_conf_header.dl_head; 1465*7c478bd9Sstevel@tonic-gate if (cep == NULL) { 1466*7c478bd9Sstevel@tonic-gate /* 1467*7c478bd9Sstevel@tonic-gate * if dat.conf doesn't have a header, we prepend a 1468*7c478bd9Sstevel@tonic-gate * default one. 1469*7c478bd9Sstevel@tonic-gate */ 1470*7c478bd9Sstevel@tonic-gate retval = fprintf(outfile, "%s", datadm_conf_header_default); 1471*7c478bd9Sstevel@tonic-gate goto done; 1472*7c478bd9Sstevel@tonic-gate } 1473*7c478bd9Sstevel@tonic-gate while (cep != NULL) { 1474*7c478bd9Sstevel@tonic-gate cmnt = (datadm_cmnt_entry_t *)cep; 1475*7c478bd9Sstevel@tonic-gate if (cmnt->cmnt_line != NULL) { 1476*7c478bd9Sstevel@tonic-gate int len; 1477*7c478bd9Sstevel@tonic-gate 1478*7c478bd9Sstevel@tonic-gate retval = fprintf(outfile, "%s", cmnt->cmnt_line); 1479*7c478bd9Sstevel@tonic-gate if (retval < 0) { 1480*7c478bd9Sstevel@tonic-gate break; 1481*7c478bd9Sstevel@tonic-gate } 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate /* 1484*7c478bd9Sstevel@tonic-gate * append a newline if the comment line doesn't 1485*7c478bd9Sstevel@tonic-gate * have one. 1486*7c478bd9Sstevel@tonic-gate */ 1487*7c478bd9Sstevel@tonic-gate len = strlen(cmnt->cmnt_line); 1488*7c478bd9Sstevel@tonic-gate if (cmnt->cmnt_line[len - 1] != '\n') { 1489*7c478bd9Sstevel@tonic-gate retval = fprintf(outfile, "\n"); 1490*7c478bd9Sstevel@tonic-gate if (retval < 0) { 1491*7c478bd9Sstevel@tonic-gate break; 1492*7c478bd9Sstevel@tonic-gate } 1493*7c478bd9Sstevel@tonic-gate } 1494*7c478bd9Sstevel@tonic-gate } 1495*7c478bd9Sstevel@tonic-gate cep = cep->de_next; 1496*7c478bd9Sstevel@tonic-gate } 1497*7c478bd9Sstevel@tonic-gate done:; 1498*7c478bd9Sstevel@tonic-gate if (retval < 0) { 1499*7c478bd9Sstevel@tonic-gate return (-1); 1500*7c478bd9Sstevel@tonic-gate } 1501*7c478bd9Sstevel@tonic-gate return (0); 1502*7c478bd9Sstevel@tonic-gate } 1503*7c478bd9Sstevel@tonic-gate 1504*7c478bd9Sstevel@tonic-gate /* 1505*7c478bd9Sstevel@tonic-gate * outputs dat.conf to stdout or to basedir/etc/dat/dat.conf 1506*7c478bd9Sstevel@tonic-gate */ 1507*7c478bd9Sstevel@tonic-gate static int 1508*7c478bd9Sstevel@tonic-gate datadm_generate_dat_conf(datadm_list_t *hca_list) 1509*7c478bd9Sstevel@tonic-gate { 1510*7c478bd9Sstevel@tonic-gate FILE *outfile = NULL; 1511*7c478bd9Sstevel@tonic-gate char *dat_conf = datadm_args.da_dat_conf; 1512*7c478bd9Sstevel@tonic-gate datadm_entry_t *hep; 1513*7c478bd9Sstevel@tonic-gate int retval = 0; 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate if (datadm_args.da_op_type == DATADM_OP_VIEW) { 1516*7c478bd9Sstevel@tonic-gate outfile = stdout; 1517*7c478bd9Sstevel@tonic-gate } else { 1518*7c478bd9Sstevel@tonic-gate outfile = fopen(dat_conf, "w+"); 1519*7c478bd9Sstevel@tonic-gate if (outfile == NULL) { 1520*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1521*7c478bd9Sstevel@tonic-gate "datadm: cannot open %s: %s\n"), 1522*7c478bd9Sstevel@tonic-gate dat_conf, strerror(errno)); 1523*7c478bd9Sstevel@tonic-gate return (-1); 1524*7c478bd9Sstevel@tonic-gate } 1525*7c478bd9Sstevel@tonic-gate } 1526*7c478bd9Sstevel@tonic-gate if (outfile != stdout) { 1527*7c478bd9Sstevel@tonic-gate /* 1528*7c478bd9Sstevel@tonic-gate * do not generate the header if we are 1529*7c478bd9Sstevel@tonic-gate * printing to the screen 1530*7c478bd9Sstevel@tonic-gate */ 1531*7c478bd9Sstevel@tonic-gate retval = datadm_generate_conf_header(outfile); 1532*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1533*7c478bd9Sstevel@tonic-gate goto done; 1534*7c478bd9Sstevel@tonic-gate } 1535*7c478bd9Sstevel@tonic-gate } 1536*7c478bd9Sstevel@tonic-gate hep = hca_list->dl_head; 1537*7c478bd9Sstevel@tonic-gate while (hep != NULL) { 1538*7c478bd9Sstevel@tonic-gate datadm_entry_t *iep; 1539*7c478bd9Sstevel@tonic-gate 1540*7c478bd9Sstevel@tonic-gate iep = ((datadm_hca_entry_t *)hep)->he_ia_list.dl_head; 1541*7c478bd9Sstevel@tonic-gate while (iep != NULL) { 1542*7c478bd9Sstevel@tonic-gate datadm_entry_t *sep; 1543*7c478bd9Sstevel@tonic-gate 1544*7c478bd9Sstevel@tonic-gate sep = ((datadm_hca_entry_t *)hep)->he_sp_list.dl_head; 1545*7c478bd9Sstevel@tonic-gate while (sep != NULL) { 1546*7c478bd9Sstevel@tonic-gate if (((datadm_sp_entry_t *)sep)->spe_invalid) { 1547*7c478bd9Sstevel@tonic-gate sep = sep->de_next; 1548*7c478bd9Sstevel@tonic-gate continue; 1549*7c478bd9Sstevel@tonic-gate } 1550*7c478bd9Sstevel@tonic-gate retval = datadm_generate_conf_entry(outfile, 1551*7c478bd9Sstevel@tonic-gate (datadm_ia_entry_t *)iep, 1552*7c478bd9Sstevel@tonic-gate (datadm_sp_entry_t *)sep); 1553*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1554*7c478bd9Sstevel@tonic-gate goto done; 1555*7c478bd9Sstevel@tonic-gate } 1556*7c478bd9Sstevel@tonic-gate sep = sep->de_next; 1557*7c478bd9Sstevel@tonic-gate } 1558*7c478bd9Sstevel@tonic-gate iep = iep->de_next; 1559*7c478bd9Sstevel@tonic-gate } 1560*7c478bd9Sstevel@tonic-gate hep = hep->de_next; 1561*7c478bd9Sstevel@tonic-gate } 1562*7c478bd9Sstevel@tonic-gate retval = fflush(outfile); 1563*7c478bd9Sstevel@tonic-gate done:; 1564*7c478bd9Sstevel@tonic-gate if (outfile != stdout) { 1565*7c478bd9Sstevel@tonic-gate (void) fclose(outfile); 1566*7c478bd9Sstevel@tonic-gate } 1567*7c478bd9Sstevel@tonic-gate if (retval < 0) { 1568*7c478bd9Sstevel@tonic-gate perror("datadm: fprintf"); 1569*7c478bd9Sstevel@tonic-gate } 1570*7c478bd9Sstevel@tonic-gate return (retval); 1571*7c478bd9Sstevel@tonic-gate } 1572*7c478bd9Sstevel@tonic-gate 1573*7c478bd9Sstevel@tonic-gate static int 1574*7c478bd9Sstevel@tonic-gate datadm_view(void) 1575*7c478bd9Sstevel@tonic-gate { 1576*7c478bd9Sstevel@tonic-gate int retval = 0; 1577*7c478bd9Sstevel@tonic-gate datadm_list_t hca_list; 1578*7c478bd9Sstevel@tonic-gate 1579*7c478bd9Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1580*7c478bd9Sstevel@tonic-gate 1581*7c478bd9Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1582*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1583*7c478bd9Sstevel@tonic-gate goto cleanup; 1584*7c478bd9Sstevel@tonic-gate } 1585*7c478bd9Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1586*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1587*7c478bd9Sstevel@tonic-gate goto cleanup; 1588*7c478bd9Sstevel@tonic-gate } 1589*7c478bd9Sstevel@tonic-gate 1590*7c478bd9Sstevel@tonic-gate cleanup:; 1591*7c478bd9Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1592*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1593*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_list, 1594*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1595*7c478bd9Sstevel@tonic-gate return (retval); 1596*7c478bd9Sstevel@tonic-gate } 1597*7c478bd9Sstevel@tonic-gate 1598*7c478bd9Sstevel@tonic-gate static int 1599*7c478bd9Sstevel@tonic-gate datadm_update(void) 1600*7c478bd9Sstevel@tonic-gate { 1601*7c478bd9Sstevel@tonic-gate int retval = 0; 1602*7c478bd9Sstevel@tonic-gate datadm_list_t hca_list; 1603*7c478bd9Sstevel@tonic-gate 1604*7c478bd9Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1605*7c478bd9Sstevel@tonic-gate 1606*7c478bd9Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1607*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1608*7c478bd9Sstevel@tonic-gate goto cleanup; 1609*7c478bd9Sstevel@tonic-gate } 1610*7c478bd9Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list); 1611*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1612*7c478bd9Sstevel@tonic-gate goto cleanup; 1613*7c478bd9Sstevel@tonic-gate } 1614*7c478bd9Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1615*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1616*7c478bd9Sstevel@tonic-gate goto cleanup; 1617*7c478bd9Sstevel@tonic-gate } 1618*7c478bd9Sstevel@tonic-gate 1619*7c478bd9Sstevel@tonic-gate cleanup:; 1620*7c478bd9Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1621*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1622*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_list, 1623*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1624*7c478bd9Sstevel@tonic-gate return (retval); 1625*7c478bd9Sstevel@tonic-gate } 1626*7c478bd9Sstevel@tonic-gate 1627*7c478bd9Sstevel@tonic-gate static int 1628*7c478bd9Sstevel@tonic-gate datadm_add(void) 1629*7c478bd9Sstevel@tonic-gate { 1630*7c478bd9Sstevel@tonic-gate int retval = 0; 1631*7c478bd9Sstevel@tonic-gate datadm_list_t hca_list; 1632*7c478bd9Sstevel@tonic-gate 1633*7c478bd9Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1634*7c478bd9Sstevel@tonic-gate 1635*7c478bd9Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1636*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1637*7c478bd9Sstevel@tonic-gate goto cleanup; 1638*7c478bd9Sstevel@tonic-gate } 1639*7c478bd9Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list); 1640*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1641*7c478bd9Sstevel@tonic-gate goto cleanup; 1642*7c478bd9Sstevel@tonic-gate } 1643*7c478bd9Sstevel@tonic-gate retval = datadm_build_ia_lists(&hca_list); 1644*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1645*7c478bd9Sstevel@tonic-gate goto cleanup; 1646*7c478bd9Sstevel@tonic-gate } 1647*7c478bd9Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1648*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1649*7c478bd9Sstevel@tonic-gate goto cleanup; 1650*7c478bd9Sstevel@tonic-gate } 1651*7c478bd9Sstevel@tonic-gate 1652*7c478bd9Sstevel@tonic-gate cleanup:; 1653*7c478bd9Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1654*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1655*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_list, 1656*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1657*7c478bd9Sstevel@tonic-gate return (retval); 1658*7c478bd9Sstevel@tonic-gate } 1659*7c478bd9Sstevel@tonic-gate 1660*7c478bd9Sstevel@tonic-gate static int 1661*7c478bd9Sstevel@tonic-gate datadm_remove(void) 1662*7c478bd9Sstevel@tonic-gate { 1663*7c478bd9Sstevel@tonic-gate int retval = 0; 1664*7c478bd9Sstevel@tonic-gate datadm_list_t hca_list; 1665*7c478bd9Sstevel@tonic-gate datadm_list_t hca_list2; 1666*7c478bd9Sstevel@tonic-gate 1667*7c478bd9Sstevel@tonic-gate bzero(&hca_list, sizeof (hca_list)); 1668*7c478bd9Sstevel@tonic-gate bzero(&hca_list2, sizeof (hca_list2)); 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate retval = datadm_parse_dat_conf(&hca_list); 1671*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1672*7c478bd9Sstevel@tonic-gate goto cleanup; 1673*7c478bd9Sstevel@tonic-gate } 1674*7c478bd9Sstevel@tonic-gate retval = datadm_parse_sp_conf(&hca_list2); 1675*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1676*7c478bd9Sstevel@tonic-gate goto cleanup; 1677*7c478bd9Sstevel@tonic-gate } 1678*7c478bd9Sstevel@tonic-gate datadm_invalidate_common_sp_entries(&hca_list, &hca_list2); 1679*7c478bd9Sstevel@tonic-gate 1680*7c478bd9Sstevel@tonic-gate retval = datadm_generate_dat_conf(&hca_list); 1681*7c478bd9Sstevel@tonic-gate if (retval != 0) { 1682*7c478bd9Sstevel@tonic-gate goto cleanup; 1683*7c478bd9Sstevel@tonic-gate } 1684*7c478bd9Sstevel@tonic-gate 1685*7c478bd9Sstevel@tonic-gate cleanup:; 1686*7c478bd9Sstevel@tonic-gate datadm_free_list(&datadm_conf_header, 1687*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_cmnt_entry); 1688*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_list, 1689*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1690*7c478bd9Sstevel@tonic-gate datadm_free_list(&hca_list2, 1691*7c478bd9Sstevel@tonic-gate (void (*)(datadm_entry_t *))datadm_free_hca_entry); 1692*7c478bd9Sstevel@tonic-gate return (retval); 1693*7c478bd9Sstevel@tonic-gate } 1694*7c478bd9Sstevel@tonic-gate 1695*7c478bd9Sstevel@tonic-gate static int 1696*7c478bd9Sstevel@tonic-gate datadm_locate_dat_conf(char *basedir) 1697*7c478bd9Sstevel@tonic-gate { 1698*7c478bd9Sstevel@tonic-gate char *dat_conf; 1699*7c478bd9Sstevel@tonic-gate 1700*7c478bd9Sstevel@tonic-gate if (basedir == NULL) { 1701*7c478bd9Sstevel@tonic-gate datadm_args.da_dat_conf = DATADM_DAT_CONF; 1702*7c478bd9Sstevel@tonic-gate return (0); 1703*7c478bd9Sstevel@tonic-gate } 1704*7c478bd9Sstevel@tonic-gate dat_conf = (char *)malloc(strlen(basedir) + 1705*7c478bd9Sstevel@tonic-gate strlen(DATADM_DAT_CONF) + 1); 1706*7c478bd9Sstevel@tonic-gate if (dat_conf == NULL) { 1707*7c478bd9Sstevel@tonic-gate return (-1); 1708*7c478bd9Sstevel@tonic-gate } 1709*7c478bd9Sstevel@tonic-gate dat_conf[0] = '\0'; 1710*7c478bd9Sstevel@tonic-gate (void) strcat(dat_conf, basedir); 1711*7c478bd9Sstevel@tonic-gate (void) strcat(dat_conf, DATADM_DAT_CONF); 1712*7c478bd9Sstevel@tonic-gate datadm_args.da_dat_conf = dat_conf; 1713*7c478bd9Sstevel@tonic-gate return (0); 1714*7c478bd9Sstevel@tonic-gate } 1715*7c478bd9Sstevel@tonic-gate 1716*7c478bd9Sstevel@tonic-gate int 1717*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1718*7c478bd9Sstevel@tonic-gate { 1719*7c478bd9Sstevel@tonic-gate extern char *optarg; 1720*7c478bd9Sstevel@tonic-gate extern int optind; 1721*7c478bd9Sstevel@tonic-gate char *basedir = NULL; 1722*7c478bd9Sstevel@tonic-gate int c, retval; 1723*7c478bd9Sstevel@tonic-gate int op_type = -1, errflg = 0; 1724*7c478bd9Sstevel@tonic-gate 1725*7c478bd9Sstevel@tonic-gate bzero(&datadm_args, sizeof (datadm_args)); 1726*7c478bd9Sstevel@tonic-gate bzero(&datadm_conf_header, sizeof (datadm_conf_header)); 1727*7c478bd9Sstevel@tonic-gate 1728*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1729*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1730*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1731*7c478bd9Sstevel@tonic-gate #endif 1732*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1733*7c478bd9Sstevel@tonic-gate 1734*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "vua:r:b:")) != EOF) { 1735*7c478bd9Sstevel@tonic-gate switch (c) { 1736*7c478bd9Sstevel@tonic-gate case 'v': 1737*7c478bd9Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1738*7c478bd9Sstevel@tonic-gate op_type = DATADM_OP_VIEW; 1739*7c478bd9Sstevel@tonic-gate break; 1740*7c478bd9Sstevel@tonic-gate case 'u': 1741*7c478bd9Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1742*7c478bd9Sstevel@tonic-gate op_type = DATADM_OP_UPDATE; 1743*7c478bd9Sstevel@tonic-gate break; 1744*7c478bd9Sstevel@tonic-gate case 'a': 1745*7c478bd9Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1746*7c478bd9Sstevel@tonic-gate op_type = DATADM_OP_ADD; 1747*7c478bd9Sstevel@tonic-gate datadm_args.da_sp_conf = optarg; 1748*7c478bd9Sstevel@tonic-gate break; 1749*7c478bd9Sstevel@tonic-gate case 'r': 1750*7c478bd9Sstevel@tonic-gate if (op_type != -1) errflg = 1; 1751*7c478bd9Sstevel@tonic-gate op_type = DATADM_OP_REMOVE; 1752*7c478bd9Sstevel@tonic-gate datadm_args.da_sp_conf = optarg; 1753*7c478bd9Sstevel@tonic-gate break; 1754*7c478bd9Sstevel@tonic-gate case 'b': 1755*7c478bd9Sstevel@tonic-gate basedir = optarg; 1756*7c478bd9Sstevel@tonic-gate break; 1757*7c478bd9Sstevel@tonic-gate default: 1758*7c478bd9Sstevel@tonic-gate errflg = 1; 1759*7c478bd9Sstevel@tonic-gate break; 1760*7c478bd9Sstevel@tonic-gate } 1761*7c478bd9Sstevel@tonic-gate if (errflg != 0) { 1762*7c478bd9Sstevel@tonic-gate break; 1763*7c478bd9Sstevel@tonic-gate } 1764*7c478bd9Sstevel@tonic-gate } 1765*7c478bd9Sstevel@tonic-gate if (errflg != 0 || op_type == -1 || optind < argc) { 1766*7c478bd9Sstevel@tonic-gate datadm_usage(); 1767*7c478bd9Sstevel@tonic-gate return (1); 1768*7c478bd9Sstevel@tonic-gate } 1769*7c478bd9Sstevel@tonic-gate datadm_args.da_op_type = op_type; 1770*7c478bd9Sstevel@tonic-gate if (datadm_locate_dat_conf(basedir)) { 1771*7c478bd9Sstevel@tonic-gate return (1); 1772*7c478bd9Sstevel@tonic-gate } 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate retval = (*datadm_ops[op_type])(); 1775*7c478bd9Sstevel@tonic-gate return (retval); 1776*7c478bd9Sstevel@tonic-gate } 1777