Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / udapl / libdat / common / dat_dr.c
blob8a346579e8b775b99968b7eedd31f1486cd98aec
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
27 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
35 * MODULE: dat_dr.c
37 * PURPOSE: dynamic registry implementation
39 * $Id: dat_dr.c,v 1.12 2003/08/20 14:28:40 hobie16 Exp $
43 #include "dat_dr.h"
45 #include "dat_dictionary.h"
50 * Global Variables
54 static DAT_OS_LOCK g_dr_lock;
55 static DAT_DICTIONARY *g_dr_dictionary = NULL;
60 * External Functions
66 * Function: dat_dr_init
69 DAT_RETURN
70 dat_dr_init(void)
72 DAT_RETURN status;
74 status = dat_os_lock_init(&g_dr_lock);
75 if (DAT_SUCCESS != status) {
76 return (status);
79 status = dat_dictionary_create(&g_dr_dictionary);
80 if (DAT_SUCCESS != status) {
81 return (status);
84 return (DAT_SUCCESS);
89 * Function: dat_dr_fini
92 DAT_RETURN
93 dat_dr_fini(void)
95 DAT_RETURN status;
97 status = dat_os_lock_destroy(&g_dr_lock);
98 if (DAT_SUCCESS != status) {
99 return (status);
102 status = dat_dictionary_destroy(g_dr_dictionary);
103 if (DAT_SUCCESS != status) {
104 return (status);
107 return (DAT_SUCCESS);
112 * Function: dat_dr_insert
115 extern DAT_RETURN
116 dat_dr_insert(
117 IN const DAT_PROVIDER_INFO *info,
118 IN DAT_DR_ENTRY *entry)
120 DAT_RETURN status;
121 DAT_DICTIONARY_ENTRY dict_entry;
122 DAT_DR_ENTRY *data;
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;
131 *data = *entry;
133 dict_entry = NULL;
134 status = dat_dictionary_entry_create(&dict_entry);
135 if (DAT_SUCCESS != status) {
136 goto bail;
139 dat_os_lock(&g_dr_lock);
141 status = dat_dictionary_insert(g_dr_dictionary,
142 dict_entry,
143 info,
144 (DAT_DICTIONARY_DATA *) data);
146 dat_os_unlock(&g_dr_lock);
148 bail:
149 if (DAT_SUCCESS != status) {
150 if (NULL != data) {
151 dat_os_free(data, sizeof (DAT_DR_ENTRY));
155 if (NULL != dict_entry) {
156 (void) dat_dictionary_entry_destroy(dict_entry);
160 return (status);
165 * Function: dat_dr_remove
168 extern DAT_RETURN
169 dat_dr_remove(
170 IN const DAT_PROVIDER_INFO *info)
172 DAT_DR_ENTRY *data;
173 DAT_DICTIONARY_ENTRY dict_entry;
174 DAT_RETURN status;
176 dat_os_lock(&g_dr_lock);
178 status = dat_dictionary_search(g_dr_dictionary,
179 info,
180 (DAT_DICTIONARY_DATA *) &data);
182 if (DAT_SUCCESS != status) {
183 /* return status from dat_dictionary_search() */
184 goto bail;
187 if (0 != data->ref_count) {
188 status = DAT_ERROR(DAT_PROVIDER_IN_USE, 0);
189 goto bail;
192 dict_entry = NULL;
193 status = dat_dictionary_remove(g_dr_dictionary,
194 &dict_entry,
195 info,
196 (DAT_DICTIONARY_DATA *) &data);
198 if (DAT_SUCCESS != status) {
199 /* return status from dat_dictionary_remove() */
200 goto bail;
203 dat_os_free(data, sizeof (DAT_DR_ENTRY));
205 bail:
206 dat_os_unlock(&g_dr_lock);
208 if (NULL != dict_entry) {
209 (void) dat_dictionary_entry_destroy(dict_entry);
212 return (status);
217 * Function: dat_dr_provider_open
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)
225 DAT_RETURN status;
226 DAT_DR_ENTRY *data;
228 dat_os_lock(&g_dr_lock);
230 status = dat_dictionary_search(g_dr_dictionary,
231 info,
232 (DAT_DICTIONARY_DATA *) &data);
234 dat_os_unlock(&g_dr_lock);
236 if (DAT_SUCCESS == status) {
237 data->ref_count++;
238 *p_ia_open_func = data->ia_open_func;
241 return (status);
246 * Function: dat_dr_provider_close
249 extern DAT_RETURN
250 dat_dr_provider_close(
251 IN const DAT_PROVIDER_INFO *info)
253 DAT_RETURN status;
254 DAT_DR_ENTRY *data;
256 dat_os_lock(&g_dr_lock);
258 status = dat_dictionary_search(g_dr_dictionary,
259 info,
260 (DAT_DICTIONARY_DATA *) &data);
262 dat_os_unlock(&g_dr_lock);
264 if (DAT_SUCCESS == status) {
265 data->ref_count--;
268 return (status);
273 * Function: dat_dr_size
276 DAT_RETURN
277 dat_dr_size(
278 OUT DAT_COUNT *size)
280 return (dat_dictionary_size(g_dr_dictionary, size));
285 * Function: dat_dr_list
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[]))
294 DAT_DR_ENTRY **array;
295 DAT_COUNT array_size;
296 DAT_COUNT i;
297 DAT_RETURN status;
299 array = NULL;
300 status = DAT_SUCCESS;
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.
307 *entries_returned = 0;
308 for (;;) {
309 status = dat_dictionary_size(g_dr_dictionary, &array_size);
310 if (status != DAT_SUCCESS) {
311 goto bail;
314 if (array_size == 0) {
315 status = DAT_SUCCESS;
316 goto bail;
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;
326 dat_os_lock(&g_dr_lock);
328 status = dat_dictionary_enumerate(g_dr_dictionary,
329 (DAT_DICTIONARY_DATA *) array,
330 array_size);
332 dat_os_unlock(&g_dr_lock);
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;
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;
351 *dat_provider_list[i] = array[i]->info;
354 *entries_returned = i;
356 bail:
357 if (NULL != array) {
358 dat_os_free(array, array_size * sizeof (DAT_DR_ENTRY *));
361 return (status);
365 * Local variables:
366 * c-indent-level: 4
367 * c-basic-offset: 4
368 * tab-width: 8
369 * End: