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 2003 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * MODULE: dat_dr.c 34 * 35 * PURPOSE: dynamic registry implementation 36 * 37 * $Id: dat_dr.c,v 1.12 2003/08/20 14:28:40 hobie16 Exp $ 38 */ 39 40 41 #include "dat_dr.h" 42 43 #include "dat_dictionary.h" 44 45 46 /* 47 * 48 * Global Variables 49 * 50 */ 51 52 static DAT_OS_LOCK g_dr_lock; 53 static DAT_DICTIONARY *g_dr_dictionary = NULL; 54 55 56 /* 57 * 58 * External Functions 59 * 60 */ 61 62 63 /* 64 * Function: dat_dr_init 65 */ 66 67 DAT_RETURN 68 dat_dr_init(void) 69 { 70 DAT_RETURN status; 71 72 status = dat_os_lock_init(&g_dr_lock); 73 if (DAT_SUCCESS != status) { 74 return (status); 75 } 76 77 status = dat_dictionary_create(&g_dr_dictionary); 78 if (DAT_SUCCESS != status) { 79 return (status); 80 } 81 82 return (DAT_SUCCESS); 83 } 84 85 86 /* 87 * Function: dat_dr_fini 88 */ 89 90 DAT_RETURN 91 dat_dr_fini(void) 92 { 93 DAT_RETURN status; 94 95 status = dat_os_lock_destroy(&g_dr_lock); 96 if (DAT_SUCCESS != status) { 97 return (status); 98 } 99 100 status = dat_dictionary_destroy(g_dr_dictionary); 101 if (DAT_SUCCESS != status) { 102 return (status); 103 } 104 105 return (DAT_SUCCESS); 106 } 107 108 109 /* 110 * Function: dat_dr_insert 111 */ 112 113 extern DAT_RETURN 114 dat_dr_insert( 115 IN const DAT_PROVIDER_INFO *info, 116 IN DAT_DR_ENTRY *entry) 117 { 118 DAT_RETURN status; 119 DAT_DICTIONARY_ENTRY dict_entry; 120 DAT_DR_ENTRY *data; 121 122 data = dat_os_alloc(sizeof (DAT_DR_ENTRY)); 123 if (NULL == data) { 124 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 125 DAT_RESOURCE_MEMORY); 126 goto bail; 127 } 128 129 *data = *entry; 130 131 dict_entry = NULL; 132 status = dat_dictionary_entry_create(&dict_entry); 133 if (DAT_SUCCESS != status) { 134 goto bail; 135 } 136 137 dat_os_lock(&g_dr_lock); 138 139 status = dat_dictionary_insert(g_dr_dictionary, 140 dict_entry, 141 info, 142 (DAT_DICTIONARY_DATA *) data); 143 144 dat_os_unlock(&g_dr_lock); 145 146 bail: 147 if (DAT_SUCCESS != status) { 148 if (NULL != data) { 149 dat_os_free(data, sizeof (DAT_DR_ENTRY)); 150 } 151 152 153 if (NULL != dict_entry) { 154 (void) dat_dictionary_entry_destroy(dict_entry); 155 } 156 } 157 158 return (status); 159 } 160 161 162 /* 163 * Function: dat_dr_remove 164 */ 165 166 extern DAT_RETURN 167 dat_dr_remove( 168 IN const DAT_PROVIDER_INFO *info) 169 { 170 DAT_DR_ENTRY *data; 171 DAT_DICTIONARY_ENTRY dict_entry; 172 DAT_RETURN status; 173 174 dat_os_lock(&g_dr_lock); 175 176 status = dat_dictionary_search(g_dr_dictionary, 177 info, 178 (DAT_DICTIONARY_DATA *) &data); 179 180 if (DAT_SUCCESS != status) { 181 /* return status from dat_dictionary_search() */ 182 goto bail; 183 } 184 185 if (0 != data->ref_count) { 186 status = DAT_ERROR(DAT_PROVIDER_IN_USE, 0); 187 goto bail; 188 } 189 190 dict_entry = NULL; 191 status = dat_dictionary_remove(g_dr_dictionary, 192 &dict_entry, 193 info, 194 (DAT_DICTIONARY_DATA *) &data); 195 196 if (DAT_SUCCESS != status) { 197 /* return status from dat_dictionary_remove() */ 198 goto bail; 199 } 200 201 dat_os_free(data, sizeof (DAT_DR_ENTRY)); 202 203 bail: 204 dat_os_unlock(&g_dr_lock); 205 206 if (NULL != dict_entry) { 207 (void) dat_dictionary_entry_destroy(dict_entry); 208 } 209 210 return (status); 211 } 212 213 214 /* 215 * Function: dat_dr_provider_open 216 */ 217 218 extern DAT_RETURN 219 dat_dr_provider_open( 220 IN const DAT_PROVIDER_INFO *info, 221 OUT DAT_IA_OPEN_FUNC *p_ia_open_func) 222 { 223 DAT_RETURN status; 224 DAT_DR_ENTRY *data; 225 226 dat_os_lock(&g_dr_lock); 227 228 status = dat_dictionary_search(g_dr_dictionary, 229 info, 230 (DAT_DICTIONARY_DATA *) &data); 231 232 dat_os_unlock(&g_dr_lock); 233 234 if (DAT_SUCCESS == status) { 235 data->ref_count++; 236 *p_ia_open_func = data->ia_open_func; 237 } 238 239 return (status); 240 } 241 242 243 /* 244 * Function: dat_dr_provider_close 245 */ 246 247 extern DAT_RETURN 248 dat_dr_provider_close( 249 IN const DAT_PROVIDER_INFO *info) 250 { 251 DAT_RETURN status; 252 DAT_DR_ENTRY *data; 253 254 dat_os_lock(&g_dr_lock); 255 256 status = dat_dictionary_search(g_dr_dictionary, 257 info, 258 (DAT_DICTIONARY_DATA *) &data); 259 260 dat_os_unlock(&g_dr_lock); 261 262 if (DAT_SUCCESS == status) { 263 data->ref_count--; 264 } 265 266 return (status); 267 } 268 269 270 /* 271 * Function: dat_dr_size 272 */ 273 274 DAT_RETURN 275 dat_dr_size( 276 OUT DAT_COUNT *size) 277 { 278 return (dat_dictionary_size(g_dr_dictionary, size)); 279 } 280 281 282 /* 283 * Function: dat_dr_list 284 */ 285 286 DAT_RETURN 287 dat_dr_list( 288 IN DAT_COUNT max_to_return, 289 OUT DAT_COUNT *entries_returned, 290 OUT DAT_PROVIDER_INFO * (dat_provider_list[])) 291 { 292 DAT_DR_ENTRY **array; 293 DAT_COUNT array_size; 294 DAT_COUNT i; 295 DAT_RETURN status; 296 297 array = NULL; 298 status = DAT_SUCCESS; 299 300 /* 301 * The dictionary size may increase between the call to 302 * dat_dictionary_size() and dat_dictionary_enumerate(). 303 * Therefore we loop until a successful enumeration is made. 304 */ 305 *entries_returned = 0; 306 for (;;) { 307 status = dat_dictionary_size(g_dr_dictionary, &array_size); 308 if (status != DAT_SUCCESS) { 309 goto bail; 310 } 311 312 if (array_size == 0) { 313 status = DAT_SUCCESS; 314 goto bail; 315 } 316 317 array = dat_os_alloc(array_size * sizeof (DAT_DR_ENTRY *)); 318 if (array == NULL) { 319 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 320 DAT_RESOURCE_MEMORY); 321 goto bail; 322 } 323 324 dat_os_lock(&g_dr_lock); 325 326 status = dat_dictionary_enumerate(g_dr_dictionary, 327 (DAT_DICTIONARY_DATA *) array, 328 array_size); 329 330 dat_os_unlock(&g_dr_lock); 331 332 if (DAT_SUCCESS == status) { 333 break; 334 } else { 335 dat_os_free(array, 336 array_size * sizeof (DAT_DR_ENTRY *)); 337 array = NULL; 338 continue; 339 } 340 } 341 342 for (i = 0; (i < max_to_return) && (i < array_size); i++) { 343 if (NULL == dat_provider_list[i]) { 344 status = DAT_ERROR(DAT_INVALID_PARAMETER, 345 DAT_INVALID_ARG3); 346 goto bail; 347 } 348 349 *dat_provider_list[i] = array[i]->info; 350 } 351 352 *entries_returned = i; 353 354 bail: 355 if (NULL != array) { 356 dat_os_free(array, array_size * sizeof (DAT_DR_ENTRY *)); 357 } 358 359 return (status); 360 } 361 362 /* 363 * Local variables: 364 * c-indent-level: 4 365 * c-basic-offset: 4 366 * tab-width: 8 367 * End: 368 */ 369