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