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