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 #pragma ident "@(#)daio.c 1.10 09/05/26 SMI" 23 24 /* 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 /* 30 * diskomizer async io abstraction. 31 */ 32 #include <diskomizer/daio.h> 33 #include <stdlib.h> 34 #include <ctype.h> 35 #include <strings.h> 36 #include <dlfcn.h> 37 #include <stdio.h> 38 39 TNF_DEFINE_RECORD_2(daio_aio_result_t, daio_tnf_aio_result, 40 tnf_longlong, daio_return, 41 tnf_uint, daio_errno) 42 TNF_DEFINE_RECORD_2(daio_result_t, daio_tnf_result, 43 tnf_longlong, result.daio_return, 44 tnf_uint, result.daio_errno) 45 46 static struct daio_ops * 47 do_dlopen(const char *name) 48 { 49 void * handle; 50 if ((handle = dlopen(name, RTLD_NOW)) != NULL) { 51 struct daio_ops *ops; 52 53 if ((ops = dlsym(handle, DAIO_OPS_STRING)) == NULL) { 54 dlclose(handle); 55 } else { 56 return (ops); 57 } 58 } 59 return (NULL); 60 } 61 static void 62 lower(char *x) 63 { 64 while (*x != NULL) { 65 *x = tolower(*x); 66 x++; 67 } 68 } 69 static const char libdaio_name[] = "libdaio_%s.so"; 70 71 static struct daio_ops * 72 open_daio(char *libname, const char *name) 73 { 74 sprintf(libname, libdaio_name, name); 75 lower(libname); 76 return (do_dlopen(libname)); 77 } 78 79 struct daio_ops * 80 daio_choose_ops(const char *name) 81 { 82 struct daio_ops *ops = NULL; 83 char *x = (char *)name; 84 85 if ((ops = do_dlopen(name)) != NULL) { 86 return (ops); 87 } else { 88 char *full_name; 89 /* 90 * Have to allocate enough space for the string in 'name' 91 * and the string "libdaio_%s.so" and the trailing NULL. 92 */ 93 if ((full_name = malloc(strlen(name) + 94 strlen(libdaio_name) + 1)) != NULL) { 95 x = full_name; 96 ops = open_daio(full_name, name); 97 if (ops == NULL) { 98 char *tname; 99 100 tname = strdup(name); 101 if (tname != NULL) { 102 char *space; 103 char again = 0; 104 105 space = strchr(tname, ' '); 106 if (space != NULL) { 107 *space = NULL; 108 again = 1; 109 } 110 space = strchr(tname, '\t'); 111 if (space != NULL) { 112 *space = NULL; 113 again = 1; 114 } 115 if (again) { 116 ops = open_daio(full_name, 117 tname); 118 } 119 free(tname); 120 } 121 } 122 } 123 } 124 if (ops == NULL) { 125 fprintf(stderr, "Err %s: %s\n", x, dlerror()); 126 } 127 if (name != x) { 128 free(x); 129 } 130 return (ops); 131 } 132