1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
24*0Sstevel@tonic-gate */
25*0Sstevel@tonic-gate
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28*0Sstevel@tonic-gate * Use is subject to license terms.
29*0Sstevel@tonic-gate */
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate /*
34*0Sstevel@tonic-gate *
35*0Sstevel@tonic-gate * MODULE: dat_sr.c
36*0Sstevel@tonic-gate *
37*0Sstevel@tonic-gate * PURPOSE: static registry implementation
38*0Sstevel@tonic-gate *
39*0Sstevel@tonic-gate * $Id: dat_sr.c,v 1.12 2003/08/20 14:28:40 hobie16 Exp $
40*0Sstevel@tonic-gate */
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate #include "dat_sr.h"
44*0Sstevel@tonic-gate
45*0Sstevel@tonic-gate #include "dat_dictionary.h"
46*0Sstevel@tonic-gate #include "udat_sr_parser.h"
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gate /*
50*0Sstevel@tonic-gate *
51*0Sstevel@tonic-gate * Global Variables
52*0Sstevel@tonic-gate *
53*0Sstevel@tonic-gate */
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate static DAT_OS_LOCK g_sr_lock;
56*0Sstevel@tonic-gate static DAT_DICTIONARY *g_sr_dictionary = NULL;
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate
59*0Sstevel@tonic-gate /*
60*0Sstevel@tonic-gate *
61*0Sstevel@tonic-gate * External Functions
62*0Sstevel@tonic-gate *
63*0Sstevel@tonic-gate */
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate /*
67*0Sstevel@tonic-gate * Function: dat_sr_init
68*0Sstevel@tonic-gate */
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate DAT_RETURN
dat_sr_init(void)71*0Sstevel@tonic-gate dat_sr_init(void)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate DAT_RETURN status;
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate status = dat_os_lock_init(&g_sr_lock);
76*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
77*0Sstevel@tonic-gate return (status);
78*0Sstevel@tonic-gate }
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate status = dat_dictionary_create(&g_sr_dictionary);
81*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
82*0Sstevel@tonic-gate return (status);
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate /*
86*0Sstevel@tonic-gate * Since DAT allows providers to be loaded by either the static
87*0Sstevel@tonic-gate * registry or explicitly through OS dependent methods, do not
88*0Sstevel@tonic-gate * return an error if no providers are loaded via the static registry.
89*0Sstevel@tonic-gate */
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate (void) dat_sr_load();
92*0Sstevel@tonic-gate
93*0Sstevel@tonic-gate return (DAT_SUCCESS);
94*0Sstevel@tonic-gate }
95*0Sstevel@tonic-gate
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate /*
98*0Sstevel@tonic-gate * Function: dat_sr_fini
99*0Sstevel@tonic-gate */
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_fini(void)102*0Sstevel@tonic-gate dat_sr_fini(void)
103*0Sstevel@tonic-gate {
104*0Sstevel@tonic-gate DAT_RETURN status;
105*0Sstevel@tonic-gate
106*0Sstevel@tonic-gate status = dat_os_lock_destroy(&g_sr_lock);
107*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
108*0Sstevel@tonic-gate return (status);
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate status = dat_dictionary_destroy(g_sr_dictionary);
112*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
113*0Sstevel@tonic-gate return (status);
114*0Sstevel@tonic-gate }
115*0Sstevel@tonic-gate
116*0Sstevel@tonic-gate return (DAT_SUCCESS);
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate /*
121*0Sstevel@tonic-gate * Function: dat_sr_insert
122*0Sstevel@tonic-gate */
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_insert(IN const DAT_PROVIDER_INFO * info,IN DAT_SR_ENTRY * entry)125*0Sstevel@tonic-gate dat_sr_insert(
126*0Sstevel@tonic-gate IN const DAT_PROVIDER_INFO *info,
127*0Sstevel@tonic-gate IN DAT_SR_ENTRY *entry)
128*0Sstevel@tonic-gate {
129*0Sstevel@tonic-gate DAT_RETURN status;
130*0Sstevel@tonic-gate DAT_SR_ENTRY *data;
131*0Sstevel@tonic-gate DAT_OS_SIZE lib_path_size;
132*0Sstevel@tonic-gate DAT_OS_SIZE lib_path_len;
133*0Sstevel@tonic-gate DAT_OS_SIZE ia_params_size;
134*0Sstevel@tonic-gate DAT_OS_SIZE ia_params_len;
135*0Sstevel@tonic-gate DAT_DICTIONARY_ENTRY dict_entry;
136*0Sstevel@tonic-gate
137*0Sstevel@tonic-gate if (NULL == (data = dat_os_alloc(sizeof (DAT_SR_ENTRY)))) {
138*0Sstevel@tonic-gate status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
139*0Sstevel@tonic-gate DAT_RESOURCE_MEMORY);
140*0Sstevel@tonic-gate goto bail;
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate
143*0Sstevel@tonic-gate lib_path_len = strlen(entry->lib_path);
144*0Sstevel@tonic-gate lib_path_size = (lib_path_len + 1) * sizeof (char);
145*0Sstevel@tonic-gate
146*0Sstevel@tonic-gate if (NULL == (data->lib_path = dat_os_alloc(lib_path_size))) {
147*0Sstevel@tonic-gate status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
148*0Sstevel@tonic-gate DAT_RESOURCE_MEMORY);
149*0Sstevel@tonic-gate goto bail;
150*0Sstevel@tonic-gate }
151*0Sstevel@tonic-gate
152*0Sstevel@tonic-gate (void) dat_os_strncpy(data->lib_path, entry->lib_path, lib_path_len);
153*0Sstevel@tonic-gate data->lib_path[lib_path_len] = '\0';
154*0Sstevel@tonic-gate
155*0Sstevel@tonic-gate ia_params_len = strlen(entry->ia_params);
156*0Sstevel@tonic-gate ia_params_size = (ia_params_len + 1) * sizeof (char);
157*0Sstevel@tonic-gate
158*0Sstevel@tonic-gate if (NULL == (data->ia_params = dat_os_alloc(ia_params_size))) {
159*0Sstevel@tonic-gate status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
160*0Sstevel@tonic-gate DAT_RESOURCE_MEMORY);
161*0Sstevel@tonic-gate goto bail;
162*0Sstevel@tonic-gate }
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gate (void) dat_os_strncpy(data->ia_params, entry->ia_params, ia_params_len);
165*0Sstevel@tonic-gate data->ia_params[ia_params_len] = '\0';
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gate data->info = entry->info;
168*0Sstevel@tonic-gate data->lib_handle = entry->lib_handle;
169*0Sstevel@tonic-gate data->ref_count = entry->ref_count;
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate dict_entry = NULL;
172*0Sstevel@tonic-gate status = dat_dictionary_entry_create(&dict_entry);
173*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
174*0Sstevel@tonic-gate goto bail;
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate dat_os_lock(&g_sr_lock);
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gate status = dat_dictionary_insert(g_sr_dictionary,
180*0Sstevel@tonic-gate dict_entry,
181*0Sstevel@tonic-gate info,
182*0Sstevel@tonic-gate (DAT_DICTIONARY_DATA *)data);
183*0Sstevel@tonic-gate dat_os_unlock(&g_sr_lock);
184*0Sstevel@tonic-gate
185*0Sstevel@tonic-gate bail:
186*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
187*0Sstevel@tonic-gate if (NULL != data) {
188*0Sstevel@tonic-gate if (NULL != data->lib_path) {
189*0Sstevel@tonic-gate dat_os_free(data->lib_path, lib_path_size);
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate if (NULL != data->ia_params) {
193*0Sstevel@tonic-gate dat_os_free(data->ia_params, ia_params_size);
194*0Sstevel@tonic-gate }
195*0Sstevel@tonic-gate
196*0Sstevel@tonic-gate dat_os_free(data, sizeof (DAT_SR_ENTRY));
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate if (NULL != dict_entry) {
200*0Sstevel@tonic-gate (void) dat_dictionary_entry_destroy(dict_entry);
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate return (status);
205*0Sstevel@tonic-gate }
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gate
208*0Sstevel@tonic-gate /*
209*0Sstevel@tonic-gate * Function: dat_sr_size
210*0Sstevel@tonic-gate */
211*0Sstevel@tonic-gate
212*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_size(OUT DAT_COUNT * size)213*0Sstevel@tonic-gate dat_sr_size(
214*0Sstevel@tonic-gate OUT DAT_COUNT *size)
215*0Sstevel@tonic-gate {
216*0Sstevel@tonic-gate return (dat_dictionary_size(g_sr_dictionary, size));
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate
220*0Sstevel@tonic-gate /*
221*0Sstevel@tonic-gate * Function: dat_sr_list
222*0Sstevel@tonic-gate */
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_list(IN DAT_COUNT max_to_return,OUT DAT_COUNT * entries_returned,OUT DAT_PROVIDER_INFO * (dat_provider_list[]))225*0Sstevel@tonic-gate dat_sr_list(
226*0Sstevel@tonic-gate IN DAT_COUNT max_to_return,
227*0Sstevel@tonic-gate OUT DAT_COUNT *entries_returned,
228*0Sstevel@tonic-gate OUT DAT_PROVIDER_INFO * (dat_provider_list[]))
229*0Sstevel@tonic-gate {
230*0Sstevel@tonic-gate DAT_SR_ENTRY **array;
231*0Sstevel@tonic-gate DAT_COUNT array_size;
232*0Sstevel@tonic-gate DAT_COUNT i;
233*0Sstevel@tonic-gate DAT_RETURN status;
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate array = NULL;
236*0Sstevel@tonic-gate status = DAT_SUCCESS;
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate /*
239*0Sstevel@tonic-gate * The dictionary size may increase between the call to
240*0Sstevel@tonic-gate * dat_dictionary_size() and dat_dictionary_enumerate().
241*0Sstevel@tonic-gate * Therefore we loop until a successful enumeration is made.
242*0Sstevel@tonic-gate */
243*0Sstevel@tonic-gate *entries_returned = 0;
244*0Sstevel@tonic-gate for (;;) {
245*0Sstevel@tonic-gate status = dat_dictionary_size(g_sr_dictionary, &array_size);
246*0Sstevel@tonic-gate if (DAT_SUCCESS != status) {
247*0Sstevel@tonic-gate goto bail;
248*0Sstevel@tonic-gate }
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate if (array_size == 0) {
251*0Sstevel@tonic-gate status = DAT_SUCCESS;
252*0Sstevel@tonic-gate goto bail;
253*0Sstevel@tonic-gate }
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate array = dat_os_alloc(array_size * sizeof (DAT_SR_ENTRY *));
256*0Sstevel@tonic-gate if (array == NULL) {
257*0Sstevel@tonic-gate status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
258*0Sstevel@tonic-gate DAT_RESOURCE_MEMORY);
259*0Sstevel@tonic-gate goto bail;
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate dat_os_lock(&g_sr_lock);
263*0Sstevel@tonic-gate
264*0Sstevel@tonic-gate status = dat_dictionary_enumerate(g_sr_dictionary,
265*0Sstevel@tonic-gate (DAT_DICTIONARY_DATA *) array,
266*0Sstevel@tonic-gate array_size);
267*0Sstevel@tonic-gate
268*0Sstevel@tonic-gate dat_os_unlock(&g_sr_lock);
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate if (DAT_SUCCESS == status) {
271*0Sstevel@tonic-gate break;
272*0Sstevel@tonic-gate } else {
273*0Sstevel@tonic-gate dat_os_free(array,
274*0Sstevel@tonic-gate array_size * sizeof (DAT_SR_ENTRY *));
275*0Sstevel@tonic-gate array = NULL;
276*0Sstevel@tonic-gate continue;
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate for (i = 0; (i < max_to_return) && (i < array_size); i++) {
281*0Sstevel@tonic-gate if (NULL == dat_provider_list[i]) {
282*0Sstevel@tonic-gate status = DAT_ERROR(DAT_INVALID_PARAMETER,
283*0Sstevel@tonic-gate DAT_INVALID_ARG3);
284*0Sstevel@tonic-gate goto bail;
285*0Sstevel@tonic-gate }
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate *dat_provider_list[i] = array[i]->info;
288*0Sstevel@tonic-gate }
289*0Sstevel@tonic-gate
290*0Sstevel@tonic-gate *entries_returned = i;
291*0Sstevel@tonic-gate
292*0Sstevel@tonic-gate bail:
293*0Sstevel@tonic-gate if (NULL != array) {
294*0Sstevel@tonic-gate dat_os_free(array, array_size * sizeof (DAT_SR_ENTRY *));
295*0Sstevel@tonic-gate }
296*0Sstevel@tonic-gate
297*0Sstevel@tonic-gate return (status);
298*0Sstevel@tonic-gate }
299*0Sstevel@tonic-gate
300*0Sstevel@tonic-gate
301*0Sstevel@tonic-gate
302*0Sstevel@tonic-gate /*
303*0Sstevel@tonic-gate * Function: dat_sr_provider_open
304*0Sstevel@tonic-gate */
305*0Sstevel@tonic-gate
306*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_provider_open(IN const DAT_PROVIDER_INFO * info)307*0Sstevel@tonic-gate dat_sr_provider_open(
308*0Sstevel@tonic-gate IN const DAT_PROVIDER_INFO *info)
309*0Sstevel@tonic-gate {
310*0Sstevel@tonic-gate DAT_RETURN status;
311*0Sstevel@tonic-gate DAT_SR_ENTRY *data;
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate dat_os_lock(&g_sr_lock);
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate status = dat_dictionary_search(g_sr_dictionary,
316*0Sstevel@tonic-gate info,
317*0Sstevel@tonic-gate (DAT_DICTIONARY_DATA *) &data);
318*0Sstevel@tonic-gate
319*0Sstevel@tonic-gate if (DAT_SUCCESS == status) {
320*0Sstevel@tonic-gate if (0 == data->ref_count) {
321*0Sstevel@tonic-gate status = dat_os_library_load(data->lib_path,
322*0Sstevel@tonic-gate &data->lib_handle);
323*0Sstevel@tonic-gate if (status == DAT_SUCCESS) {
324*0Sstevel@tonic-gate data->ref_count++;
325*0Sstevel@tonic-gate } else {
326*0Sstevel@tonic-gate dat_os_dbg_print(DAT_OS_DBG_TYPE_SR,
327*0Sstevel@tonic-gate "DAT Registry: static registry unable to "
328*0Sstevel@tonic-gate "load library %s\n", data->lib_path);
329*0Sstevel@tonic-gate goto bail;
330*0Sstevel@tonic-gate }
331*0Sstevel@tonic-gate data->init_func = (DAT_PROVIDER_INIT_FUNC)
332*0Sstevel@tonic-gate dat_os_library_sym(data->lib_handle,
333*0Sstevel@tonic-gate DAT_PROVIDER_INIT_FUNC_STR);
334*0Sstevel@tonic-gate data->fini_func = (DAT_PROVIDER_FINI_FUNC)
335*0Sstevel@tonic-gate dat_os_library_sym(data->lib_handle,
336*0Sstevel@tonic-gate DAT_PROVIDER_FINI_FUNC_STR);
337*0Sstevel@tonic-gate
338*0Sstevel@tonic-gate if (NULL != data->init_func) {
339*0Sstevel@tonic-gate (*data->init_func)(&data->info,
340*0Sstevel@tonic-gate data->ia_params);
341*0Sstevel@tonic-gate }
342*0Sstevel@tonic-gate } else {
343*0Sstevel@tonic-gate data->ref_count++;
344*0Sstevel@tonic-gate }
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gate bail:
348*0Sstevel@tonic-gate dat_os_unlock(&g_sr_lock);
349*0Sstevel@tonic-gate
350*0Sstevel@tonic-gate return (status);
351*0Sstevel@tonic-gate }
352*0Sstevel@tonic-gate
353*0Sstevel@tonic-gate
354*0Sstevel@tonic-gate /*
355*0Sstevel@tonic-gate * Function: dat_sr_provider_close
356*0Sstevel@tonic-gate */
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate extern DAT_RETURN
dat_sr_provider_close(IN const DAT_PROVIDER_INFO * info)359*0Sstevel@tonic-gate dat_sr_provider_close(
360*0Sstevel@tonic-gate IN const DAT_PROVIDER_INFO *info)
361*0Sstevel@tonic-gate {
362*0Sstevel@tonic-gate DAT_RETURN status;
363*0Sstevel@tonic-gate DAT_SR_ENTRY *data;
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gate dat_os_lock(&g_sr_lock);
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gate status = dat_dictionary_search(g_sr_dictionary,
368*0Sstevel@tonic-gate info,
369*0Sstevel@tonic-gate (DAT_DICTIONARY_DATA *)&data);
370*0Sstevel@tonic-gate
371*0Sstevel@tonic-gate if (DAT_SUCCESS == status) {
372*0Sstevel@tonic-gate if (1 == data->ref_count) {
373*0Sstevel@tonic-gate if (NULL != data->fini_func) {
374*0Sstevel@tonic-gate (*data->fini_func)(&data->info);
375*0Sstevel@tonic-gate }
376*0Sstevel@tonic-gate
377*0Sstevel@tonic-gate status = dat_os_library_unload(data->lib_handle);
378*0Sstevel@tonic-gate if (status == DAT_SUCCESS) {
379*0Sstevel@tonic-gate data->ref_count--;
380*0Sstevel@tonic-gate }
381*0Sstevel@tonic-gate } else {
382*0Sstevel@tonic-gate data->ref_count--;
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate }
385*0Sstevel@tonic-gate
386*0Sstevel@tonic-gate dat_os_unlock(&g_sr_lock);
387*0Sstevel@tonic-gate
388*0Sstevel@tonic-gate return (status);
389*0Sstevel@tonic-gate }
390