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
dat_dr_init(void)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
dat_dr_fini(void)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
dat_dr_insert(IN const DAT_PROVIDER_INFO * info,IN DAT_DR_ENTRY * entry)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
dat_dr_remove(IN const DAT_PROVIDER_INFO * info)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
dat_dr_provider_open(IN const DAT_PROVIDER_INFO * info,OUT DAT_IA_OPEN_FUNC * p_ia_open_func)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
dat_dr_provider_close(IN const DAT_PROVIDER_INFO * info)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
dat_dr_size(OUT DAT_COUNT * size)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
dat_dr_list(IN DAT_COUNT max_to_return,OUT DAT_COUNT * entries_returned,OUT DAT_PROVIDER_INFO * (dat_provider_list[]))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