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 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 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 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 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 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 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