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 2004 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 * 36 * MODULE: udat.c 37 * 38 * PURPOSE: DAT Provider and Consumer registry functions. 39 * 40 * $Id: udat.c,v 1.13 2003/08/20 14:28:40 hobie16 Exp $ 41 */ 42 43 #include <dat/udat.h> 44 #include <dat/dat_registry.h> /* Provider API function prototypes */ 45 46 #include "dat_dr.h" 47 #include "dat_init.h" 48 #include "dat_osd.h" 49 #ifndef DAT_NO_STATIC_REGISTRY 50 #include "dat_sr.h" 51 #endif 52 53 54 #define UDAT_IS_BAD_POINTER(p) (NULL == (p)) 55 56 /* 57 * 58 * Internal Function Declarations 59 * 60 */ 61 62 DAT_BOOLEAN 63 udat_check_state(void); 64 65 66 /* 67 * 68 * External Function Definitions 69 * 70 */ 71 72 73 /* 74 * 75 * Provider API 76 * 77 */ 78 79 80 /* 81 * Function: dat_registry_add_provider 82 */ 83 84 DAT_RETURN 85 dat_registry_add_provider( 86 IN DAT_PROVIDER *provider, 87 IN const DAT_PROVIDER_INFO *provider_info) 88 { 89 DAT_DR_ENTRY entry; 90 91 dat_os_dbg_print(DAT_OS_DBG_TYPE_PROVIDER_API, 92 "DAT Registry: dat_registry_add_provider() called\n"); 93 94 if (UDAT_IS_BAD_POINTER(provider)) { 95 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1)); 96 } 97 98 if (UDAT_IS_BAD_POINTER(provider_info)) { 99 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2)); 100 } 101 102 if (DAT_FALSE == udat_check_state()) { 103 return (DAT_ERROR(DAT_INVALID_STATE, 0)); 104 } 105 106 entry.ref_count = 0; 107 entry.ia_open_func = provider->ia_open_func; 108 entry.info = *provider_info; 109 110 return (dat_dr_insert(provider_info, &entry)); 111 } 112 113 114 /* 115 * Function: dat_registry_remove_provider 116 */ 117 118 DAT_RETURN 119 dat_registry_remove_provider( 120 IN DAT_PROVIDER *provider, 121 IN const DAT_PROVIDER_INFO *provider_info) 122 { 123 dat_os_dbg_print(DAT_OS_DBG_TYPE_PROVIDER_API, 124 "DAT Registry: dat_registry_remove_provider() called\n"); 125 126 if (UDAT_IS_BAD_POINTER(provider)) { 127 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1)); 128 } 129 130 if (DAT_FALSE == udat_check_state()) { 131 return (DAT_ERROR(DAT_INVALID_STATE, 0)); 132 } 133 134 return (dat_dr_remove(provider_info)); 135 } 136 137 138 /* 139 * 140 * Consumer API 141 * 142 */ 143 144 /* 145 * Function: dat_ia_open 146 */ 147 148 DAT_RETURN 149 dat_ia_openv( 150 IN const DAT_NAME_PTR name, 151 IN DAT_COUNT async_event_qlen, 152 INOUT DAT_EVD_HANDLE *async_event_handle, 153 OUT DAT_IA_HANDLE *ia_handle, 154 IN DAT_UINT32 dapl_major, 155 IN DAT_UINT32 dapl_minor, 156 IN DAT_BOOLEAN thread_safety) 157 { 158 DAT_IA_OPEN_FUNC ia_open_func; 159 DAT_PROVIDER_INFO info; 160 DAT_RETURN status; 161 DAT_OS_SIZE len; 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 (void) dat_os_strncpy(info.ia_name, name, len); 185 info.ia_name[len] = '\0'; 186 187 info.dapl_version_major = dapl_major; 188 info.dapl_version_minor = dapl_minor; 189 info.is_thread_safe = thread_safety; 190 191 /* 192 * Since DAT allows providers to be loaded by either the static 193 * registry or explicitly through OS dependent methods, do not 194 * return an error if no providers are loaded via the static registry. 195 * Don't even bother calling the static registry if DAT is compiled 196 * with no static registry support. 197 */ 198 199 #ifndef DAT_NO_STATIC_REGISTRY 200 (void) dat_sr_provider_open(&info); 201 #endif 202 203 status = dat_dr_provider_open(&info, &ia_open_func); 204 if (status != DAT_SUCCESS) { 205 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 206 "DAT Registry: dat_ia_open() provider information " 207 "for IA name %s not found in dynamic registry\n", 208 name); 209 return (status); 210 } 211 212 return (*ia_open_func)(name, 213 async_event_qlen, 214 async_event_handle, 215 ia_handle); 216 } 217 218 219 /* 220 * Function: dat_ia_close 221 */ 222 223 DAT_RETURN 224 dat_ia_close( 225 IN DAT_IA_HANDLE ia_handle, 226 IN DAT_CLOSE_FLAGS ia_flags) 227 { 228 DAT_PROVIDER *provider; 229 DAT_PROVIDER_ATTR provider_attr = {0}; 230 DAT_RETURN status; 231 const char *ia_name; 232 233 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 234 "DAT Registry: dat_ia_close() called\n"); 235 236 if (UDAT_IS_BAD_POINTER(ia_handle)) { 237 return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA)); 238 } 239 240 if (DAT_FALSE == udat_check_state()) { 241 return (DAT_ERROR(DAT_INVALID_STATE, 0)); 242 } 243 244 provider = DAT_HANDLE_TO_PROVIDER(ia_handle); 245 ia_name = provider->device_name; 246 247 if (DAT_SUCCESS != (status = dat_ia_query(ia_handle, 248 NULL, 249 0, 250 NULL, 251 DAT_PROVIDER_FIELD_ALL, 252 &provider_attr))) { 253 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 254 "DAT Registry: query function for %s provider failed\n", 255 ia_name); 256 } else if (DAT_SUCCESS != (status = 257 (*provider->ia_close_func)(ia_handle, ia_flags))) { 258 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 259 "DAT Registry: close function for %s provider failed\n", 260 ia_name); 261 } else { 262 DAT_PROVIDER_INFO info; 263 DAT_OS_SIZE len; 264 265 len = dat_os_strlen(ia_name); 266 267 dat_os_assert(len <= DAT_NAME_MAX_LENGTH); 268 269 (void) dat_os_strncpy(info.ia_name, ia_name, len); 270 info.ia_name[len] = '\0'; 271 272 info.dapl_version_major = provider_attr.dapl_version_major; 273 info.dapl_version_minor = provider_attr.dapl_version_minor; 274 info.is_thread_safe = provider_attr.is_thread_safe; 275 276 status = dat_dr_provider_close(&info); 277 if (DAT_SUCCESS != status) { 278 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 279 "DAT Registry: dynamic registry unable to close " 280 "provider for IA name %s\n", 281 ia_name); 282 } 283 284 #ifndef DAT_NO_STATIC_REGISTRY 285 status = dat_sr_provider_close(&info); 286 if (DAT_SUCCESS != status) { 287 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 288 "DAT Registry: static registry unable to close " 289 "provider for IA name %s\n", 290 ia_name); 291 } 292 #endif 293 } 294 295 return (status); 296 } 297 298 299 /* 300 * Function: dat_registry_list_providers 301 */ 302 303 DAT_RETURN 304 dat_registry_list_providers( 305 IN DAT_COUNT max_to_return, 306 OUT DAT_COUNT *entries_returned, 307 OUT DAT_PROVIDER_INFO *(dat_provider_list[])) 308 { 309 DAT_RETURN dat_status; 310 311 dat_status = DAT_SUCCESS; 312 dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, 313 "DAT Registry: dat_registry_list_providers() called\n"); 314 315 if (DAT_FALSE == udat_check_state()) { 316 return (DAT_ERROR(DAT_INVALID_STATE, 0)); 317 } 318 319 if ((UDAT_IS_BAD_POINTER(entries_returned))) { 320 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2)); 321 } 322 323 if (0 != max_to_return && (UDAT_IS_BAD_POINTER(dat_provider_list))) { 324 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG3)); 325 } 326 327 if (0 == max_to_return) { 328 /* 329 * the user is allowed to call with max_to_return set to zero. 330 * in which case we simply return (in *entries_returned) the 331 * number of providers currently installed. We must also 332 * (per spec) return an error 333 */ 334 #ifndef DAT_NO_STATIC_REGISTRY 335 (void) dat_sr_size(entries_returned); 336 #else 337 (void) dat_dr_size(entries_returned); 338 #endif 339 return (DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1)); 340 } else { 341 #ifndef DAT_NO_STATIC_REGISTRY 342 dat_status = dat_sr_list(max_to_return, 343 entries_returned, 344 dat_provider_list); 345 #else 346 dat_status = dat_dr_list(max_to_return, 347 entries_returned, 348 dat_provider_list); 349 #endif 350 } 351 return (dat_status); 352 } 353 354 355 /* 356 * 357 * Internal Function Definitions 358 * 359 */ 360 361 362 /* 363 * Function: udat_check_state 364 */ 365 366 /* 367 * This function returns TRUE if the DAT registry is in a state capable 368 * of handling DAT API calls and false otherwise. 369 */ 370 371 DAT_BOOLEAN 372 udat_check_state(void) 373 { 374 DAT_MODULE_STATE state; 375 DAT_BOOLEAN status; 376 377 state = dat_module_get_state(); 378 379 if (DAT_MODULE_STATE_UNINITIALIZED == state) { 380 dat_init(); 381 status = DAT_TRUE; 382 } else if (DAT_MODULE_STATE_DEINITIALIZED == state) { 383 status = DAT_FALSE; 384 } else { 385 status = DAT_TRUE; 386 } 387 388 return (status); 389 } 390 391 392 /* 393 * Local variables: 394 * c-indent-level: 4 395 * c-basic-offset: 4 396 * tab-width: 8 397 * End: 398 */ 399