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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
23 */
24
25 /*
26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30
31 /*
32 *
33 * MODULE: udat.c
34 *
35 * PURPOSE: DAT Provider and Consumer registry functions.
36 *
37 * $Id: udat.c,v 1.13 2003/08/20 14:28:40 hobie16 Exp $
38 */
39
40 #include <dat/udat.h>
41 #include <dat/dat_registry.h> /* Provider API function prototypes */
42
43 #include "dat_dr.h"
44 #include "dat_init.h"
45 #include "dat_osd.h"
46 #ifndef DAT_NO_STATIC_REGISTRY
47 #include "dat_sr.h"
48 #endif
49
50
51 #define UDAT_IS_BAD_POINTER(p) (NULL == (p))
52
53 /*
54 *
55 * Internal Function Declarations
56 *
57 */
58
59 DAT_BOOLEAN
60 udat_check_state(void);
61
62
63 /*
64 *
65 * External Function Definitions
66 *
67 */
68
69
70 /*
71 *
72 * Provider API
73 *
74 */
75
76
77 /*
78 * Function: dat_registry_add_provider
79 */
80
81 DAT_RETURN
dat_registry_add_provider(IN DAT_PROVIDER * provider,IN const DAT_PROVIDER_INFO * provider_info)82 dat_registry_add_provider(
83 IN DAT_PROVIDER *provider,
84 IN const DAT_PROVIDER_INFO *provider_info)
85 {
86 DAT_DR_ENTRY entry;
87
88 dat_os_dbg_print(DAT_OS_DBG_TYPE_PROVIDER_API,
89 "DAT Registry: dat_registry_add_provider() called\n");
90
91 if (UDAT_IS_BAD_POINTER(provider)) {
92 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1));
93 }
94
95 if (UDAT_IS_BAD_POINTER(provider_info)) {
96 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2));
97 }
98
99 if (DAT_FALSE == udat_check_state()) {
100 return (DAT_ERROR(DAT_INVALID_STATE, 0));
101 }
102
103 entry.ref_count = 0;
104 entry.ia_open_func = provider->ia_open_func;
105 entry.info = *provider_info;
106
107 return (dat_dr_insert(provider_info, &entry));
108 }
109
110
111 /*
112 * Function: dat_registry_remove_provider
113 */
114
115 DAT_RETURN
dat_registry_remove_provider(IN DAT_PROVIDER * provider,IN const DAT_PROVIDER_INFO * provider_info)116 dat_registry_remove_provider(
117 IN DAT_PROVIDER *provider,
118 IN const DAT_PROVIDER_INFO *provider_info)
119 {
120 dat_os_dbg_print(DAT_OS_DBG_TYPE_PROVIDER_API,
121 "DAT Registry: dat_registry_remove_provider() called\n");
122
123 if (UDAT_IS_BAD_POINTER(provider)) {
124 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1));
125 }
126
127 if (DAT_FALSE == udat_check_state()) {
128 return (DAT_ERROR(DAT_INVALID_STATE, 0));
129 }
130
131 return (dat_dr_remove(provider_info));
132 }
133
134
135 /*
136 *
137 * Consumer API
138 *
139 */
140
141 /*
142 * Function: dat_ia_open
143 */
144
145 DAT_RETURN
dat_ia_openv(IN const DAT_NAME_PTR name,IN DAT_COUNT async_event_qlen,INOUT DAT_EVD_HANDLE * async_event_handle,OUT DAT_IA_HANDLE * ia_handle,IN DAT_UINT32 dapl_major,IN DAT_UINT32 dapl_minor,IN DAT_BOOLEAN thread_safety)146 dat_ia_openv(
147 IN const DAT_NAME_PTR name,
148 IN DAT_COUNT async_event_qlen,
149 INOUT DAT_EVD_HANDLE *async_event_handle,
150 OUT DAT_IA_HANDLE *ia_handle,
151 IN DAT_UINT32 dapl_major,
152 IN DAT_UINT32 dapl_minor,
153 IN DAT_BOOLEAN thread_safety)
154 {
155 DAT_IA_OPEN_FUNC ia_open_func;
156 DAT_PROVIDER_INFO info;
157 DAT_RETURN status;
158 DAT_OS_SIZE len;
159 #define RO_AWARE_PREFIX "RO_AWARE_"
160 boolean_t ro_aware_client;
161 const char *_name = name;
162
163 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
164 "DAT Registry: dat_ia_open() called\n");
165
166 if (UDAT_IS_BAD_POINTER(_name)) {
167 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1));
168 }
169
170 len = dat_os_strlen(_name);
171
172 if (DAT_NAME_MAX_LENGTH <= len) {
173 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1));
174 }
175
176 if (UDAT_IS_BAD_POINTER(ia_handle)) {
177 return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA));
178 }
179
180 if (DAT_FALSE == udat_check_state()) {
181 return (DAT_ERROR(DAT_INVALID_STATE, 0));
182 }
183
184 /* Find out if this is an RO aware client and if so, strip the prefix */
185 ro_aware_client =
186 (strncmp(RO_AWARE_PREFIX, _name, sizeof (RO_AWARE_PREFIX) - 1) ==
187 0);
188
189 /* strip off the prefix from the provider's name if present */
190 if (ro_aware_client) {
191 _name = _name + sizeof (RO_AWARE_PREFIX) - 1;
192 len -= sizeof (RO_AWARE_PREFIX) - 1;
193 }
194
195 (void) dat_os_strncpy(info.ia_name, _name, len);
196 info.ia_name[len] = '\0';
197
198 info.dapl_version_major = dapl_major;
199 info.dapl_version_minor = dapl_minor;
200 info.is_thread_safe = thread_safety;
201
202 /*
203 * Since DAT allows providers to be loaded by either the static
204 * registry or explicitly through OS dependent methods, do not
205 * return an error if no providers are loaded via the static registry.
206 * Don't even bother calling the static registry if DAT is compiled
207 * with no static registry support.
208 */
209
210 #ifndef DAT_NO_STATIC_REGISTRY
211 (void) dat_sr_provider_open(&info);
212 #endif
213
214 status = dat_dr_provider_open(&info, &ia_open_func);
215 if (status != DAT_SUCCESS) {
216 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
217 "DAT Registry: dat_ia_open() provider information "
218 "for IA name %s not found in dynamic registry\n",
219 _name);
220 return (status);
221 }
222
223 return (*ia_open_func)((const DAT_NAME_PTR) _name,
224 async_event_qlen,
225 async_event_handle,
226 ia_handle,
227 ro_aware_client);
228 }
229
230
231 /*
232 * Function: dat_ia_close
233 */
234
235 DAT_RETURN
dat_ia_close(IN DAT_IA_HANDLE ia_handle,IN DAT_CLOSE_FLAGS ia_flags)236 dat_ia_close(
237 IN DAT_IA_HANDLE ia_handle,
238 IN DAT_CLOSE_FLAGS ia_flags)
239 {
240 DAT_PROVIDER *provider;
241 DAT_PROVIDER_ATTR provider_attr = {0};
242 DAT_RETURN status;
243 const char *ia_name;
244
245 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
246 "DAT Registry: dat_ia_close() called\n");
247
248 if (UDAT_IS_BAD_POINTER(ia_handle)) {
249 return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA));
250 }
251
252 if (DAT_FALSE == udat_check_state()) {
253 return (DAT_ERROR(DAT_INVALID_STATE, 0));
254 }
255
256 provider = DAT_HANDLE_TO_PROVIDER(ia_handle);
257 ia_name = provider->device_name;
258
259 if (DAT_SUCCESS != (status = dat_ia_query(ia_handle,
260 NULL,
261 0,
262 NULL,
263 DAT_PROVIDER_FIELD_ALL,
264 &provider_attr))) {
265 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
266 "DAT Registry: query function for %s provider failed\n",
267 ia_name);
268 } else if (DAT_SUCCESS != (status =
269 (*provider->ia_close_func)(ia_handle, ia_flags))) {
270 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
271 "DAT Registry: close function for %s provider failed\n",
272 ia_name);
273 } else {
274 DAT_PROVIDER_INFO info;
275 DAT_OS_SIZE len;
276
277 len = dat_os_strlen(ia_name);
278
279 dat_os_assert(len <= DAT_NAME_MAX_LENGTH);
280
281 (void) dat_os_strncpy(info.ia_name, ia_name, len);
282 info.ia_name[len] = '\0';
283
284 info.dapl_version_major = provider_attr.dapl_version_major;
285 info.dapl_version_minor = provider_attr.dapl_version_minor;
286 info.is_thread_safe = provider_attr.is_thread_safe;
287
288 status = dat_dr_provider_close(&info);
289 if (DAT_SUCCESS != status) {
290 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
291 "DAT Registry: dynamic registry unable to close "
292 "provider for IA name %s\n",
293 ia_name);
294 }
295
296 #ifndef DAT_NO_STATIC_REGISTRY
297 status = dat_sr_provider_close(&info);
298 if (DAT_SUCCESS != status) {
299 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
300 "DAT Registry: static registry unable to close "
301 "provider for IA name %s\n",
302 ia_name);
303 }
304 #endif
305 }
306
307 return (status);
308 }
309
310
311 /*
312 * Function: dat_registry_list_providers
313 */
314
315 DAT_RETURN
dat_registry_list_providers(IN DAT_COUNT max_to_return,OUT DAT_COUNT * entries_returned,OUT DAT_PROVIDER_INFO * (dat_provider_list[]))316 dat_registry_list_providers(
317 IN DAT_COUNT max_to_return,
318 OUT DAT_COUNT *entries_returned,
319 OUT DAT_PROVIDER_INFO *(dat_provider_list[]))
320 {
321 DAT_RETURN dat_status;
322
323 dat_status = DAT_SUCCESS;
324 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API,
325 "DAT Registry: dat_registry_list_providers() called\n");
326
327 if (DAT_FALSE == udat_check_state()) {
328 return (DAT_ERROR(DAT_INVALID_STATE, 0));
329 }
330
331 if ((UDAT_IS_BAD_POINTER(entries_returned))) {
332 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2));
333 }
334
335 if (0 != max_to_return && (UDAT_IS_BAD_POINTER(dat_provider_list))) {
336 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3));
337 }
338
339 if (0 == max_to_return) {
340 /*
341 * the user is allowed to call with max_to_return set to zero.
342 * in which case we simply return (in *entries_returned) the
343 * number of providers currently installed. We must also
344 * (per spec) return an error
345 */
346 #ifndef DAT_NO_STATIC_REGISTRY
347 (void) dat_sr_size(entries_returned);
348 #else
349 (void) dat_dr_size(entries_returned);
350 #endif
351 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1));
352 } else {
353 #ifndef DAT_NO_STATIC_REGISTRY
354 dat_status = dat_sr_list(max_to_return,
355 entries_returned,
356 dat_provider_list);
357 #else
358 dat_status = dat_dr_list(max_to_return,
359 entries_returned,
360 dat_provider_list);
361 #endif
362 }
363 return (dat_status);
364 }
365
366
367 /*
368 *
369 * Internal Function Definitions
370 *
371 */
372
373
374 /*
375 * Function: udat_check_state
376 */
377
378 /*
379 * This function returns TRUE if the DAT registry is in a state capable
380 * of handling DAT API calls and false otherwise.
381 */
382
383 DAT_BOOLEAN
udat_check_state(void)384 udat_check_state(void)
385 {
386 DAT_MODULE_STATE state;
387 DAT_BOOLEAN status;
388
389 state = dat_module_get_state();
390
391 if (DAT_MODULE_STATE_UNINITIALIZED == state) {
392 dat_init();
393 status = DAT_TRUE;
394 } else if (DAT_MODULE_STATE_DEINITIALIZED == state) {
395 status = DAT_FALSE;
396 } else {
397 status = DAT_TRUE;
398 }
399
400 return (status);
401 }
402
403
404 /*
405 * Local variables:
406 * c-indent-level: 4
407 * c-basic-offset: 4
408 * tab-width: 8
409 * End:
410 */
411