xref: /onnv-gate/usr/src/lib/udapl/libdat/common/dat_sr.c (revision 0:68f95e015346)
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