1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * 35 * MODULE: dat_sr.c 36 * 37 * PURPOSE: static registry implementation 38 * 39 * $Id: dat_sr.c,v 1.12 2003/08/20 14:28:40 hobie16 Exp $ 40 */ 41 42 43 #include "dat_sr.h" 44 45 #include "dat_dictionary.h" 46 #include "udat_sr_parser.h" 47 48 49 /* 50 * 51 * Global Variables 52 * 53 */ 54 55 static DAT_OS_LOCK g_sr_lock; 56 static DAT_DICTIONARY *g_sr_dictionary = NULL; 57 58 59 /* 60 * 61 * External Functions 62 * 63 */ 64 65 66 /* 67 * Function: dat_sr_init 68 */ 69 70 DAT_RETURN 71 dat_sr_init(void) 72 { 73 DAT_RETURN status; 74 75 status = dat_os_lock_init(&g_sr_lock); 76 if (DAT_SUCCESS != status) { 77 return (status); 78 } 79 80 status = dat_dictionary_create(&g_sr_dictionary); 81 if (DAT_SUCCESS != status) { 82 return (status); 83 } 84 85 /* 86 * Since DAT allows providers to be loaded by either the static 87 * registry or explicitly through OS dependent methods, do not 88 * return an error if no providers are loaded via the static registry. 89 */ 90 91 (void) dat_sr_load(); 92 93 return (DAT_SUCCESS); 94 } 95 96 97 /* 98 * Function: dat_sr_fini 99 */ 100 101 extern DAT_RETURN 102 dat_sr_fini(void) 103 { 104 DAT_RETURN status; 105 106 status = dat_os_lock_destroy(&g_sr_lock); 107 if (DAT_SUCCESS != status) { 108 return (status); 109 } 110 111 status = dat_dictionary_destroy(g_sr_dictionary); 112 if (DAT_SUCCESS != status) { 113 return (status); 114 } 115 116 return (DAT_SUCCESS); 117 } 118 119 120 /* 121 * Function: dat_sr_insert 122 */ 123 124 extern DAT_RETURN 125 dat_sr_insert( 126 IN const DAT_PROVIDER_INFO *info, 127 IN DAT_SR_ENTRY *entry) 128 { 129 DAT_RETURN status; 130 DAT_SR_ENTRY *data; 131 DAT_OS_SIZE lib_path_size; 132 DAT_OS_SIZE lib_path_len; 133 DAT_OS_SIZE ia_params_size; 134 DAT_OS_SIZE ia_params_len; 135 DAT_DICTIONARY_ENTRY dict_entry; 136 137 if (NULL == (data = dat_os_alloc(sizeof (DAT_SR_ENTRY)))) { 138 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 139 DAT_RESOURCE_MEMORY); 140 goto bail; 141 } 142 143 lib_path_len = strlen(entry->lib_path); 144 lib_path_size = (lib_path_len + 1) * sizeof (char); 145 146 if (NULL == (data->lib_path = dat_os_alloc(lib_path_size))) { 147 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 148 DAT_RESOURCE_MEMORY); 149 goto bail; 150 } 151 152 (void) dat_os_strncpy(data->lib_path, entry->lib_path, lib_path_len); 153 data->lib_path[lib_path_len] = '\0'; 154 155 ia_params_len = strlen(entry->ia_params); 156 ia_params_size = (ia_params_len + 1) * sizeof (char); 157 158 if (NULL == (data->ia_params = dat_os_alloc(ia_params_size))) { 159 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 160 DAT_RESOURCE_MEMORY); 161 goto bail; 162 } 163 164 (void) dat_os_strncpy(data->ia_params, entry->ia_params, ia_params_len); 165 data->ia_params[ia_params_len] = '\0'; 166 167 data->info = entry->info; 168 data->lib_handle = entry->lib_handle; 169 data->ref_count = entry->ref_count; 170 171 dict_entry = NULL; 172 status = dat_dictionary_entry_create(&dict_entry); 173 if (DAT_SUCCESS != status) { 174 goto bail; 175 } 176 177 dat_os_lock(&g_sr_lock); 178 179 status = dat_dictionary_insert(g_sr_dictionary, 180 dict_entry, 181 info, 182 (DAT_DICTIONARY_DATA *)data); 183 dat_os_unlock(&g_sr_lock); 184 185 bail: 186 if (DAT_SUCCESS != status) { 187 if (NULL != data) { 188 if (NULL != data->lib_path) { 189 dat_os_free(data->lib_path, lib_path_size); 190 } 191 192 if (NULL != data->ia_params) { 193 dat_os_free(data->ia_params, ia_params_size); 194 } 195 196 dat_os_free(data, sizeof (DAT_SR_ENTRY)); 197 } 198 199 if (NULL != dict_entry) { 200 (void) dat_dictionary_entry_destroy(dict_entry); 201 } 202 } 203 204 return (status); 205 } 206 207 208 /* 209 * Function: dat_sr_size 210 */ 211 212 extern DAT_RETURN 213 dat_sr_size( 214 OUT DAT_COUNT *size) 215 { 216 return (dat_dictionary_size(g_sr_dictionary, size)); 217 } 218 219 220 /* 221 * Function: dat_sr_list 222 */ 223 224 extern DAT_RETURN 225 dat_sr_list( 226 IN DAT_COUNT max_to_return, 227 OUT DAT_COUNT *entries_returned, 228 OUT DAT_PROVIDER_INFO * (dat_provider_list[])) 229 { 230 DAT_SR_ENTRY **array; 231 DAT_COUNT array_size; 232 DAT_COUNT i; 233 DAT_RETURN status; 234 235 array = NULL; 236 status = DAT_SUCCESS; 237 238 /* 239 * The dictionary size may increase between the call to 240 * dat_dictionary_size() and dat_dictionary_enumerate(). 241 * Therefore we loop until a successful enumeration is made. 242 */ 243 *entries_returned = 0; 244 for (;;) { 245 status = dat_dictionary_size(g_sr_dictionary, &array_size); 246 if (DAT_SUCCESS != status) { 247 goto bail; 248 } 249 250 if (array_size == 0) { 251 status = DAT_SUCCESS; 252 goto bail; 253 } 254 255 array = dat_os_alloc(array_size * sizeof (DAT_SR_ENTRY *)); 256 if (array == NULL) { 257 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 258 DAT_RESOURCE_MEMORY); 259 goto bail; 260 } 261 262 dat_os_lock(&g_sr_lock); 263 264 status = dat_dictionary_enumerate(g_sr_dictionary, 265 (DAT_DICTIONARY_DATA *) array, 266 array_size); 267 268 dat_os_unlock(&g_sr_lock); 269 270 if (DAT_SUCCESS == status) { 271 break; 272 } else { 273 dat_os_free(array, 274 array_size * sizeof (DAT_SR_ENTRY *)); 275 array = NULL; 276 continue; 277 } 278 } 279 280 for (i = 0; (i < max_to_return) && (i < array_size); i++) { 281 if (NULL == dat_provider_list[i]) { 282 status = DAT_ERROR(DAT_INVALID_PARAMETER, 283 DAT_INVALID_ARG3); 284 goto bail; 285 } 286 287 *dat_provider_list[i] = array[i]->info; 288 } 289 290 *entries_returned = i; 291 292 bail: 293 if (NULL != array) { 294 dat_os_free(array, array_size * sizeof (DAT_SR_ENTRY *)); 295 } 296 297 return (status); 298 } 299 300 301 302 /* 303 * Function: dat_sr_provider_open 304 */ 305 306 extern DAT_RETURN 307 dat_sr_provider_open( 308 IN const DAT_PROVIDER_INFO *info) 309 { 310 DAT_RETURN status; 311 DAT_SR_ENTRY *data; 312 313 dat_os_lock(&g_sr_lock); 314 315 status = dat_dictionary_search(g_sr_dictionary, 316 info, 317 (DAT_DICTIONARY_DATA *) &data); 318 319 if (DAT_SUCCESS == status) { 320 if (0 == data->ref_count) { 321 status = dat_os_library_load(data->lib_path, 322 &data->lib_handle); 323 if (status == DAT_SUCCESS) { 324 data->ref_count++; 325 } else { 326 dat_os_dbg_print(DAT_OS_DBG_TYPE_SR, 327 "DAT Registry: static registry unable to " 328 "load library %s\n", data->lib_path); 329 goto bail; 330 } 331 data->init_func = (DAT_PROVIDER_INIT_FUNC) 332 dat_os_library_sym(data->lib_handle, 333 DAT_PROVIDER_INIT_FUNC_STR); 334 data->fini_func = (DAT_PROVIDER_FINI_FUNC) 335 dat_os_library_sym(data->lib_handle, 336 DAT_PROVIDER_FINI_FUNC_STR); 337 338 if (NULL != data->init_func) { 339 (*data->init_func)(&data->info, 340 data->ia_params); 341 } 342 } else { 343 data->ref_count++; 344 } 345 } 346 347 bail: 348 dat_os_unlock(&g_sr_lock); 349 350 return (status); 351 } 352 353 354 /* 355 * Function: dat_sr_provider_close 356 */ 357 358 extern DAT_RETURN 359 dat_sr_provider_close( 360 IN const DAT_PROVIDER_INFO *info) 361 { 362 DAT_RETURN status; 363 DAT_SR_ENTRY *data; 364 365 dat_os_lock(&g_sr_lock); 366 367 status = dat_dictionary_search(g_sr_dictionary, 368 info, 369 (DAT_DICTIONARY_DATA *)&data); 370 371 if (DAT_SUCCESS == status) { 372 if (1 == data->ref_count) { 373 if (NULL != data->fini_func) { 374 (*data->fini_func)(&data->info); 375 } 376 377 status = dat_os_library_unload(data->lib_handle); 378 if (status == DAT_SUCCESS) { 379 data->ref_count--; 380 } 381 } else { 382 data->ref_count--; 383 } 384 } 385 386 dat_os_unlock(&g_sr_lock); 387 388 return (status); 389 } 390