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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Block comment which describes the contents of this file. 31 */ 32 33 #include <dlfcn.h> 34 #include <meta.h> 35 #include <metadyn.h> 36 #include <sdssc.h> 37 38 #define SDSSC_PATH SDSSC_CL_LIBDIR "/sc/libsds_sc.so" 39 40 static func_table_t dl_table[] = { 41 { "_sdssc_version", (void **)&sdssc_version }, 42 { "_sdssc_create_begin", (void **)&sdssc_create_begin }, 43 { "_sdssc_mo_create_begin", (void **)&sdssc_mo_create_begin }, 44 { "_sdssc_create_end", (void **)&sdssc_create_end }, 45 { "_sdssc_delete_begin", (void **)&sdssc_delete_begin }, 46 { "_sdssc_delete_end", (void **)&sdssc_delete_end }, 47 { "_sdssc_get_index", (void **)&sdssc_get_index }, 48 { "_sdssc_add_hosts", (void **)&sdssc_add_hosts }, 49 { "_sdssc_delete_hosts", (void **)&sdssc_delete_hosts }, 50 { "_sdssc_get_primary_host", (void **)&sdssc_get_primary_host }, 51 { "_sdssc_cmd_proxy", (void **)&sdssc_cmd_proxy }, 52 { "_sdssc_getnodelist", (void **)&sdssc_getnodelist }, 53 { "_sdssc_freenodelist", (void **)&sdssc_freenodelist }, 54 { "_sdssc_binddevs", (void **)&sdssc_binddevs }, 55 { "_sdssc_bindclusterdevs", (void **)&sdssc_bindclusterdevs }, 56 { "_sdssc_gettransportbynode", (void **)&sdssc_gettransportbynode }, 57 { "_sdssc_free_mdcerr_list", (void **)&sdssc_free_mdcerr_list }, 58 { "_sdssc_property_get", (void **)&sdssc_property_get }, 59 { "_sdssc_property_set", (void **)&sdssc_property_set }, 60 { "_sdssc_get_services", (void **)&sdssc_get_services }, 61 { "_sdssc_get_services_free", (void **)&sdssc_get_services_free }, 62 { "_sdssc_suspend", (void **)&sdssc_suspend }, 63 { "_sdssc_convert_cluster_path", 64 (void **)&sdssc_convert_cluster_path }, 65 { "_sdssc_convert_ctd_path", 66 (void **)&sdssc_convert_ctd_path }, 67 { "_sdssc_convert_path_free", 68 (void **)&sdssc_convert_path_free }, 69 { "_sdssc_notify_service", (void **)&sdssc_notify_service }, 70 { "_sdssc_cm_nm2nid", (void **)&sdssc_cm_nm2nid }, 71 { "_sdssc_cm_sr_nm2nid", (void **)&sdssc_cm_sr_nm2nid }, 72 { "_sdssc_cm_nid2nm", (void **)&sdssc_cm_nid2nm }, 73 { "_sdssc_cm_sr_nid2nm", (void **)&sdssc_cm_sr_nid2nm }, 74 { "_sdssc_get_priv_ipaddr", (void **)&sdssc_get_priv_ipaddr }, 75 { (char *)0, (void **)0 } 76 }; 77 78 static rval_e 79 just_dup_string(const char *source, char **dest) 80 { 81 *dest = strdup(source); 82 return (SDSSC_OKAY); 83 } 84 85 static void 86 free_dup_string(char *source) 87 { 88 free(source); 89 } 90 91 /* 92 * not_bound -- routine to always return NOT_BOUND 93 */ 94 static rval_e 95 not_bound(void) 96 { 97 return (SDSSC_NOT_BOUND); 98 } 99 100 /* 101 * not_bound_error -- routine to always return SDSSC_NOT_BOUND_ERROR since 102 * routine is not bound. This is used when using an older version 103 * of libsdssc that doesn't support MN disksets. When an MN specific 104 * routine is called (such as sdssc_mo_create_set) an SDSSC_NOT_BOUND_ERROR 105 * will be returned. 106 */ 107 static rval_e 108 not_bound_error(void) 109 { 110 return (SDSSC_NOT_BOUND_ERROR); 111 } 112 113 114 /* 115 * set_common_routine -- set cluster interface routines to return NOT_BOUND 116 */ 117 static void 118 set_common_routine() 119 { 120 func_table_p f; 121 122 for (f = dl_table; f->fptr != (void *)0; f++) { 123 if (strcmp(f->fname, "_sdssc_convert_cluster_path") == 0) { 124 *f->fptr = (void *)&just_dup_string; 125 } else if (strcmp(f->fname, "_sdssc_free_convert_cluster_path") 126 == 0) { 127 *f->fptr = (void *)&free_dup_string; 128 } else { 129 *f->fptr = (void *)¬_bound; 130 } 131 } 132 } 133 134 /* 135 * sdssc_bind_library -- entry point which resolves all cluster interface pts. 136 */ 137 rval_e 138 sdssc_bind_library(void) 139 { 140 void *dp; 141 int (*lb)(); 142 func_table_p ftp; 143 144 /* 145 * If already bound then just return okay so this routine 146 * becomes idempotent. If this check isn't made then we'll 147 * fail when calling the "_bind_library" function because 148 * dcs_initialize() can only be called once. 149 */ 150 if (sdssc_version != 0) { 151 if ((void *)sdssc_version == (void *)not_bound) 152 return (SDSSC_NOT_BOUND); 153 else 154 return (SDSSC_OKAY); 155 } 156 157 if ((dp = dlopen(SDSSC_PATH, RTLD_LAZY)) == NULL) { 158 set_common_routine(); 159 return (SDSSC_NOT_BOUND); 160 } else { 161 162 /* 163 * Allow the binding library to initialize state if 164 * necessary. Currently this calls the DCS initialize() 165 * routine which checks to see if we're part of a cluster. 166 */ 167 if ((lb = (int (*)())dlsym(dp, "_bind_library")) != NULL) { 168 if (lb() != 0) { 169 set_common_routine(); 170 return (SDSSC_NOT_BOUND); 171 } 172 } 173 174 /* 175 * Load 'em up. Pick up the function address and store 176 * the values in the global pointers for other routines 177 * to use. 178 */ 179 for (ftp = dl_table; ftp->fptr != (void *)0; ftp++) { 180 if ((*ftp->fptr = dlsym(dp, ftp->fname)) == NULL) { 181 182 /* 183 * If old libsdssc library is there, then 184 * sdssc_mo_create_begin is not yet supported. 185 */ 186 if (strcmp(ftp->fname, 187 "sdssc_mo_create_begin")) { 188 *ftp->fptr = (void *)¬_bound_error; 189 continue; 190 } 191 /* 192 * If this routine fails to find a single 193 * entry point that it's expecting 194 * (except sdssc_mo_create_begin) then 195 * setup non-sdssc stubs routines 196 * as function pointers. 197 */ 198 set_common_routine(); 199 return (SDSSC_ERROR); 200 } 201 } 202 203 return (SDSSC_OKAY); 204 } 205 } 206